From 99a33b32b8a7c639d6d742ad5f31592d33098596 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Tue, 1 Dec 2020 14:45:43 +0100 Subject: [PATCH 001/370] Adding diesel to the cargetest suite This was proposed in #79459 and #79560. Diesel stresses the trait system implementation quite a lot and there have been various regressions regarding that in the past. --- src/tools/cargotest/main.rs | 50 +++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index 8aabe077cf1..574938235c6 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -9,6 +9,8 @@ struct Test { sha: &'static str, lock: Option<&'static str>, packages: &'static [&'static str], + features: Option<&'static [&'static str]>, + manifest_path: Option<&'static str>, } const TEST_REPOS: &[Test] = &[ @@ -18,6 +20,8 @@ const TEST_REPOS: &[Test] = &[ sha: "cf056ea5e8052c1feea6141e40ab0306715a2c33", lock: None, packages: &[], + features: None, + manifest_path: None, }, Test { name: "ripgrep", @@ -25,6 +29,8 @@ const TEST_REPOS: &[Test] = &[ sha: "3de31f752729525d85a3d1575ac1978733b3f7e7", lock: None, packages: &[], + features: None, + manifest_path: None, }, Test { name: "tokei", @@ -32,6 +38,8 @@ const TEST_REPOS: &[Test] = &[ sha: "fdf3f8cb279a7aeac0696c87e5d8b0cd946e4f9e", lock: None, packages: &[], + features: None, + manifest_path: None, }, Test { name: "xsv", @@ -39,6 +47,8 @@ const TEST_REPOS: &[Test] = &[ sha: "66956b6bfd62d6ac767a6b6499c982eae20a2c9f", lock: None, packages: &[], + features: None, + manifest_path: None, }, Test { name: "servo", @@ -48,6 +58,23 @@ const TEST_REPOS: &[Test] = &[ // Only test Stylo a.k.a. Quantum CSS, the parts of Servo going into Firefox. // This takes much less time to build than all of Servo and supports stable Rust. packages: &["selectors"], + features: None, + manifest_path: None, + }, + Test { + name: "diesel", + repo: "https://github.com/diesel-rs/diesel", + sha: "91493fe47175076f330ce5fc518f0196c0476f56", + lock: None, + packages: &[], + // Test the embeded sqlite variant of diesel + // This does not require any dependency to be present, + // sqlite will be compiled as part of the build process + features: Some(&["sqlite", "libsqlite3-sys/bundled"]), + // We are only interested in testing diesel itself + // not any other crate present in the diesel workspace + // (This is required to set the feature flags above) + manifest_path: Some("diesel/Cargo.toml"), }, ]; @@ -68,7 +95,7 @@ fn test_repo(cargo: &Path, out_dir: &Path, test: &Test) { if let Some(lockfile) = test.lock { fs::write(&dir.join("Cargo.lock"), lockfile).unwrap(); } - if !run_cargo_test(cargo, &dir, test.packages) { + if !run_cargo_test(cargo, &dir, test.packages, test.features, test.manifest_path) { panic!("tests failed for {}", test.repo); } } @@ -120,12 +147,31 @@ fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf { out_dir } -fn run_cargo_test(cargo_path: &Path, crate_path: &Path, packages: &[&str]) -> bool { +fn run_cargo_test( + cargo_path: &Path, + crate_path: &Path, + packages: &[&str], + features: Option<&[&str]>, + manifest_path: Option<&str>, +) -> bool { let mut command = Command::new(cargo_path); command.arg("test"); + + if let Some(path) = manifest_path { + command.arg(format!("--manifest-path={}", path)); + } + + if let Some(features) = features { + command.arg("--no-default-features"); + for feature in features { + command.arg(format!("--features={}", feature)); + } + } + for name in packages { command.arg("-p").arg(name); } + let status = command // Disable rust-lang/cargo's cross-compile tests .env("CFG_DISABLE_CROSS_TESTS", "1") From fe0ab7f1b21e8ade84beb2b83132bdb2092ab166 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Tue, 5 Jan 2021 15:53:07 +0100 Subject: [PATCH 002/370] Make documentation of which items the prelude exports more readably. --- library/std/src/prelude/mod.rs | 66 +++++++++++++++++----------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs index eb2095b8196..e0f26c3a4cf 100644 --- a/library/std/src/prelude/mod.rs +++ b/library/std/src/prelude/mod.rs @@ -1,4 +1,4 @@ -//! # The Rust Prelude +//! The Rust Prelude. //! //! Rust comes with a variety of things in its standard library. However, if //! you had to manually import every single thing that you used, it would be @@ -28,53 +28,53 @@ //! The current version of the prelude (version 1) lives in //! [`std::prelude::v1`], and re-exports the following: //! -//! * [`std::marker`]::{[`Copy`], [`Send`], [`Sized`], [`Sync`], [`Unpin`]}: +//! * [std::marker]::{[Copy], [Send], [Sized], [Sync], [Unpin]}, //! marker traits that indicate fundamental properties of types. -//! * [`std::ops`]::{[`Drop`], [`Fn`], [`FnMut`], [`FnOnce`]}: various +//! * [std::ops]::{[Drop], [Fn], [FnMut], [FnOnce]}, various //! operations for both destructors and overloading `()`. -//! * [`std::mem`]::[`drop`][`mem::drop`]: a convenience function for explicitly +//! * [std::mem]::[drop][mem::drop], a convenience function for explicitly //! dropping a value. -//! * [`std::boxed`]::[`Box`]: a way to allocate values on the heap. -//! * [`std::borrow`]::[`ToOwned`]: the conversion trait that defines +//! * [std::boxed]::[Box], a way to allocate values on the heap. +//! * [std::borrow]::[ToOwned], the conversion trait that defines //! [`to_owned`], the generic method for creating an owned type from a //! borrowed type. -//! * [`std::clone`]::[`Clone`]: the ubiquitous trait that defines -//! [`clone`][`Clone::clone`], the method for producing a copy of a value. -//! * [`std::cmp`]::{[`PartialEq`], [`PartialOrd`], [`Eq`], [`Ord`]}: the +//! * [std::clone]::[Clone], the ubiquitous trait that defines +//! [`clone`][Clone::clone], the method for producing a copy of a value. +//! * [std::cmp]::{[PartialEq], [PartialOrd], [Eq], [Ord]}, the //! comparison traits, which implement the comparison operators and are often //! seen in trait bounds. -//! * [`std::convert`]::{[`AsRef`], [`AsMut`], [`Into`], [`From`]}: generic +//! * [std::convert]::{[AsRef], [AsMut], [Into], [From]}, generic //! conversions, used by savvy API authors to create overloaded methods. -//! * [`std::default`]::[`Default`], types that have default values. -//! * [`std::iter`]::{[`Iterator`], [`Extend`], [`IntoIterator`], -//! [`DoubleEndedIterator`], [`ExactSizeIterator`]}: iterators of various +//! * [std::default]::[Default], types that have default values. +//! * [std::iter]::{[Iterator], [Extend], [IntoIterator], [DoubleEndedIterator], [ExactSizeIterator]}, +//! iterators of various //! kinds. -//! * [`std::option`]::[`Option`]::{[`self`][`Option`], [`Some`], [`None`]}, a +//! * [std::option]::[Option]::{[self][Option], [Some], [None]}, a //! type which expresses the presence or absence of a value. This type is so //! commonly used, its variants are also exported. -//! * [`std::result`]::[`Result`]::{[`self`][`Result`], [`Ok`], [`Err`]}: a type +//! * [std::result]::[Result]::{[self][Result], [Ok], [Err]}, a type //! for functions that may succeed or fail. Like [`Option`], its variants are //! exported as well. -//! * [`std::string`]::{[`String`], [`ToString`]}: heap-allocated strings. -//! * [`std::vec`]::[`Vec`]: a growable, heap-allocated vector. +//! * [std::string]::{[String], [ToString]}, heap-allocated strings. +//! * [std::vec]::[Vec], a growable, heap-allocated vector. //! -//! [`mem::drop`]: crate::mem::drop -//! [`std::borrow`]: crate::borrow -//! [`std::boxed`]: crate::boxed -//! [`std::clone`]: crate::clone -//! [`std::cmp`]: crate::cmp -//! [`std::convert`]: crate::convert -//! [`std::default`]: crate::default -//! [`std::iter`]: crate::iter -//! [`std::marker`]: crate::marker -//! [`std::mem`]: crate::mem -//! [`std::ops`]: crate::ops -//! [`std::option`]: crate::option +//! [mem::drop]: crate::mem::drop +//! [std::borrow]: crate::borrow +//! [std::boxed]: crate::boxed +//! [std::clone]: crate::clone +//! [std::cmp]: crate::cmp +//! [std::convert]: crate::convert +//! [std::default]: crate::default +//! [std::iter]: crate::iter +//! [std::marker]: crate::marker +//! [std::mem]: crate::mem +//! [std::ops]: crate::ops +//! [std::option]: crate::option //! [`std::prelude::v1`]: v1 -//! [`std::result`]: crate::result -//! [`std::slice`]: crate::slice -//! [`std::string`]: crate::string -//! [`std::vec`]: mod@crate::vec +//! [std::result]: crate::result +//! [std::slice]: crate::slice +//! [std::string]: crate::string +//! [std::vec]: mod@crate::vec //! [`to_owned`]: crate::borrow::ToOwned::to_owned //! [book-closures]: ../../book/ch13-01-closures.html //! [book-dtor]: ../../book/ch15-03-drop.html From af424c1813eca41024da5290e064ead85f68dc0b Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Mon, 1 Feb 2021 10:31:05 +0100 Subject: [PATCH 003/370] Implement SourceIterator and InPlaceIterable for ResultShunt --- library/core/src/iter/adapters/mod.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index 41a7b13232a..f72e6426200 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -191,3 +191,26 @@ where self.try_fold(init, ok(fold)).unwrap() } } + +#[unstable(issue = "none", feature = "inplace_iteration")] +unsafe impl SourceIter for ResultShunt<'_, I, E> +where + I: SourceIter, +{ + type Source = S; + + #[inline] + unsafe fn as_inner(&mut self) -> &mut S { + // SAFETY: unsafe function forwarding to unsafe function with the same requirements + unsafe { SourceIter::as_inner(&mut self.iter) } + } +} + +// SAFETY: ResultShunt::next calls I::find, which has to advance `iter` in order to +// return `Some(_)`. Since `iter` has type `I: InPlaceIterable` it's guaranteed that +// at least one item will be moved out from the underlying source. +#[unstable(issue = "none", feature = "inplace_iteration")] +unsafe impl InPlaceIterable for ResultShunt<'_, I, E> where + I: Iterator> + InPlaceIterable +{ +} From 524b0c9c614d4691b2e21ace47fce4df15900701 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Mon, 1 Feb 2021 10:31:34 +0100 Subject: [PATCH 004/370] Add test for inplace collection of Result,_> --- library/core/tests/iter/mod.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/library/core/tests/iter/mod.rs b/library/core/tests/iter/mod.rs index 770b6f7601f..b88f2f2089d 100644 --- a/library/core/tests/iter/mod.rs +++ b/library/core/tests/iter/mod.rs @@ -100,3 +100,29 @@ pub fn extend_for_unit() { } assert_eq!(x, 5); } + +#[test] +pub fn inplace_result_collect() { + let src = vec![0usize; 256]; + let srcptr = src.as_ptr(); + let sink = src.into_iter().map(|i| Ok(i)).collect::, ()>>().unwrap(); + let sinkptr = sink.as_ptr(); + assert_eq!(srcptr, sinkptr); + + let src: Vec = vec![0usize; 256]; + let srcptr = src.as_ptr(); + let iter = src + .into_iter() + .enumerate() + .map(|i| i.0 + i.1) + .zip(std::iter::repeat(1usize)) + .map(|(a, b)| a + b) + .map_while(Option::Some) + .peekable() + .skip(1) + .map(|e| std::num::NonZeroUsize::new(e)) + .map(|z| z.map(|u| u.get()).ok_or(())); + let sink = iter.collect::, _>>().unwrap(); + let sinkptr = sink.as_ptr(); + assert_eq!(srcptr, sinkptr as *const usize); +} From c6c8f3bf12bdeba01ba16eaacc5808e5321302f8 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Mon, 1 Feb 2021 17:16:54 +0100 Subject: [PATCH 005/370] Move test --- library/alloc/tests/vec.rs | 4 ++-- library/core/tests/iter/mod.rs | 26 -------------------------- 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index e19406d7a06..9ae333ce2c3 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -931,9 +931,9 @@ fn test_from_iter_specialization_with_iterator_adapters() { .map_while(Option::Some) .peekable() .skip(1) - .map(|e| std::num::NonZeroUsize::new(e)); + .map(|e| if e != 0 { Ok(e) } else { Err(()) }); assert_in_place_trait(&iter); - let sink = iter.collect::>(); + let sink = iter.collect::, _>>().unwrap(); let sinkptr = sink.as_ptr(); assert_eq!(srcptr, sinkptr as *const usize); } diff --git a/library/core/tests/iter/mod.rs b/library/core/tests/iter/mod.rs index b88f2f2089d..770b6f7601f 100644 --- a/library/core/tests/iter/mod.rs +++ b/library/core/tests/iter/mod.rs @@ -100,29 +100,3 @@ pub fn extend_for_unit() { } assert_eq!(x, 5); } - -#[test] -pub fn inplace_result_collect() { - let src = vec![0usize; 256]; - let srcptr = src.as_ptr(); - let sink = src.into_iter().map(|i| Ok(i)).collect::, ()>>().unwrap(); - let sinkptr = sink.as_ptr(); - assert_eq!(srcptr, sinkptr); - - let src: Vec = vec![0usize; 256]; - let srcptr = src.as_ptr(); - let iter = src - .into_iter() - .enumerate() - .map(|i| i.0 + i.1) - .zip(std::iter::repeat(1usize)) - .map(|(a, b)| a + b) - .map_while(Option::Some) - .peekable() - .skip(1) - .map(|e| std::num::NonZeroUsize::new(e)) - .map(|z| z.map(|u| u.get()).ok_or(())); - let sink = iter.collect::, _>>().unwrap(); - let sinkptr = sink.as_ptr(); - assert_eq!(srcptr, sinkptr as *const usize); -} From 7f19a2d2de32ea61a8c9b8bca44a13894954b3be Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 1 Feb 2021 19:29:31 +0100 Subject: [PATCH 006/370] Find codegen backends in more locations * Search in the sysroot passed using `--sysroot` in addition to the default sysroot. * Search for `librustc_codegen_$name.so` in addition to `librustc_codegen_$name-$release.so`. --- compiler/rustc_driver/src/lib.rs | 4 ++-- compiler/rustc_interface/src/util.rs | 25 +++++++++++++++++-------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 15b984acac5..d80454d29a5 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -799,7 +799,7 @@ pub fn version(binary: &str, matches: &getopts::Matches) { println!("host: {}", config::host_triple()); println!("release: {}", unw(util::release_str())); if cfg!(feature = "llvm") { - get_builtin_codegen_backend("llvm")().print_version(); + get_builtin_codegen_backend(&None, "llvm")().print_version(); } } } @@ -1088,7 +1088,7 @@ pub fn handle_options(args: &[String]) -> Option { if cg_flags.iter().any(|x| *x == "passes=list") { if cfg!(feature = "llvm") { - get_builtin_codegen_backend("llvm")().print_passes(); + get_builtin_codegen_backend(&None, "llvm")().print_passes(); } return None; } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index f34990a1a10..ec496032f52 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -241,7 +241,7 @@ pub fn get_codegen_backend(sopts: &config::Options) -> Box { let backend = match codegen_name { filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()), - codegen_name => get_builtin_codegen_backend(codegen_name), + codegen_name => get_builtin_codegen_backend(&sopts.maybe_sysroot, codegen_name), }; unsafe { @@ -366,15 +366,21 @@ fn sysroot_candidates() -> Vec { } } -pub fn get_builtin_codegen_backend(backend_name: &str) -> fn() -> Box { +pub fn get_builtin_codegen_backend( + maybe_sysroot: &Option, + backend_name: &str, +) -> fn() -> Box { match backend_name { #[cfg(feature = "llvm")] "llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new, - _ => get_codegen_sysroot(backend_name), + _ => get_codegen_sysroot(maybe_sysroot, backend_name), } } -pub fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box { +pub fn get_codegen_sysroot( + maybe_sysroot: &Option, + backend_name: &str, +) -> fn() -> Box { // For now we only allow this function to be called once as it'll dlopen a // few things, which seems to work best if we only do that once. In // general this assertion never trips due to the once guard in `get_codegen_backend`, @@ -389,8 +395,9 @@ pub fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box fn() -> Box = None; - let expected_name = - format!("rustc_codegen_{}-{}", backend_name, release_str().expect("CFG_RELEASE")); + let expected_names = &[ + format!("rustc_codegen_{}-{}", backend_name, release_str().expect("CFG_RELEASE")), + format!("rustc_codegen_{}", backend_name), + ]; for entry in d.filter_map(|e| e.ok()) { let path = entry.path(); let filename = match path.file_name().and_then(|s| s.to_str()) { @@ -438,7 +447,7 @@ pub fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box Date: Wed, 3 Feb 2021 21:00:07 +0100 Subject: [PATCH 007/370] Update test to collect item with a different type than the original vec --- library/alloc/tests/vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 9ae333ce2c3..9a0739a2759 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -931,7 +931,7 @@ fn test_from_iter_specialization_with_iterator_adapters() { .map_while(Option::Some) .peekable() .skip(1) - .map(|e| if e != 0 { Ok(e) } else { Err(()) }); + .map(|e| if e != usize::MAX { Ok(std::num::NonZeroUsize::new(e)) } else { Err(()) }); assert_in_place_trait(&iter); let sink = iter.collect::, _>>().unwrap(); let sinkptr = sink.as_ptr(); From 6d43225bfb08ec91f7476b76c7fec632c4a096ef Mon Sep 17 00:00:00 2001 From: Yechan Bae Date: Wed, 3 Feb 2021 16:36:33 -0500 Subject: [PATCH 008/370] Fixes #80335 --- library/alloc/src/str.rs | 40 ++++++++++++++++++++++---------------- library/alloc/tests/str.rs | 30 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index 70e0c7dba5e..a7584c6b651 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -90,8 +90,8 @@ impl> Join<&str> for [S] { } } -macro_rules! spezialize_for_lengths { - ($separator:expr, $target:expr, $iter:expr; $($num:expr),*) => { +macro_rules! specialize_for_lengths { + ($separator:expr, $target:expr, $iter:expr; $($num:expr),*) => {{ let mut target = $target; let iter = $iter; let sep_bytes = $separator; @@ -102,7 +102,8 @@ macro_rules! spezialize_for_lengths { $num => { for s in iter { copy_slice_and_advance!(target, sep_bytes); - copy_slice_and_advance!(target, s.borrow().as_ref()); + let content_bytes = s.borrow().as_ref(); + copy_slice_and_advance!(target, content_bytes); } }, )* @@ -110,11 +111,13 @@ macro_rules! spezialize_for_lengths { // arbitrary non-zero size fallback for s in iter { copy_slice_and_advance!(target, sep_bytes); - copy_slice_and_advance!(target, s.borrow().as_ref()); + let content_bytes = s.borrow().as_ref(); + copy_slice_and_advance!(target, content_bytes); } } } - }; + target + }} } macro_rules! copy_slice_and_advance { @@ -153,7 +156,7 @@ where // if the `len` calculation overflows, we'll panic // we would have run out of memory anyway and the rest of the function requires // the entire Vec pre-allocated for safety - let len = sep_len + let reserved_len = sep_len .checked_mul(iter.len()) .and_then(|n| { slice.iter().map(|s| s.borrow().as_ref().len()).try_fold(n, usize::checked_add) @@ -161,22 +164,25 @@ where .expect("attempt to join into collection with len > usize::MAX"); // crucial for safety - let mut result = Vec::with_capacity(len); - assert!(result.capacity() >= len); + let mut result = Vec::with_capacity(reserved_len); + debug_assert!(result.capacity() >= reserved_len); result.extend_from_slice(first.borrow().as_ref()); unsafe { - { - let pos = result.len(); - let target = result.get_unchecked_mut(pos..len); + let pos = result.len(); + let target = result.get_unchecked_mut(pos..reserved_len); - // copy separator and slices over without bounds checks - // generate loops with hardcoded offsets for small separators - // massive improvements possible (~ x2) - spezialize_for_lengths!(sep, target, iter; 0, 1, 2, 3, 4); - } - result.set_len(len); + // copy separator and slices over without bounds checks + // generate loops with hardcoded offsets for small separators + // massive improvements possible (~ x2) + let remain = specialize_for_lengths!(sep, target, iter; 0, 1, 2, 3, 4); + + // issue #80335: A weird borrow implementation can return different + // slices for the length calculation and the actual copy, so + // `remain.len()` might be non-zero. + let result_len = reserved_len - remain.len(); + result.set_len(result_len); } result } diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs index 604835e6cc4..6df8d8c2f35 100644 --- a/library/alloc/tests/str.rs +++ b/library/alloc/tests/str.rs @@ -160,6 +160,36 @@ fn test_join_for_different_lengths_with_long_separator() { test_join!("~~~~~a~~~~~bc", ["", "a", "bc"], "~~~~~"); } +#[test] +fn test_join_isue_80335() { + use core::{borrow::Borrow, cell::Cell}; + + struct WeirdBorrow { + state: Cell, + } + + impl Default for WeirdBorrow { + fn default() -> Self { + WeirdBorrow { state: Cell::new(false) } + } + } + + impl Borrow for WeirdBorrow { + fn borrow(&self) -> &str { + let state = self.state.get(); + if state { + "0" + } else { + self.state.set(true); + "123456" + } + } + } + + let arr: [WeirdBorrow; 3] = Default::default(); + test_join!("0-0-0", arr, "-"); +} + #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn test_unsafe_slice() { From 6233f3f4a391b9ef562e77dc4fb857ffaa4ca410 Mon Sep 17 00:00:00 2001 From: Vlad Frolov Date: Sat, 20 Feb 2021 15:22:48 +0200 Subject: [PATCH 009/370] alloc: Added `as_slice` method to `BinaryHeap` collection --- library/alloc/src/collections/binary_heap.rs | 23 ++++++++++++++++++++ library/alloc/tests/lib.rs | 1 + 2 files changed, 24 insertions(+) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 8a36b2af765..7a43a3a868b 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -889,6 +889,29 @@ impl BinaryHeap { self.data.shrink_to(min_capacity) } + /// Returns a slice of all values in the underlying vector, in arbitrary + /// order. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(binary_heap_as_slice)] + /// use std::collections::BinaryHeap; + /// let heap = BinaryHeap::from(vec![1, 2, 3, 4, 5, 6, 7]); + /// let slice = heap.as_slice(); + /// + /// // Will print in some order + /// for x in slice { + /// println!("{}", x); + /// } + /// ``` + #[unstable(feature = "binary_heap_as_slice", issue = "82331")] + pub fn as_slice(&self) -> &[T] { + self.data.as_slice() + } + /// Consumes the `BinaryHeap` and returns the underlying vector /// in arbitrary order. /// diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index dd98f806451..4679121c929 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -15,6 +15,7 @@ #![feature(binary_heap_drain_sorted)] #![feature(slice_ptr_get)] #![feature(binary_heap_retain)] +#![feature(binary_heap_as_slice)] #![feature(inplace_iteration)] #![feature(iter_map_while)] #![feature(int_bits_const)] From 5b84b9a8d8518e3db0e9f7995a54297a33c59b5c Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Wed, 24 Feb 2021 18:18:26 +0100 Subject: [PATCH 010/370] Constify methods of `std::net::SocketAddr`, `SocketAddrV4` and `SocketAddrV6` The following methods are made unstable const under the `const_socketaddr` feature: `SocketAddr` - `ip` - `port` - `is_ipv4` - `is_ipv6` `SocketAddrV4` - `ip` - `port` `SocketAddrV6` - `ip` - `port` - `flowinfo` - `scope_id` --- library/std/src/lib.rs | 1 + library/std/src/net/addr.rs | 30 ++++++++++++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 961cff661e3..c3ca7c3a1a4 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -247,6 +247,7 @@ #![feature(const_ip)] #![feature(const_ipv6)] #![feature(const_raw_ptr_deref)] +#![feature(const_socketaddr)] #![feature(const_ipv4)] #![feature(container_error_extra)] #![feature(core_intrinsics)] diff --git a/library/std/src/net/addr.rs b/library/std/src/net/addr.rs index 63de8712834..6857aa25628 100644 --- a/library/std/src/net/addr.rs +++ b/library/std/src/net/addr.rs @@ -143,7 +143,8 @@ impl SocketAddr { /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))); /// ``` #[stable(feature = "ip_addr", since = "1.7.0")] - pub fn ip(&self) -> IpAddr { + #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")] + pub const fn ip(&self) -> IpAddr { match *self { SocketAddr::V4(ref a) => IpAddr::V4(*a.ip()), SocketAddr::V6(ref a) => IpAddr::V6(*a.ip()), @@ -182,7 +183,8 @@ impl SocketAddr { /// assert_eq!(socket.port(), 8080); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn port(&self) -> u16 { + #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")] + pub const fn port(&self) -> u16 { match *self { SocketAddr::V4(ref a) => a.port(), SocketAddr::V6(ref a) => a.port(), @@ -224,7 +226,8 @@ impl SocketAddr { /// assert_eq!(socket.is_ipv6(), false); /// ``` #[stable(feature = "sockaddr_checker", since = "1.16.0")] - pub fn is_ipv4(&self) -> bool { + #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")] + pub const fn is_ipv4(&self) -> bool { matches!(*self, SocketAddr::V4(_)) } @@ -244,7 +247,8 @@ impl SocketAddr { /// assert_eq!(socket.is_ipv6(), true); /// ``` #[stable(feature = "sockaddr_checker", since = "1.16.0")] - pub fn is_ipv6(&self) -> bool { + #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")] + pub const fn is_ipv6(&self) -> bool { matches!(*self, SocketAddr::V6(_)) } } @@ -284,7 +288,8 @@ impl SocketAddrV4 { /// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1)); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn ip(&self) -> &Ipv4Addr { + #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")] + pub const fn ip(&self) -> &Ipv4Addr { // SAFETY: `Ipv4Addr` is `#[repr(C)] struct { _: in_addr; }`. // It is safe to cast from `&in_addr` to `&Ipv4Addr`. unsafe { &*(&self.inner.sin_addr as *const c::in_addr as *const Ipv4Addr) } @@ -317,7 +322,8 @@ impl SocketAddrV4 { /// assert_eq!(socket.port(), 8080); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn port(&self) -> u16 { + #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")] + pub const fn port(&self) -> u16 { ntohs(self.inner.sin_port) } @@ -380,7 +386,8 @@ impl SocketAddrV6 { /// assert_eq!(socket.ip(), &Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn ip(&self) -> &Ipv6Addr { + #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")] + pub const fn ip(&self) -> &Ipv6Addr { unsafe { &*(&self.inner.sin6_addr as *const c::in6_addr as *const Ipv6Addr) } } @@ -411,7 +418,8 @@ impl SocketAddrV6 { /// assert_eq!(socket.port(), 8080); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn port(&self) -> u16 { + #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")] + pub const fn port(&self) -> u16 { ntohs(self.inner.sin6_port) } @@ -452,7 +460,8 @@ impl SocketAddrV6 { /// assert_eq!(socket.flowinfo(), 10); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn flowinfo(&self) -> u32 { + #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")] + pub const fn flowinfo(&self) -> u32 { self.inner.sin6_flowinfo } @@ -490,7 +499,8 @@ impl SocketAddrV6 { /// assert_eq!(socket.scope_id(), 78); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn scope_id(&self) -> u32 { + #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")] + pub const fn scope_id(&self) -> u32 { self.inner.sin6_scope_id } From 77d1185f00699236c4caec6504d758644d747453 Mon Sep 17 00:00:00 2001 From: The8472 Date: Sat, 20 Feb 2021 22:45:30 +0100 Subject: [PATCH 011/370] parallelize tidy checks --- Cargo.lock | 1 + src/tools/tidy/Cargo.toml | 1 + src/tools/tidy/src/bins.rs | 7 +++- src/tools/tidy/src/lib.rs | 7 ++++ src/tools/tidy/src/main.rs | 81 +++++++++++++++++++++++++------------- 5 files changed, 67 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e95fd6af27..2f2d9065511 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5239,6 +5239,7 @@ name = "tidy" version = "0.1.0" dependencies = [ "cargo_metadata 0.11.1", + "crossbeam-utils 0.8.0", "lazy_static", "regex", "walkdir", diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index 777d7be8fdc..58c32993cb6 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -10,6 +10,7 @@ cargo_metadata = "0.11" regex = "1" lazy_static = "1" walkdir = "2" +crossbeam-utils = "0.8.0" [[bin]] name = "rust-tidy" diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs index 62cfa85577f..f4e203cac40 100644 --- a/src/tools/tidy/src/bins.rs +++ b/src/tools/tidy/src/bins.rs @@ -32,9 +32,12 @@ pub fn check(path: &Path, output: &Path, bad: &mut bool) { // readily create a file there to test. // // See #36706 and #74753 for context. - let mut temp_path = path.join("tidy-test-file"); + // + // We also add the thread ID to avoid threads trampling on each others files. + let file_name = format!("t{}.tidy-test-file", std::thread::current().id().as_u64()); + let mut temp_path = path.join(&file_name); match fs::File::create(&temp_path).or_else(|_| { - temp_path = output.join("tidy-test-file"); + temp_path = output.join(&file_name); fs::File::create(&temp_path) }) { Ok(file) => { diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 11d36751f67..45cc169470b 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -4,6 +4,7 @@ //! to be used by tools. #![cfg_attr(bootstrap, feature(str_split_once))] +#![feature(thread_id_value)] use std::fs::File; use std::io::Read; @@ -54,6 +55,12 @@ pub mod unit_tests; pub mod unstable_book; fn filter_dirs(path: &Path) -> bool { + // Filter out temporary files used by the bins module to probe the filesystem + match path.extension() { + Some(ext) if ext == "tidy-test-file" => return true, + _ => {} + } + let skip = [ "compiler/rustc_codegen_cranelift", "src/llvm-project", diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 2ac96e404ac..9151d2bb406 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -6,9 +6,11 @@ use tidy::*; +use crossbeam_utils::thread::scope; use std::env; use std::path::PathBuf; use std::process; +use std::sync::atomic::{AtomicBool, Ordering}; fn main() { let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into(); @@ -22,45 +24,68 @@ fn main() { let args: Vec = env::args().skip(1).collect(); - let mut bad = false; let verbose = args.iter().any(|s| *s == "--verbose"); - // Checks over tests. - debug_artifacts::check(&src_path, &mut bad); - ui_tests::check(&src_path, &mut bad); + let bad = std::sync::Arc::new(AtomicBool::new(false)); - // Checks that only make sense for the compiler. - errors::check(&compiler_path, &mut bad); - error_codes_check::check(&src_path, &mut bad); + scope(|s| { + macro_rules! check { + ($p:ident $(, $args:expr)* ) => { + s.spawn(|_| { + let mut flag = false; + $p::check($($args),* , &mut flag); + if (flag) { + bad.store(true, Ordering::Relaxed); + } + }); + } + } - // Checks that only make sense for the std libs. - pal::check(&library_path, &mut bad); + // Checks that are done on the cargo workspace. + check!(deps, &root_path, &cargo); + check!(extdeps, &root_path); - // Checks that need to be done for both the compiler and std libraries. - unit_tests::check(&src_path, &mut bad); - unit_tests::check(&compiler_path, &mut bad); - unit_tests::check(&library_path, &mut bad); + // Checks over tests. + check!(debug_artifacts, &src_path); + check!(ui_tests, &src_path); - bins::check(&src_path, &output_directory, &mut bad); - bins::check(&compiler_path, &output_directory, &mut bad); - bins::check(&library_path, &output_directory, &mut bad); + // Checks that only make sense for the compiler. + check!(errors, &compiler_path); + check!(error_codes_check, &src_path); - style::check(&src_path, &mut bad); - style::check(&compiler_path, &mut bad); - style::check(&library_path, &mut bad); + // Checks that only make sense for the std libs. + check!(pal, &library_path); - edition::check(&src_path, &mut bad); - edition::check(&compiler_path, &mut bad); - edition::check(&library_path, &mut bad); + // Checks that need to be done for both the compiler and std libraries. + check!(unit_tests, &src_path); + check!(unit_tests, &compiler_path); + check!(unit_tests, &library_path); - let collected = features::check(&src_path, &compiler_path, &library_path, &mut bad, verbose); - unstable_book::check(&src_path, collected, &mut bad); + check!(bins, &src_path, &output_directory); + check!(bins, &compiler_path, &output_directory); + check!(bins, &library_path, &output_directory); - // Checks that are done on the cargo workspace. - deps::check(&root_path, &cargo, &mut bad); - extdeps::check(&root_path, &mut bad); + check!(style, &src_path); + check!(style, &compiler_path); + check!(style, &library_path); - if bad { + check!(edition, &src_path); + check!(edition, &compiler_path); + check!(edition, &library_path); + + let collected = { + let mut flag = false; + let r = features::check(&src_path, &compiler_path, &library_path, &mut flag, verbose); + if flag { + bad.store(true, Ordering::Relaxed); + } + r + }; + check!(unstable_book, &src_path, collected); + }) + .unwrap(); + + if bad.load(Ordering::Relaxed) { eprintln!("some tidy checks failed"); process::exit(1); } From 207104010a5c60ac31d52a834f9d45094b927c48 Mon Sep 17 00:00:00 2001 From: The8472 Date: Sat, 13 Feb 2021 20:28:18 +0100 Subject: [PATCH 012/370] limit tidy parallelism by taking -j into account --- src/bootstrap/test.rs | 1 + src/tools/tidy/src/main.rs | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index c0cd24dd81f..af4263d85c3 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -782,6 +782,7 @@ impl Step for Tidy { cmd.arg(&builder.src); cmd.arg(&builder.initial_cargo); cmd.arg(&builder.out); + cmd.arg(builder.jobs().to_string()); if builder.is_verbose() { cmd.arg("--verbose"); } diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 9151d2bb406..2d19db38799 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -6,10 +6,13 @@ use tidy::*; -use crossbeam_utils::thread::scope; +use crossbeam_utils::thread::{scope, ScopedJoinHandle}; +use std::collections::VecDeque; use std::env; +use std::num::NonZeroUsize; use std::path::PathBuf; use std::process; +use std::str::FromStr; use std::sync::atomic::{AtomicBool, Ordering}; fn main() { @@ -17,6 +20,9 @@ fn main() { let cargo: PathBuf = env::args_os().nth(2).expect("need path to cargo").into(); let output_directory: PathBuf = env::args_os().nth(3).expect("need path to output directory").into(); + let concurrency: NonZeroUsize = + FromStr::from_str(&env::args().nth(4).expect("need concurrency")) + .expect("concurrency must be a number"); let src_path = root_path.join("src"); let library_path = root_path.join("library"); @@ -29,15 +35,23 @@ fn main() { let bad = std::sync::Arc::new(AtomicBool::new(false)); scope(|s| { + let mut handles: VecDeque> = + VecDeque::with_capacity(concurrency.get()); + macro_rules! check { ($p:ident $(, $args:expr)* ) => { - s.spawn(|_| { + while handles.len() >= concurrency.get() { + handles.pop_front().unwrap().join().unwrap(); + } + + let handle = s.spawn(|_| { let mut flag = false; $p::check($($args),* , &mut flag); if (flag) { bad.store(true, Ordering::Relaxed); } }); + handles.push_back(handle); } } @@ -74,6 +88,9 @@ fn main() { check!(edition, &library_path); let collected = { + while handles.len() >= concurrency.get() { + handles.pop_front().unwrap().join().unwrap(); + } let mut flag = false; let r = features::check(&src_path, &compiler_path, &library_path, &mut flag, verbose); if flag { From e7f340e19be8a4d50214c364aabb5577b6b38e9f Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Tue, 16 Feb 2021 17:13:43 +0100 Subject: [PATCH 013/370] BTree: move blocks around in node.rs --- library/alloc/src/collections/btree/node.rs | 332 ++++++++++---------- 1 file changed, 165 insertions(+), 167 deletions(-) diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index 9a7119470f3..f330a1bb3dc 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -128,106 +128,6 @@ impl InternalNode { /// is not a separate type and has no destructor. type BoxedNode = NonNull>; -/// The root node of an owned tree. -/// -/// Note that this does not have a destructor, and must be cleaned up manually. -pub type Root = NodeRef; - -impl Root { - /// Returns a new owned tree, with its own root node that is initially empty. - pub fn new() -> Self { - NodeRef::new_leaf().forget_type() - } -} - -impl NodeRef { - fn new_leaf() -> Self { - Self::from_new_leaf(LeafNode::new()) - } - - fn from_new_leaf(leaf: Box>) -> Self { - NodeRef { height: 0, node: NonNull::from(Box::leak(leaf)), _marker: PhantomData } - } -} - -impl NodeRef { - fn new_internal(child: Root) -> Self { - let mut new_node = unsafe { InternalNode::new() }; - new_node.edges[0].write(child.node); - unsafe { NodeRef::from_new_internal(new_node, child.height + 1) } - } - - /// # Safety - /// `height` must not be zero. - unsafe fn from_new_internal(internal: Box>, height: usize) -> Self { - debug_assert!(height > 0); - let node = NonNull::from(Box::leak(internal)).cast(); - let mut this = NodeRef { height, node, _marker: PhantomData }; - this.borrow_mut().correct_all_childrens_parent_links(); - this - } -} - -impl NodeRef { - /// Mutably borrows the owned root node. Unlike `reborrow_mut`, this is safe - /// because the return value cannot be used to destroy the root, and there - /// cannot be other references to the tree. - pub fn borrow_mut(&mut self) -> NodeRef, K, V, Type> { - NodeRef { height: self.height, node: self.node, _marker: PhantomData } - } - - /// Slightly mutably borrows the owned root node. - pub fn borrow_valmut(&mut self) -> NodeRef, K, V, Type> { - NodeRef { height: self.height, node: self.node, _marker: PhantomData } - } - - /// Irreversibly transitions to a reference that permits traversal and offers - /// destructive methods and little else. - pub fn into_dying(self) -> NodeRef { - NodeRef { height: self.height, node: self.node, _marker: PhantomData } - } -} - -impl NodeRef { - /// Adds a new internal node with a single edge pointing to the previous root node, - /// make that new node the root node, and return it. This increases the height by 1 - /// and is the opposite of `pop_internal_level`. - pub fn push_internal_level(&mut self) -> NodeRef, K, V, marker::Internal> { - super::mem::take_mut(self, |old_root| NodeRef::new_internal(old_root).forget_type()); - - // `self.borrow_mut()`, except that we just forgot we're internal now: - NodeRef { height: self.height, node: self.node, _marker: PhantomData } - } - - /// Removes the internal root node, using its first child as the new root node. - /// As it is intended only to be called when the root node has only one child, - /// no cleanup is done on any of the keys, values and other children. - /// This decreases the height by 1 and is the opposite of `push_internal_level`. - /// - /// Requires exclusive access to the `Root` object but not to the root node; - /// it will not invalidate other handles or references to the root node. - /// - /// Panics if there is no internal level, i.e., if the root node is a leaf. - pub fn pop_internal_level(&mut self) { - assert!(self.height > 0); - - let top = self.node; - - // SAFETY: we asserted to be internal. - let internal_self = unsafe { self.borrow_mut().cast_to_internal_unchecked() }; - // SAFETY: we borrowed `self` exclusively and its borrow type is exclusive. - let internal_node = unsafe { &mut *NodeRef::as_internal_ptr(&internal_self) }; - // SAFETY: the first edge is always initialized. - self.node = unsafe { internal_node.edges[0].assume_init_read() }; - self.height -= 1; - self.clear_parent_link(); - - unsafe { - Global.deallocate(top.cast(), Layout::new::>()); - } - } -} - // N.B. `NodeRef` is always covariant in `K` and `V`, even when the `BorrowType` // is `Mut`. This is technically wrong, but cannot result in any unsafety due to // internal use of `NodeRef` because we stay completely generic over `K` and `V`. @@ -292,6 +192,11 @@ pub struct NodeRef { _marker: PhantomData<(BorrowType, Type)>, } +/// The root node of an owned tree. +/// +/// Note that this does not have a destructor, and must be cleaned up manually. +pub type Root = NodeRef; + impl<'a, K: 'a, V: 'a, Type> Copy for NodeRef, K, V, Type> {} impl<'a, K: 'a, V: 'a, Type> Clone for NodeRef, K, V, Type> { fn clone(&self) -> Self { @@ -307,6 +212,34 @@ unsafe impl<'a, K: Send + 'a, V: Send + 'a, Type> Send for NodeRef Send for NodeRef {} unsafe impl Send for NodeRef {} +impl NodeRef { + fn new_leaf() -> Self { + Self::from_new_leaf(LeafNode::new()) + } + + fn from_new_leaf(leaf: Box>) -> Self { + NodeRef { height: 0, node: NonNull::from(Box::leak(leaf)), _marker: PhantomData } + } +} + +impl NodeRef { + fn new_internal(child: Root) -> Self { + let mut new_node = unsafe { InternalNode::new() }; + new_node.edges[0].write(child.node); + unsafe { NodeRef::from_new_internal(new_node, child.height + 1) } + } + + /// # Safety + /// `height` must not be zero. + unsafe fn from_new_internal(internal: Box>, height: usize) -> Self { + debug_assert!(height > 0); + let node = NonNull::from(Box::leak(internal)).cast(); + let mut this = NodeRef { height, node, _marker: PhantomData }; + this.borrow_mut().correct_all_childrens_parent_links(); + this + } +} + impl NodeRef { /// Unpack a node reference that was packed as `NodeRef::parent`. fn from_internal(node: NonNull>, height: usize) -> Self { @@ -420,6 +353,19 @@ impl NodeRef } } +impl NodeRef { + /// Could be a public implementation of PartialEq, but only used in this module. + fn eq(&self, other: &Self) -> bool { + let Self { node, height, _marker } = self; + if node.eq(&other.node) { + debug_assert_eq!(*height, other.height); + true + } else { + false + } + } +} + impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { /// Exposes the leaf portion of any leaf or internal node in an immutable tree. fn into_leaf(self) -> &'a LeafNode { @@ -461,20 +407,6 @@ impl NodeRef { } } -impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { - /// Unsafely asserts to the compiler the static information that this node is a `Leaf`. - unsafe fn cast_to_leaf_unchecked(self) -> NodeRef, K, V, marker::Leaf> { - debug_assert!(self.height == 0); - NodeRef { height: self.height, node: self.node, _marker: PhantomData } - } - - /// Unsafely asserts to the compiler the static information that this node is an `Internal`. - unsafe fn cast_to_internal_unchecked(self) -> NodeRef, K, V, marker::Internal> { - debug_assert!(self.height > 0); - NodeRef { height: self.height, node: self.node, _marker: PhantomData } - } -} - impl<'a, K, V, Type> NodeRef, K, V, Type> { /// Temporarily takes out another, mutable reference to the same node. Beware, as /// this method is very dangerous, doubly so since it may not immediately appear @@ -577,6 +509,22 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { } } +impl<'a, K, V> NodeRef, K, V, marker::Internal> { + /// # Safety + /// Every item returned by `range` is a valid edge index for the node. + unsafe fn correct_childrens_parent_links>(&mut self, range: R) { + for i in range { + debug_assert!(i <= self.len()); + unsafe { Handle::new_edge(self.reborrow_mut(), i) }.correct_parent_link(); + } + } + + fn correct_all_childrens_parent_links(&mut self) { + let len = self.len(); + unsafe { self.correct_childrens_parent_links(0..=len) }; + } +} + impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { /// Sets the node's link to its parent edge, /// without invalidating other references to the node. @@ -596,6 +544,71 @@ impl NodeRef { } } +impl NodeRef { + /// Returns a new owned tree, with its own root node that is initially empty. + pub fn new() -> Self { + NodeRef::new_leaf().forget_type() + } + + /// Adds a new internal node with a single edge pointing to the previous root node, + /// make that new node the root node, and return it. This increases the height by 1 + /// and is the opposite of `pop_internal_level`. + pub fn push_internal_level(&mut self) -> NodeRef, K, V, marker::Internal> { + super::mem::take_mut(self, |old_root| NodeRef::new_internal(old_root).forget_type()); + + // `self.borrow_mut()`, except that we just forgot we're internal now: + NodeRef { height: self.height, node: self.node, _marker: PhantomData } + } + + /// Removes the internal root node, using its first child as the new root node. + /// As it is intended only to be called when the root node has only one child, + /// no cleanup is done on any of the keys, values and other children. + /// This decreases the height by 1 and is the opposite of `push_internal_level`. + /// + /// Requires exclusive access to the `Root` object but not to the root node; + /// it will not invalidate other handles or references to the root node. + /// + /// Panics if there is no internal level, i.e., if the root node is a leaf. + pub fn pop_internal_level(&mut self) { + assert!(self.height > 0); + + let top = self.node; + + // SAFETY: we asserted to be internal. + let internal_self = unsafe { self.borrow_mut().cast_to_internal_unchecked() }; + // SAFETY: we borrowed `self` exclusively and its borrow type is exclusive. + let internal_node = unsafe { &mut *NodeRef::as_internal_ptr(&internal_self) }; + // SAFETY: the first edge is always initialized. + self.node = unsafe { internal_node.edges[0].assume_init_read() }; + self.height -= 1; + self.clear_parent_link(); + + unsafe { + Global.deallocate(top.cast(), Layout::new::>()); + } + } +} + +impl NodeRef { + /// Mutably borrows the owned root node. Unlike `reborrow_mut`, this is safe + /// because the return value cannot be used to destroy the root, and there + /// cannot be other references to the tree. + pub fn borrow_mut(&mut self) -> NodeRef, K, V, Type> { + NodeRef { height: self.height, node: self.node, _marker: PhantomData } + } + + /// Slightly mutably borrows the owned root node. + pub fn borrow_valmut(&mut self) -> NodeRef, K, V, Type> { + NodeRef { height: self.height, node: self.node, _marker: PhantomData } + } + + /// Irreversibly transitions to a reference that permits traversal and offers + /// destructive methods and little else. + pub fn into_dying(self) -> NodeRef { + NodeRef { height: self.height, node: self.node, _marker: PhantomData } + } +} + impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Leaf> { /// Adds a key-value pair to the end of the node. pub fn push(&mut self, key: K, val: V) { @@ -610,22 +623,6 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Leaf> { } } -impl<'a, K, V> NodeRef, K, V, marker::Internal> { - /// # Safety - /// Every item returned by `range` is a valid edge index for the node. - unsafe fn correct_childrens_parent_links>(&mut self, range: R) { - for i in range { - debug_assert!(i <= self.len()); - unsafe { Handle::new_edge(self.reborrow_mut(), i) }.correct_parent_link(); - } - } - - fn correct_all_childrens_parent_links(&mut self) { - let len = self.len(); - unsafe { self.correct_childrens_parent_links(0..=len) }; - } -} - impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Internal> { /// Adds a key-value pair, and an edge to go to the right of that pair, /// to the end of the node. @@ -645,6 +642,20 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Internal> { } } +impl NodeRef { + /// Removes any static information asserting that this node is a `Leaf` node. + pub fn forget_type(self) -> NodeRef { + NodeRef { height: self.height, node: self.node, _marker: PhantomData } + } +} + +impl NodeRef { + /// Removes any static information asserting that this node is an `Internal` node. + pub fn forget_type(self) -> NodeRef { + NodeRef { height: self.height, node: self.node, _marker: PhantomData } + } +} + impl NodeRef { /// Checks whether a node is an `Internal` node or a `Leaf` node. pub fn force( @@ -669,6 +680,20 @@ impl NodeRef { } } +impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { + /// Unsafely asserts to the compiler the static information that this node is a `Leaf`. + unsafe fn cast_to_leaf_unchecked(self) -> NodeRef, K, V, marker::Leaf> { + debug_assert!(self.height == 0); + NodeRef { height: self.height, node: self.node, _marker: PhantomData } + } + + /// Unsafely asserts to the compiler the static information that this node is an `Internal`. + unsafe fn cast_to_internal_unchecked(self) -> NodeRef, K, V, marker::Internal> { + debug_assert!(self.height > 0); + NodeRef { height: self.height, node: self.node, _marker: PhantomData } + } +} + /// A reference to a specific key-value pair or edge within a node. The `Node` parameter /// must be a `NodeRef`, while the `Type` can either be `KV` (signifying a handle on a key-value /// pair) or `Edge` (signifying a handle on an edge). @@ -722,19 +747,6 @@ impl Handle, mar } } -impl NodeRef { - /// Could be a public implementation of PartialEq, but only used in this module. - fn eq(&self, other: &Self) -> bool { - let Self { node, height, _marker } = self; - if node.eq(&other.node) { - debug_assert_eq!(*height, other.height); - true - } else { - false - } - } -} - impl PartialEq for Handle, HandleType> { @@ -754,16 +766,6 @@ impl } } -impl<'a, K, V, Type> Handle, K, V, marker::LeafOrInternal>, Type> { - /// Unsafely asserts to the compiler the static information that the handle's node is a `Leaf`. - pub unsafe fn cast_to_leaf_unchecked( - self, - ) -> Handle, K, V, marker::Leaf>, Type> { - let node = unsafe { self.node.cast_to_leaf_unchecked() }; - Handle { node, idx: self.idx, _marker: PhantomData } - } -} - impl<'a, K, V, NodeType, HandleType> Handle, K, V, NodeType>, HandleType> { /// Temporarily takes out another, mutable handle on the same location. Beware, as /// this method is very dangerous, doubly so since it may not immediately appear @@ -1466,20 +1468,6 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { } } -impl NodeRef { - /// Removes any static information asserting that this node is a `Leaf` node. - pub fn forget_type(self) -> NodeRef { - NodeRef { height: self.height, node: self.node, _marker: PhantomData } - } -} - -impl NodeRef { - /// Removes any static information asserting that this node is an `Internal` node. - pub fn forget_type(self) -> NodeRef { - NodeRef { height: self.height, node: self.node, _marker: PhantomData } - } -} - impl Handle, marker::Edge> { pub fn forget_node_type( self, @@ -1531,6 +1519,16 @@ impl Handle Handle, K, V, marker::LeafOrInternal>, Type> { + /// Unsafely asserts to the compiler the static information that the handle's node is a `Leaf`. + pub unsafe fn cast_to_leaf_unchecked( + self, + ) -> Handle, K, V, marker::Leaf>, Type> { + let node = unsafe { self.node.cast_to_leaf_unchecked() }; + Handle { node, idx: self.idx, _marker: PhantomData } + } +} + impl<'a, K, V> Handle, K, V, marker::LeafOrInternal>, marker::Edge> { /// Move the suffix after `self` from one node to another one. `right` must be empty. /// The first edge of `right` remains unchanged. From b63df38a98a1dac5a7d4bc54a28a6204923443a4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 5 Mar 2021 09:32:47 +0000 Subject: [PATCH 014/370] Shrink the size of Rvalue by 16 bytes --- src/base.rs | 4 ++-- src/lib.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/base.rs b/src/base.rs index 4842628a99d..db65c38ced1 100644 --- a/src/base.rs +++ b/src/base.rs @@ -494,14 +494,14 @@ fn codegen_stmt<'tcx>( let val = crate::constant::codegen_tls_ref(fx, def_id, lval.layout()); lval.write_cvalue(fx, val); } - Rvalue::BinaryOp(bin_op, ref lhs, ref rhs) => { + Rvalue::BinaryOp(bin_op, box (ref lhs, ref rhs)) => { let lhs = codegen_operand(fx, lhs); let rhs = codegen_operand(fx, rhs); let res = crate::num::codegen_binop(fx, bin_op, lhs, rhs); lval.write_cvalue(fx, res); } - Rvalue::CheckedBinaryOp(bin_op, ref lhs, ref rhs) => { + Rvalue::CheckedBinaryOp(bin_op, box (ref lhs, ref rhs)) => { let lhs = codegen_operand(fx, lhs); let rhs = codegen_operand(fx, rhs); diff --git a/src/lib.rs b/src/lib.rs index 1480ab25133..33158d89d30 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ associated_type_bounds, never_type, try_blocks, + box_patterns, hash_drain_filter )] #![warn(rust_2018_idioms)] From 27886cd6b6a52d5bf3d0a9ea667e04c5e8c59705 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 5 Mar 2021 19:12:59 +0100 Subject: [PATCH 015/370] Merge commit '9a0c32934ebe376128230aa8da3275697b2053e7' into sync_cg_clif-2021-03-05 --- .cirrus.yml | 25 ++ .github/workflows/main.yml | 5 +- .vscode/settings.json | 2 +- Cargo.lock | 128 +++----- Cargo.toml | 5 +- build.sh | 16 +- build_sysroot/Cargo.lock | 20 +- build_sysroot/Cargo.toml | 2 - build_sysroot/alloc_system/Cargo.toml | 13 - build_sysroot/build_sysroot.sh | 2 +- build_sysroot/prepare_sysroot_src.sh | 4 +- clean_all.sh | 2 +- ...ins-Disable-128bit-atomic-operations.patch | 48 +++ example/alloc_example.rs | 2 +- .../lib.rs => example/alloc_system.rs | 136 +-------- ...itrary_self_types_pointers_and_wrappers.rs | 31 +- example/mini_core.rs | 16 + example/mini_core_hello_world.rs | 3 + ...022-core-Disable-not-compiling-tests.patch | 16 - ...027-Disable-128bit-atomic-operations.patch | 103 +++++++ prepare.sh | 2 +- rust-toolchain | 2 +- rustfmt.toml | 4 + scripts/cargo.sh | 2 +- scripts/config.sh | 4 +- scripts/rustup.sh | 2 +- scripts/test_bootstrap.sh | 42 ++- scripts/tests.sh | 13 +- src/abi/comments.rs | 56 ++-- src/abi/mod.rs | 144 +++------ src/abi/pass_mode.rs | 108 ++----- src/abi/returning.rs | 90 ++---- src/allocator.rs | 29 +- src/analyze.rs | 9 +- src/archive.rs | 49 +-- src/atomic_shim.rs | 185 ------------ src/backend.rs | 62 +--- src/base.rs | 269 +++++------------ src/bin/cg_clif.rs | 8 +- src/bin/cg_clif_build_sysroot.rs | 11 +- src/cast.rs | 34 +-- src/codegen_i128.rs | 87 ++---- src/common.rs | 111 ++----- src/constant.rs | 118 +++----- src/debuginfo/emit.rs | 14 +- src/debuginfo/line_info.rs | 75 ++--- src/debuginfo/mod.rs | 157 ++-------- src/debuginfo/unwind.rs | 27 +- src/discriminant.rs | 45 +-- src/driver/aot.rs | 114 ++----- src/driver/jit.rs | 115 +++---- src/driver/mod.rs | 32 +- src/inline_asm.rs | 57 +--- src/intrinsics/cpuid.rs | 44 +-- src/intrinsics/llvm.rs | 2 +- src/intrinsics/mod.rs | 280 +++++++++--------- src/intrinsics/simd.rs | 2 +- src/lib.rs | 55 ++-- src/main_shim.rs | 29 +- src/metadata.rs | 4 +- src/num.rs | 72 ++--- src/optimize/code_layout.rs | 10 +- src/optimize/mod.rs | 7 +- src/optimize/peephole.rs | 22 +- src/optimize/stack2reg.rs | 49 +-- src/pointer.rs | 123 ++------ src/pretty_clif.rs | 72 ++--- src/toolchain.rs | 15 +- src/trap.rs | 12 +- src/unsize.rs | 75 ++--- src/value_and_place.rs | 187 ++++-------- src/vtable.rs | 23 +- test.sh | 2 +- 73 files changed, 1145 insertions(+), 2596 deletions(-) create mode 100644 .cirrus.yml delete mode 100644 build_sysroot/alloc_system/Cargo.toml create mode 100644 crate_patches/0002-compiler-builtins-Disable-128bit-atomic-operations.patch rename build_sysroot/alloc_system/lib.rs => example/alloc_system.rs (62%) create mode 100644 patches/0027-Disable-128bit-atomic-operations.patch create mode 100644 rustfmt.toml delete mode 100644 src/atomic_shim.rs diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 00000000000..e173df423a7 --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,25 @@ +task: + name: freebsd + freebsd_instance: + image: freebsd-12-1-release-amd64 + setup_rust_script: + - pkg install -y curl git bash + - curl https://sh.rustup.rs -sSf --output rustup.sh + - sh rustup.sh --default-toolchain none -y --profile=minimal + cargo_bin_cache: + folder: ~/.cargo/bin + target_cache: + folder: target + prepare_script: + - . $HOME/.cargo/env + - git config --global user.email "user@example.com" + - git config --global user.name "User" + - ./prepare.sh + test_script: + - . $HOME/.cargo/env + - # Enable backtraces for easier debugging + - export RUST_BACKTRACE=1 + - # Reduce amount of benchmark runs as they are slow + - export COMPILE_RUNS=2 + - export RUN_RUNS=2 + - ./test.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 20c58423a0c..e6d3375fb1b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,9 +12,6 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] - env: - - BACKEND: "" - - BACKEND: --oldbe steps: - uses: actions/checkout@v2 @@ -54,7 +51,7 @@ jobs: export COMPILE_RUNS=2 export RUN_RUNS=2 - ./test.sh $BACKEND + ./test.sh - name: Package prebuilt cg_clif run: tar cvfJ cg_clif.tar.xz build diff --git a/.vscode/settings.json b/.vscode/settings.json index 19ea41563df..a13d5931ffa 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { // source for rustc_* is not included in the rust-src component; disable the errors about this - "rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate"], + "rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "macro-error"], "rust-analyzer.assist.importMergeBehavior": "last", "rust-analyzer.cargo.loadOutDirsFromCheck": true, "rust-analyzer.linkedProjects": [ diff --git a/Cargo.lock b/Cargo.lock index 5495cfa5eaa..76d9f0d27ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "anyhow" version = "1.0.38" @@ -29,18 +31,6 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" -[[package]] -name = "cc" -version = "1.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -49,16 +39,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "byteorder", "cranelift-bforest", @@ -75,8 +65,8 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -84,18 +74,18 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" [[package]] name = "cranelift-entity" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" [[package]] name = "cranelift-frontend" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "cranelift-codegen", "log", @@ -105,8 +95,8 @@ dependencies = [ [[package]] name = "cranelift-jit" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "anyhow", "cranelift-codegen", @@ -123,8 +113,8 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "anyhow", "cranelift-codegen", @@ -135,18 +125,17 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "cranelift-codegen", - "raw-cpuid", "target-lexicon", ] [[package]] name = "cranelift-object" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "anyhow", "cranelift-codegen", @@ -162,7 +151,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -219,9 +208,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.82" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" [[package]] name = "libloading" @@ -229,17 +218,17 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "winapi", ] [[package]] name = "log" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 0.1.10", + "cfg-if", ] [[package]] @@ -253,9 +242,9 @@ dependencies = [ [[package]] name = "object" -version = "0.22.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" +checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4" dependencies = [ "crc32fast", "indexmap", @@ -272,24 +261,13 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ "proc-macro2", ] -[[package]] -name = "raw-cpuid" -version = "8.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fdf7d9dbd43f3d81d94a49c1c3df73cc2b3827995147e6cf7f89d4ec5483e73" -dependencies = [ - "bitflags", - "cc", - "rustc_version", -] - [[package]] name = "regalloc" version = "0.0.31" @@ -337,30 +315,6 @@ dependencies = [ "target-lexicon", ] -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "smallvec" version = "1.6.1" @@ -369,9 +323,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "syn" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5" +checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" dependencies = [ "proc-macro2", "quote", @@ -380,24 +334,24 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee5a98e506fb7231a304c3a1bd7c132a55016cf65001e0282480665870dfcb9" +checksum = "422045212ea98508ae3d28025bc5aaa2bd4a9cdaecd442a08da2ee620ee9ea95" [[package]] name = "thiserror" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146" +checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1" +checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 3820fce6d1e..9861af1f8ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,14 +9,14 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main", features = ["unwind", "x86", "x64"] } +cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main", features = ["unwind", "x64"] } cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" } cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" } cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main", optional = true } cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" } target-lexicon = "0.11.0" gimli = { version = "0.23.0", default-features = false, features = ["write"]} -object = { version = "0.22.0", default-features = false, features = ["std", "read_core", "write", "coff", "elf", "macho", "pe"] } +object = { version = "0.23.0", default-features = false, features = ["std", "read_core", "write", "coff", "elf", "macho", "pe"] } ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" } indexmap = "1.0.2" @@ -38,7 +38,6 @@ smallvec = "1.6.1" default = ["jit", "inline_asm"] jit = ["cranelift-jit", "libloading"] inline_asm = [] -oldbe = [] [profile.dev] # By compiling dependencies with optimizations, performing tests gets much faster. diff --git a/build.sh b/build.sh index 598ce35ecea..090349e54b1 100755 --- a/build.sh +++ b/build.sh @@ -1,11 +1,10 @@ -#!/bin/bash +#!/usr/bin/env bash set -e # Settings export CHANNEL="release" build_sysroot="clif" target_dir='build' -oldbe='' while [[ $# != 0 ]]; do case $1 in "--debug") @@ -19,12 +18,9 @@ while [[ $# != 0 ]]; do target_dir=$2 shift ;; - "--oldbe") - oldbe='--features oldbe' - ;; *) echo "Unknown flag '$1'" - echo "Usage: ./build.sh [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--oldbe]" + echo "Usage: ./build.sh [--debug] [--sysroot none|clif|llvm] [--target-dir DIR]" exit 1 ;; esac @@ -34,19 +30,19 @@ done # Build cg_clif unset CARGO_TARGET_DIR unamestr=$(uname) -if [[ "$unamestr" == 'Linux' ]]; then +if [[ "$unamestr" == 'Linux' || "$unamestr" == "FreeBSD" ]]; then export RUSTFLAGS='-Clink-arg=-Wl,-rpath=$ORIGIN/../lib '$RUSTFLAGS elif [[ "$unamestr" == 'Darwin' ]]; then export RUSTFLAGS='-Csplit-debuginfo=unpacked -Clink-arg=-Wl,-rpath,@loader_path/../lib -Zosx-rpath-install-name '$RUSTFLAGS dylib_ext='dylib' else - echo "Unsupported os" + echo "Unsupported os $unamestr" exit 1 fi if [[ "$CHANNEL" == "release" ]]; then - cargo build $oldbe --release + cargo build --release else - cargo build $oldbe + cargo build fi source scripts/ext_config.sh diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index 0da9999c172..a7650ab995b 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "addr2line" version = "0.14.1" @@ -30,15 +32,6 @@ dependencies = [ "core", ] -[[package]] -name = "alloc_system" -version = "0.0.0" -dependencies = [ - "compiler_builtins", - "core", - "libc", -] - [[package]] name = "autocfg" version = "1.0.1" @@ -47,9 +40,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "cc" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" +checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" [[package]] name = "cfg-if" @@ -139,9 +132,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cca32fa0182e8c0989459524dc356b8f2b5c10f1b9eb521b7d182c03cf8c5ff" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" dependencies = [ "rustc-std-workspace-core", ] @@ -258,7 +251,6 @@ name = "sysroot" version = "0.0.0" dependencies = [ "alloc", - "alloc_system", "compiler_builtins", "core", "std", diff --git a/build_sysroot/Cargo.toml b/build_sysroot/Cargo.toml index 82516c98af2..04748d5dbab 100644 --- a/build_sysroot/Cargo.toml +++ b/build_sysroot/Cargo.toml @@ -9,8 +9,6 @@ alloc = { path = "./sysroot_src/library/alloc" } std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] } test = { path = "./sysroot_src/library/test" } -alloc_system = { path = "./alloc_system" } - compiler_builtins = { version = "0.1.39", default-features = false, features = ["no-asm"] } [patch.crates-io] diff --git a/build_sysroot/alloc_system/Cargo.toml b/build_sysroot/alloc_system/Cargo.toml deleted file mode 100644 index 9fffca84300..00000000000 --- a/build_sysroot/alloc_system/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -authors = ["The Rust Project Developers", "bjorn3 (edited to be usable outside the rust source)"] -name = "alloc_system" -version = "0.0.0" -[lib] -name = "alloc_system" -path = "lib.rs" -test = false -doc = false -[dependencies] -core = { path = "../sysroot_src/library/core" } -libc = { version = "0.2.43", features = ['rustc-dep-of-std'], default-features = false } -compiler_builtins = "0.1" diff --git a/build_sysroot/build_sysroot.sh b/build_sysroot/build_sysroot.sh index 282ce4a582c..636aa5f3f3d 100755 --- a/build_sysroot/build_sysroot.sh +++ b/build_sysroot/build_sysroot.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Requires the CHANNEL env var to be set to `debug` or `release.` diff --git a/build_sysroot/prepare_sysroot_src.sh b/build_sysroot/prepare_sysroot_src.sh index d3b87e02ba8..c90205db0fb 100755 --- a/build_sysroot/prepare_sysroot_src.sh +++ b/build_sysroot/prepare_sysroot_src.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e cd "$(dirname "$0")" @@ -33,7 +33,7 @@ git clone https://github.com/rust-lang/compiler-builtins.git || echo "rust-lang/ pushd compiler-builtins git checkout -- . git checkout 0.1.39 -git apply ../../crate_patches/0001-compiler-builtins-Remove-rotate_left-from-Int.patch +git apply ../../crate_patches/000*-compiler-builtins-*.patch popd echo "Successfully prepared sysroot source for building" diff --git a/clean_all.sh b/clean_all.sh index b47efe72bce..a7bbeb05cac 100755 --- a/clean_all.sh +++ b/clean_all.sh @@ -1,4 +1,4 @@ -#!/bin/bash --verbose +#!/usr/bin/env bash set -e rm -rf target/ build/ build_sysroot/{sysroot_src/,target/,compiler-builtins/} perf.data{,.old} diff --git a/crate_patches/0002-compiler-builtins-Disable-128bit-atomic-operations.patch b/crate_patches/0002-compiler-builtins-Disable-128bit-atomic-operations.patch new file mode 100644 index 00000000000..7daea99f579 --- /dev/null +++ b/crate_patches/0002-compiler-builtins-Disable-128bit-atomic-operations.patch @@ -0,0 +1,48 @@ +From 1d574bf5e32d51641dcacaf8ef777e95b44f6f2a Mon Sep 17 00:00:00 2001 +From: bjorn3 +Date: Thu, 18 Feb 2021 18:30:55 +0100 +Subject: [PATCH] Disable 128bit atomic operations + +Cranelift doesn't support them yet +--- + src/mem/mod.rs | 12 ------------ + 1 file changed, 12 deletions(-) + +diff --git a/src/mem/mod.rs b/src/mem/mod.rs +index 107762c..2d1ae10 100644 +--- a/src/mem/mod.rs ++++ b/src/mem/mod.rs +@@ -137,10 +137,6 @@ intrinsics! { + pub extern "C" fn __llvm_memcpy_element_unordered_atomic_8(dest: *mut u64, src: *const u64, bytes: usize) -> () { + memcpy_element_unordered_atomic(dest, src, bytes); + } +- #[cfg(target_has_atomic_load_store = "128")] +- pub extern "C" fn __llvm_memcpy_element_unordered_atomic_16(dest: *mut u128, src: *const u128, bytes: usize) -> () { +- memcpy_element_unordered_atomic(dest, src, bytes); +- } + + #[cfg(target_has_atomic_load_store = "8")] + pub extern "C" fn __llvm_memmove_element_unordered_atomic_1(dest: *mut u8, src: *const u8, bytes: usize) -> () { +@@ -158,10 +154,6 @@ intrinsics! { + pub extern "C" fn __llvm_memmove_element_unordered_atomic_8(dest: *mut u64, src: *const u64, bytes: usize) -> () { + memmove_element_unordered_atomic(dest, src, bytes); + } +- #[cfg(target_has_atomic_load_store = "128")] +- pub extern "C" fn __llvm_memmove_element_unordered_atomic_16(dest: *mut u128, src: *const u128, bytes: usize) -> () { +- memmove_element_unordered_atomic(dest, src, bytes); +- } + + #[cfg(target_has_atomic_load_store = "8")] + pub extern "C" fn __llvm_memset_element_unordered_atomic_1(s: *mut u8, c: u8, bytes: usize) -> () { +@@ -179,8 +171,4 @@ intrinsics! { + pub extern "C" fn __llvm_memset_element_unordered_atomic_8(s: *mut u64, c: u8, bytes: usize) -> () { + memset_element_unordered_atomic(s, c, bytes); + } +- #[cfg(target_has_atomic_load_store = "128")] +- pub extern "C" fn __llvm_memset_element_unordered_atomic_16(s: *mut u128, c: u8, bytes: usize) -> () { +- memset_element_unordered_atomic(s, c, bytes); +- } + } +-- +2.26.2.7.g19db9cfb68 + diff --git a/example/alloc_example.rs b/example/alloc_example.rs index f59600ebb33..71e93e87b6c 100644 --- a/example/alloc_example.rs +++ b/example/alloc_example.rs @@ -1,4 +1,4 @@ -#![feature(start, box_syntax, alloc_system, core_intrinsics, alloc_prelude, alloc_error_handler)] +#![feature(start, box_syntax, core_intrinsics, alloc_prelude, alloc_error_handler)] #![no_std] extern crate alloc; diff --git a/build_sysroot/alloc_system/lib.rs b/example/alloc_system.rs similarity index 62% rename from build_sysroot/alloc_system/lib.rs rename to example/alloc_system.rs index c832d5e5ebb..5f66ca67f2d 100644 --- a/build_sysroot/alloc_system/lib.rs +++ b/example/alloc_system.rs @@ -8,66 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. #![no_std] -#![allow(unused_attributes)] -#![unstable(feature = "alloc_system", - reason = "this library is unlikely to be stabilized in its current \ - form or name", - issue = "32838")] -#![feature(allocator_api)] -#![feature(core_intrinsics)] -#![feature(nll)] -#![feature(staged_api)] -#![feature(rustc_attrs)] -#![feature(alloc_layout_extra)] -#![cfg_attr( - all(target_arch = "wasm32", not(target_os = "emscripten")), - feature(integer_atomics, stdsimd) -)] +#![feature(allocator_api, rustc_private)] #![cfg_attr(any(unix, target_os = "redox"), feature(libc))] + // The minimum alignment guaranteed by the architecture. This value is used to // add fast paths for low alignment values. #[cfg(all(any(target_arch = "x86", target_arch = "arm", target_arch = "mips", target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "asmjs", - target_arch = "wasm32")))] -#[allow(dead_code)] + target_arch = "powerpc64")))] const MIN_ALIGN: usize = 8; #[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "mips64", target_arch = "s390x", target_arch = "sparc64")))] -#[allow(dead_code)] const MIN_ALIGN: usize = 16; -/// The default memory allocator provided by the operating system. -/// -/// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows, -/// plus related functions. -/// -/// This type can be used in a `static` item -/// with the `#[global_allocator]` attribute -/// to force the global allocator to be the system’s one. -/// (The default is jemalloc for executables, on some platforms.) -/// -/// ```rust -/// use std::alloc::System; -/// -/// #[global_allocator] -/// static A: System = System; -/// -/// fn main() { -/// let a = Box::new(4); // Allocates from the system allocator. -/// println!("{}", a); -/// } -/// ``` -/// -/// It can also be used directly to allocate memory -/// independently of the standard library’s global allocator. -#[stable(feature = "alloc_system_type", since = "1.28.0")] pub struct System; #[cfg(any(windows, unix, target_os = "redox"))] mod realloc_fallback { @@ -96,7 +54,6 @@ mod platform { use MIN_ALIGN; use System; use core::alloc::{GlobalAlloc, Layout}; - #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { @@ -221,7 +178,6 @@ mod platform { }; ptr as *mut u8 } - #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { @@ -254,89 +210,3 @@ mod platform { } } } -// This is an implementation of a global allocator on the wasm32 platform when -// emscripten is not in use. In that situation there's no actual runtime for us -// to lean on for allocation, so instead we provide our own! -// -// The wasm32 instruction set has two instructions for getting the current -// amount of memory and growing the amount of memory. These instructions are the -// foundation on which we're able to build an allocator, so we do so! Note that -// the instructions are also pretty "global" and this is the "global" allocator -// after all! -// -// The current allocator here is the `dlmalloc` crate which we've got included -// in the rust-lang/rust repository as a submodule. The crate is a port of -// dlmalloc.c from C to Rust and is basically just so we can have "pure Rust" -// for now which is currently technically required (can't link with C yet). -// -// The crate itself provides a global allocator which on wasm has no -// synchronization as there are no threads! -#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] -mod platform { - extern crate dlmalloc; - use core::alloc::{GlobalAlloc, Layout}; - use System; - static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT; - #[stable(feature = "alloc_system_type", since = "1.28.0")] - unsafe impl GlobalAlloc for System { - #[inline] - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - let _lock = lock::lock(); - DLMALLOC.malloc(layout.size(), layout.align()) - } - #[inline] - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - let _lock = lock::lock(); - DLMALLOC.calloc(layout.size(), layout.align()) - } - #[inline] - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - let _lock = lock::lock(); - DLMALLOC.free(ptr, layout.size(), layout.align()) - } - #[inline] - unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - let _lock = lock::lock(); - DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size) - } - } - #[cfg(target_feature = "atomics")] - mod lock { - use core::arch::wasm32; - use core::sync::atomic::{AtomicI32, Ordering::SeqCst}; - static LOCKED: AtomicI32 = AtomicI32::new(0); - pub struct DropLock; - pub fn lock() -> DropLock { - loop { - if LOCKED.swap(1, SeqCst) == 0 { - return DropLock - } - unsafe { - let r = wasm32::atomic::wait_i32( - &LOCKED as *const AtomicI32 as *mut i32, - 1, // expected value - -1, // timeout - ); - debug_assert!(r == 0 || r == 1); - } - } - } - impl Drop for DropLock { - fn drop(&mut self) { - let r = LOCKED.swap(0, SeqCst); - debug_assert_eq!(r, 1); - unsafe { - wasm32::atomic::wake( - &LOCKED as *const AtomicI32 as *mut i32, - 1, // only one thread - ); - } - } - } - } - #[cfg(not(target_feature = "atomics"))] - mod lock { - #[inline] - pub fn lock() {} // no atomics, no threads, that's easy! - } -} diff --git a/example/arbitrary_self_types_pointers_and_wrappers.rs b/example/arbitrary_self_types_pointers_and_wrappers.rs index 0b0039a1370..ddeb752f93e 100644 --- a/example/arbitrary_self_types_pointers_and_wrappers.rs +++ b/example/arbitrary_self_types_pointers_and_wrappers.rs @@ -1,22 +1,12 @@ // Adapted from rustc run-pass test suite -#![feature(no_core, arbitrary_self_types, box_syntax)] +#![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)] #![feature(rustc_attrs)] -#![feature(start, lang_items)] -#![no_core] - -extern crate mini_core; - -use mini_core::*; - -macro_rules! assert_eq { - ($l:expr, $r: expr) => { - if $l != $r { - panic(stringify!($l != $r)); - } - } -} +use std::{ + ops::{Deref, CoerceUnsized, DispatchFromDyn}, + marker::Unsize, +}; struct Ptr(Box); @@ -67,16 +57,13 @@ impl Trait for i32 { } } -#[start] -fn main(_: isize, _: *const *const u8) -> isize { - let pw = Ptr(box Wrapper(5)) as Ptr>; +fn main() { + let pw = Ptr(Box::new(Wrapper(5))) as Ptr>; assert_eq!(pw.ptr_wrapper(), 5); - let wp = Wrapper(Ptr(box 6)) as Wrapper>; + let wp = Wrapper(Ptr(Box::new(6))) as Wrapper>; assert_eq!(wp.wrapper_ptr(), 6); - let wpw = Wrapper(Ptr(box Wrapper(7))) as Wrapper>>; + let wpw = Wrapper(Ptr(Box::new(Wrapper(7)))) as Wrapper>>; assert_eq!(wpw.wrapper_ptr_wrapper(), 7); - - 0 } diff --git a/example/mini_core.rs b/example/mini_core.rs index 002ec7e2e3d..7c6d7fc106d 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -365,6 +365,22 @@ impl PartialEq for Option { } } +#[lang = "shl"] +pub trait Shl { + type Output; + + #[must_use] + fn shl(self, rhs: RHS) -> Self::Output; +} + +impl Shl for u128 { + type Output = u128; + + fn shl(self, rhs: u128) -> u128 { + self << rhs + } +} + #[lang = "neg"] pub trait Neg { type Output; diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 4a8375afac3..237f4d11d57 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -264,6 +264,9 @@ fn main() { assert_eq!(f2 as i8, -128); assert_eq!(f2 as u8, 0); + let amount = 0; + assert_eq!(1u128 << amount, 1); + static ANOTHER_STATIC: &u8 = &A_STATIC; assert_eq!(*ANOTHER_STATIC, 42); diff --git a/patches/0022-core-Disable-not-compiling-tests.patch b/patches/0022-core-Disable-not-compiling-tests.patch index 3eb10069ada..8cfffe580a1 100644 --- a/patches/0022-core-Disable-not-compiling-tests.patch +++ b/patches/0022-core-Disable-not-compiling-tests.patch @@ -119,21 +119,5 @@ index 6609bc3..241b497 100644 #[test] #[should_panic(expected = "index 0 greater than length of slice")] -diff --git a/library/core/tests/num/ops.rs b/library/core/tests/num/ops.rs -index 9979cc8..d5d1d83 100644 ---- a/library/core/tests/num/ops.rs -+++ b/library/core/tests/num/ops.rs -@@ -238,7 +238,7 @@ macro_rules! test_shift_assign { - } - }; - } --test_shift!(test_shl_defined, Shl::shl); --test_shift_assign!(test_shl_assign_defined, ShlAssign::shl_assign); --test_shift!(test_shr_defined, Shr::shr); --test_shift_assign!(test_shr_assign_defined, ShrAssign::shr_assign); -+//test_shift!(test_shl_defined, Shl::shl); -+//test_shift_assign!(test_shl_assign_defined, ShlAssign::shl_assign); -+//test_shift!(test_shr_defined, Shr::shr); -+//test_shift_assign!(test_shr_assign_defined, ShrAssign::shr_assign); -- 2.21.0 (Apple Git-122) diff --git a/patches/0027-Disable-128bit-atomic-operations.patch b/patches/0027-Disable-128bit-atomic-operations.patch new file mode 100644 index 00000000000..32e59309690 --- /dev/null +++ b/patches/0027-Disable-128bit-atomic-operations.patch @@ -0,0 +1,103 @@ +From 894e07dfec2624ba539129b1c1d63e1d7d812bda Mon Sep 17 00:00:00 2001 +From: bjorn3 +Date: Thu, 18 Feb 2021 18:45:28 +0100 +Subject: [PATCH] Disable 128bit atomic operations + +Cranelift doesn't support them yet +--- + library/core/src/sync/atomic.rs | 38 --------------------------------- + library/core/tests/atomic.rs | 4 ---- + library/std/src/panic.rs | 6 ------ + 3 files changed, 48 deletions(-) + +diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs +index 81c9e1d..65c9503 100644 +--- a/library/core/src/sync/atomic.rs ++++ b/library/core/src/sync/atomic.rs +@@ -2228,44 +2228,6 @@ atomic_int! { + "AtomicU64::new(0)", + u64 AtomicU64 ATOMIC_U64_INIT + } +-#[cfg(target_has_atomic_load_store = "128")] +-atomic_int! { +- cfg(target_has_atomic = "128"), +- cfg(target_has_atomic_equal_alignment = "128"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), +- unstable(feature = "integer_atomics", issue = "32976"), +- "i128", +- "#![feature(integer_atomics)]\n\n", +- atomic_min, atomic_max, +- 16, +- "AtomicI128::new(0)", +- i128 AtomicI128 ATOMIC_I128_INIT +-} +-#[cfg(target_has_atomic_load_store = "128")] +-atomic_int! { +- cfg(target_has_atomic = "128"), +- cfg(target_has_atomic_equal_alignment = "128"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), +- unstable(feature = "integer_atomics", issue = "32976"), +- "u128", +- "#![feature(integer_atomics)]\n\n", +- atomic_umin, atomic_umax, +- 16, +- "AtomicU128::new(0)", +- u128 AtomicU128 ATOMIC_U128_INIT +-} + + macro_rules! atomic_int_ptr_sized { + ( $($target_pointer_width:literal $align:literal)* ) => { $( +diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs +index 2d1e449..cb6da5d 100644 +--- a/library/core/tests/atomic.rs ++++ b/library/core/tests/atomic.rs +@@ -145,10 +145,6 @@ fn atomic_alignment() { + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "64")] + assert_eq!(align_of::(), size_of::()); +- #[cfg(target_has_atomic = "128")] +- assert_eq!(align_of::(), size_of::()); +- #[cfg(target_has_atomic = "128")] +- assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "ptr")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "ptr")] +diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs +index 89a822a..779fd88 100644 +--- a/library/std/src/panic.rs ++++ b/library/std/src/panic.rs +@@ -279,9 +279,6 @@ impl RefUnwindSafe for atomic::AtomicI32 {} + #[cfg(target_has_atomic_load_store = "64")] + #[stable(feature = "integer_atomics_stable", since = "1.34.0")] + impl RefUnwindSafe for atomic::AtomicI64 {} +-#[cfg(target_has_atomic_load_store = "128")] +-#[unstable(feature = "integer_atomics", issue = "32976")] +-impl RefUnwindSafe for atomic::AtomicI128 {} + + #[cfg(target_has_atomic_load_store = "ptr")] + #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] +@@ -298,9 +295,6 @@ impl RefUnwindSafe for atomic::AtomicU32 {} + #[cfg(target_has_atomic_load_store = "64")] + #[stable(feature = "integer_atomics_stable", since = "1.34.0")] + impl RefUnwindSafe for atomic::AtomicU64 {} +-#[cfg(target_has_atomic_load_store = "128")] +-#[unstable(feature = "integer_atomics", issue = "32976")] +-impl RefUnwindSafe for atomic::AtomicU128 {} + + #[cfg(target_has_atomic_load_store = "8")] + #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] +-- +2.26.2.7.g19db9cfb68 + diff --git a/prepare.sh b/prepare.sh index 08e7cb18029..ee995ffcfa9 100755 --- a/prepare.sh +++ b/prepare.sh @@ -1,4 +1,4 @@ -#!/bin/bash --verbose +#!/usr/bin/env bash set -e rustup component add rust-src rustc-dev llvm-tools-preview diff --git a/rust-toolchain b/rust-toolchain index a08f00d19c2..908ca52135b 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2021-01-30 +nightly-2021-03-05 diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000000..2bd8f7d1bc1 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,4 @@ +# Matches rustfmt.toml of rustc +version = "Two" +use_small_heuristics = "Max" +merge_derives = false diff --git a/scripts/cargo.sh b/scripts/cargo.sh index a3d6d303057..669d2d45b71 100755 --- a/scripts/cargo.sh +++ b/scripts/cargo.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash dir=$(dirname "$0") source "$dir/config.sh" diff --git a/scripts/config.sh b/scripts/config.sh index 834708aa9a6..c2ed2bf256d 100644 --- a/scripts/config.sh +++ b/scripts/config.sh @@ -3,7 +3,7 @@ set -e unamestr=$(uname) -if [[ "$unamestr" == 'Linux' ]]; then +if [[ "$unamestr" == 'Linux' || "$unamestr" == 'FreeBSD' ]]; then dylib_ext='so' elif [[ "$unamestr" == 'Darwin' ]]; then dylib_ext='dylib' @@ -26,7 +26,7 @@ export RUSTC=$dir"/bin/cg_clif" export RUSTDOCFLAGS=$linker' -Cpanic=abort -Zpanic-abort-tests '\ '-Zcodegen-backend='$dir'/lib/librustc_codegen_cranelift.'$dylib_ext' --sysroot '$dir -# FIXME remove once the atomic shim is gone +# FIXME fix `#[linkage = "extern_weak"]` without this if [[ "$unamestr" == 'Darwin' ]]; then export RUSTFLAGS="$RUSTFLAGS -Clink-arg=-undefined -Clink-arg=dynamic_lookup" fi diff --git a/scripts/rustup.sh b/scripts/rustup.sh index 430f5c469b4..694945a87c2 100755 --- a/scripts/rustup.sh +++ b/scripts/rustup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/scripts/test_bootstrap.sh b/scripts/test_bootstrap.sh index db69541b226..6473c6ad67d 100755 --- a/scripts/test_bootstrap.sh +++ b/scripts/test_bootstrap.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e cd "$(dirname "$0")/../" @@ -14,21 +14,18 @@ git checkout -- . git checkout "$(rustc -V | cut -d' ' -f3 | tr -d '(')" git apply - < config.toml <) { +pub(super) fn add_args_header_comment(fx: &mut FunctionCx<'_, '_, '_>) { fx.add_global_comment( "kind loc.idx param pass mode ty".to_string(), ); } pub(super) fn add_arg_comment<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, kind: &str, local: Option, local_field: Option, @@ -42,11 +42,7 @@ pub(super) fn add_arg_comment<'tcx>( [param_a, param_b] => Cow::Owned(format!("= {:?},{:?}", param_a, param_b)), params => Cow::Owned(format!( "= {}", - params - .iter() - .map(ToString::to_string) - .collect::>() - .join(",") + params.iter().map(ToString::to_string).collect::>().join(",") )), }; @@ -62,7 +58,7 @@ pub(super) fn add_arg_comment<'tcx>( )); } -pub(super) fn add_locals_header_comment(fx: &mut FunctionCx<'_, '_, impl Module>) { +pub(super) fn add_locals_header_comment(fx: &mut FunctionCx<'_, '_, '_>) { fx.add_global_comment(String::new()); fx.add_global_comment( "kind local ty size align (abi,pref)".to_string(), @@ -70,19 +66,13 @@ pub(super) fn add_locals_header_comment(fx: &mut FunctionCx<'_, '_, impl Module> } pub(super) fn add_local_place_comments<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, place: CPlace<'tcx>, local: Local, ) { let TyAndLayout { ty, layout } = place.layout(); - let rustc_target::abi::Layout { - size, - align, - abi: _, - variants: _, - fields: _, - largest_niche: _, - } = layout; + let rustc_target::abi::Layout { size, align, abi: _, variants: _, fields: _, largest_niche: _ } = + layout; let (kind, extra) = match *place.inner() { CPlaceInner::Var(place_local, var) => { @@ -91,10 +81,7 @@ pub(super) fn add_local_place_comments<'tcx>( } CPlaceInner::VarPair(place_local, var1, var2) => { assert_eq!(local, place_local); - ( - "ssa", - Cow::Owned(format!(",var=({}, {})", var1.index(), var2.index())), - ) + ("ssa", Cow::Owned(format!(",var=({}, {})", var1.index(), var2.index()))) } CPlaceInner::VarLane(_local, _var, _lane) => unreachable!(), CPlaceInner::Addr(ptr, meta) => { @@ -104,18 +91,15 @@ pub(super) fn add_local_place_comments<'tcx>( Cow::Borrowed("") }; match ptr.base_and_offset() { - (crate::pointer::PointerBase::Addr(addr), offset) => ( - "reuse", - format!("storage={}{}{}", addr, offset, meta).into(), - ), - (crate::pointer::PointerBase::Stack(stack_slot), offset) => ( - "stack", - format!("storage={}{}{}", stack_slot, offset, meta).into(), - ), - (crate::pointer::PointerBase::Dangling(align), offset) => ( - "zst", - format!("align={},offset={}", align.bytes(), offset).into(), - ), + (crate::pointer::PointerBase::Addr(addr), offset) => { + ("reuse", format!("storage={}{}{}", addr, offset, meta).into()) + } + (crate::pointer::PointerBase::Stack(stack_slot), offset) => { + ("stack", format!("storage={}{}{}", stack_slot, offset, meta).into()) + } + (crate::pointer::PointerBase::Dangling(align), offset) => { + ("zst", format!("align={},offset={}", align.bytes(), offset).into()) + } } } }; @@ -128,11 +112,7 @@ pub(super) fn add_local_place_comments<'tcx>( size.bytes(), align.abi.bytes(), align.pref.bytes(), - if extra.is_empty() { - "" - } else { - " " - }, + if extra.is_empty() { "" } else { " " }, extra, )); } diff --git a/src/abi/mod.rs b/src/abi/mod.rs index b2647e6c8d3..c79889f8ca1 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -38,25 +38,15 @@ fn clif_sig_from_fn_abi<'tcx>( | Conv::X86VectorCall | Conv::AmdGpuKernel | Conv::AvrInterrupt - | Conv::AvrNonBlockingInterrupt => { - todo!("{:?}", fn_abi.conv) - } + | Conv::AvrNonBlockingInterrupt => todo!("{:?}", fn_abi.conv), }; - let inputs = fn_abi - .args - .iter() - .map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()) - .flatten(); + let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten(); let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx); // Sometimes the first param is an pointer to the place where the return value needs to be stored. let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect(); - Signature { - params, - returns, - call_conv, - } + Signature { params, returns, call_conv } } pub(crate) fn get_function_sig<'tcx>( @@ -65,34 +55,25 @@ pub(crate) fn get_function_sig<'tcx>( inst: Instance<'tcx>, ) -> Signature { assert!(!inst.substs.needs_infer()); - clif_sig_from_fn_abi( - tcx, - triple, - &FnAbi::of_instance(&RevealAllLayoutCx(tcx), inst, &[]), - ) + clif_sig_from_fn_abi(tcx, triple, &FnAbi::of_instance(&RevealAllLayoutCx(tcx), inst, &[])) } /// Instance must be monomorphized pub(crate) fn import_function<'tcx>( tcx: TyCtxt<'tcx>, - module: &mut impl Module, + module: &mut dyn Module, inst: Instance<'tcx>, ) -> FuncId { let name = tcx.symbol_name(inst).name.to_string(); let sig = get_function_sig(tcx, module.isa().triple(), inst); - module - .declare_function(&name, Linkage::Import, &sig) - .unwrap() + module.declare_function(&name, Linkage::Import, &sig).unwrap() } -impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { +impl<'tcx> FunctionCx<'_, '_, 'tcx> { /// Instance must be monomorphized pub(crate) fn get_function_ref(&mut self, inst: Instance<'tcx>) -> FuncRef { - let func_id = import_function(self.tcx, &mut self.cx.module, inst); - let func_ref = self - .cx - .module - .declare_func_in_func(func_id, &mut self.bcx.func); + let func_id = import_function(self.tcx, self.cx.module, inst); + let func_ref = self.cx.module.declare_func_in_func(func_id, &mut self.bcx.func); #[cfg(debug_assertions)] self.add_comment(func_ref, format!("{:?}", inst)); @@ -107,20 +88,9 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { returns: Vec, args: &[Value], ) -> &[Value] { - let sig = Signature { - params, - returns, - call_conv: CallConv::triple_default(self.triple()), - }; - let func_id = self - .cx - .module - .declare_function(&name, Linkage::Import, &sig) - .unwrap(); - let func_ref = self - .cx - .module - .declare_func_in_func(func_id, &mut self.bcx.func); + let sig = Signature { params, returns, call_conv: CallConv::triple_default(self.triple()) }; + let func_id = self.cx.module.declare_function(&name, Linkage::Import, &sig).unwrap(); + let func_ref = self.cx.module.declare_func_in_func(func_id, &mut self.bcx.func); let call_inst = self.bcx.ins().call(func_ref, args); #[cfg(debug_assertions)] { @@ -140,17 +110,12 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { let (input_tys, args): (Vec<_>, Vec<_>) = args .iter() .map(|arg| { - ( - AbiParam::new(self.clif_type(arg.layout().ty).unwrap()), - arg.load_scalar(self), - ) + (AbiParam::new(self.clif_type(arg.layout().ty).unwrap()), arg.load_scalar(self)) }) .unzip(); let return_layout = self.layout_of(return_ty); let return_tys = if let ty::Tuple(tup) = return_ty.kind() { - tup.types() - .map(|ty| AbiParam::new(self.clif_type(ty).unwrap())) - .collect() + tup.types().map(|ty| AbiParam::new(self.clif_type(ty).unwrap())).collect() } else { vec![AbiParam::new(self.clif_type(return_ty).unwrap())] }; @@ -169,7 +134,7 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { /// Make a [`CPlace`] capable of holding value of the specified type. fn make_local_place<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, local: Local, layout: TyAndLayout<'tcx>, is_ssa: bool, @@ -190,10 +155,7 @@ fn make_local_place<'tcx>( place } -pub(crate) fn codegen_fn_prelude<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - start_block: Block, -) { +pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_block: Block) { fx.bcx.append_block_params_for_function_params(start_block); fx.bcx.switch_to_block(start_block); @@ -204,13 +166,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>( #[cfg(debug_assertions)] self::comments::add_args_header_comment(fx); - let mut block_params_iter = fx - .bcx - .func - .dfg - .block_params(start_block) - .to_vec() - .into_iter(); + let mut block_params_iter = fx.bcx.func.dfg.block_params(start_block).to_vec().into_iter(); let ret_place = self::returning::codegen_return_param(fx, &ssa_analyzed, &mut block_params_iter); assert_eq!(fx.local_map.push(ret_place), RETURN_PLACE); @@ -286,10 +242,10 @@ pub(crate) fn codegen_fn_prelude<'tcx>( if let Some((addr, meta)) = val.try_to_ptr() { let local_decl = &fx.mir.local_decls[local]; // v this ! is important - let internally_mutable = !val.layout().ty.is_freeze( - fx.tcx.at(local_decl.source_info.span), - ParamEnv::reveal_all(), - ); + let internally_mutable = !val + .layout() + .ty + .is_freeze(fx.tcx.at(local_decl.source_info.span), ParamEnv::reveal_all()); if local_decl.mutability == mir::Mutability::Not && !internally_mutable { // We wont mutate this argument, so it is fine to borrow the backing storage // of this argument, to prevent a copy. @@ -321,9 +277,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>( 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, mir::Field::new(i)).write_cvalue(fx, param); } } } @@ -340,13 +294,11 @@ pub(crate) fn codegen_fn_prelude<'tcx>( assert_eq!(fx.local_map.push(place), local); } - fx.bcx - .ins() - .jump(*fx.block_map.get(START_BLOCK).unwrap(), &[]); + fx.bcx.ins().jump(*fx.block_map.get(START_BLOCK).unwrap(), &[]); } pub(crate) fn codegen_terminator_call<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, span: Span, current_block: Block, func: &Operand<'tcx>, @@ -354,9 +306,8 @@ pub(crate) fn codegen_terminator_call<'tcx>( destination: Option<(Place<'tcx>, BasicBlock)>, ) { let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx)); - let fn_sig = fx - .tcx - .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx)); + let fn_sig = + fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx)); let destination = destination.map(|(place, bb)| (codegen_place(fx, place), bb)); @@ -404,20 +355,11 @@ pub(crate) fn codegen_terminator_call<'tcx>( let fn_abi = if let Some(instance) = instance { FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), instance, &extra_args) } else { - FnAbi::of_fn_ptr( - &RevealAllLayoutCx(fx.tcx), - fn_ty.fn_sig(fx.tcx), - &extra_args, - ) + FnAbi::of_fn_ptr(&RevealAllLayoutCx(fx.tcx), fn_ty.fn_sig(fx.tcx), &extra_args) }; let is_cold = instance - .map(|inst| { - fx.tcx - .codegen_fn_attrs(inst.def_id()) - .flags - .contains(CodegenFnAttrFlags::COLD) - }) + .map(|inst| fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD)) .unwrap_or(false); if is_cold { fx.cold_blocks.insert(current_block); @@ -441,9 +383,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( } args } else { - args.iter() - .map(|arg| codegen_operand(fx, arg)) - .collect::>() + args.iter().map(|arg| codegen_operand(fx, arg)).collect::>() }; // | indirect call target @@ -451,10 +391,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( // v v let (func_ref, first_arg) = match instance { // Trait object call - Some(Instance { - def: InstanceDef::Virtual(_, idx), - .. - }) => { + Some(Instance { def: InstanceDef::Virtual(_, idx), .. }) => { #[cfg(debug_assertions)] { let nop_inst = fx.bcx.ins().nop(); @@ -511,10 +448,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( ) .collect::>(); - if instance - .map(|inst| inst.def.requires_caller_location(fx.tcx)) - .unwrap_or(false) - { + if instance.map(|inst| inst.def.requires_caller_location(fx.tcx)).unwrap_or(false) { // Pass the caller location for `#[track_caller]`. let caller_location = fx.get_caller_location(span); call_args.extend( @@ -543,10 +477,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( // FIXME find a cleaner way to support varargs if fn_sig.c_variadic { if fn_sig.abi != Abi::C { - fx.tcx.sess.span_fatal( - span, - &format!("Variadic call for non-C abi {:?}", fn_sig.abi), - ); + fx.tcx.sess.span_fatal(span, &format!("Variadic call for non-C abi {:?}", fn_sig.abi)); } let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap(); let abi_params = call_args @@ -555,9 +486,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( let ty = fx.bcx.func.dfg.value_type(arg); if !ty.is_int() { // FIXME set %al to upperbound on float args once floats are supported - fx.tcx - .sess - .span_fatal(span, &format!("Non int ty {:?} for variadic call", ty)); + fx.tcx.sess.span_fatal(span, &format!("Non int ty {:?} for variadic call", ty)); } AbiParam::new(ty) }) @@ -574,7 +503,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( } pub(crate) fn codegen_drop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, span: Span, drop_place: CPlace<'tcx>, ) { @@ -611,10 +540,7 @@ pub(crate) fn codegen_drop<'tcx>( fx, fx.layout_of(fx.tcx.mk_ref( &ty::RegionKind::ReErased, - TypeAndMut { - ty, - mutbl: crate::rustc_hir::Mutability::Mut, - }, + TypeAndMut { ty, mutbl: crate::rustc_hir::Mutability::Mut }, )), ); let arg_value = adjust_arg_for_abi(fx, arg_value, &fn_abi.args[0]); diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs index 1202c23dbe7..d58f952f53c 100644 --- a/src/abi/pass_mode.rs +++ b/src/abi/pass_mode.rs @@ -71,12 +71,7 @@ fn cast_target_to_abi_params(cast: CastTarget) -> SmallVec<[AbiParam; 2]> { .prefix .iter() .flatten() - .map(|&kind| { - reg_to_abi_param(Reg { - kind, - size: cast.prefix_chunk_size, - }) - }) + .map(|&kind| reg_to_abi_param(Reg { kind, size: cast.prefix_chunk_size })) .chain((0..rest_count).map(|_| reg_to_abi_param(cast.rest.unit))) .collect::>(); @@ -98,12 +93,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { match self.mode { PassMode::Ignore => smallvec![], PassMode::Direct(attrs) => match &self.layout.abi { - Abi::Scalar(scalar) => { - smallvec![apply_arg_attrs_to_abi_param( - AbiParam::new(scalar_to_clif_type(tcx, scalar.clone())), - attrs - )] - } + Abi::Scalar(scalar) => smallvec![apply_arg_attrs_to_abi_param( + AbiParam::new(scalar_to_clif_type(tcx, scalar.clone())), + attrs + )], Abi::Vector { .. } => { let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout).unwrap(); smallvec![AbiParam::new(vector_ty)] @@ -122,11 +115,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { _ => unreachable!("{:?}", self.layout.abi), }, PassMode::Cast(cast) => cast_target_to_abi_params(cast), - PassMode::Indirect { - attrs, - extra_attrs: None, - on_stack, - } => { + PassMode::Indirect { attrs, extra_attrs: None, on_stack } => { if on_stack { let size = u32::try_from(self.layout.size.bytes()).unwrap(); smallvec![apply_arg_attrs_to_abi_param( @@ -134,17 +123,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { attrs )] } else { - smallvec![apply_arg_attrs_to_abi_param( - AbiParam::new(pointer_ty(tcx)), - attrs - )] + smallvec![apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs)] } } - PassMode::Indirect { - attrs, - extra_attrs: Some(extra_attrs), - on_stack, - } => { + PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack } => { assert!(!on_stack); smallvec![ apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs), @@ -158,10 +140,9 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { match self.mode { PassMode::Ignore => (None, vec![]), PassMode::Direct(_) => match &self.layout.abi { - Abi::Scalar(scalar) => ( - None, - vec![AbiParam::new(scalar_to_clif_type(tcx, scalar.clone()))], - ), + Abi::Scalar(scalar) => { + (None, vec![AbiParam::new(scalar_to_clif_type(tcx, scalar.clone()))]) + } Abi::Vector { .. } => { let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout).unwrap(); (None, vec![AbiParam::new(vector_ty)]) @@ -177,31 +158,19 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { _ => unreachable!("{:?}", self.layout.abi), }, PassMode::Cast(cast) => (None, cast_target_to_abi_params(cast).into_iter().collect()), - PassMode::Indirect { - attrs: _, - extra_attrs: None, - on_stack, - } => { + PassMode::Indirect { attrs: _, extra_attrs: None, on_stack } => { assert!(!on_stack); - ( - Some(AbiParam::special( - pointer_ty(tcx), - ArgumentPurpose::StructReturn, - )), - vec![], - ) + (Some(AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructReturn)), vec![]) + } + PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + unreachable!("unsized return value") } - PassMode::Indirect { - attrs: _, - extra_attrs: Some(_), - on_stack: _, - } => unreachable!("unsized return value"), } } } pub(super) fn to_casted_value<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, arg: CValue<'tcx>, cast: CastTarget, ) -> SmallVec<[Value; 2]> { @@ -211,9 +180,7 @@ pub(super) fn to_casted_value<'tcx>( cast_target_to_abi_params(cast) .into_iter() .map(|param| { - let val = ptr - .offset_i64(fx, offset) - .load(fx, param.value_type, MemFlags::new()); + let val = ptr.offset_i64(fx, offset).load(fx, param.value_type, MemFlags::new()); offset += i64::from(param.value_type.bytes()); val }) @@ -221,16 +188,13 @@ pub(super) fn to_casted_value<'tcx>( } pub(super) fn from_casted_value<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, block_params: &[Value], layout: TyAndLayout<'tcx>, cast: CastTarget, ) -> CValue<'tcx> { let abi_params = cast_target_to_abi_params(cast); - let abi_param_size: u32 = abi_params - .iter() - .map(|param| param.value_type.bytes()) - .sum(); + let abi_param_size: u32 = abi_params.iter().map(|param| param.value_type.bytes()).sum(); let layout_size = u32::try_from(layout.size.bytes()).unwrap(); let stack_slot = fx.bcx.create_stack_slot(StackSlotData { kind: StackSlotKind::ExplicitSlot, @@ -260,7 +224,7 @@ pub(super) fn from_casted_value<'tcx>( /// Get a set of values to be passed as function arguments. pub(super) fn adjust_arg_for_abi<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, arg: CValue<'tcx>, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, ) -> SmallVec<[Value; 2]> { @@ -283,7 +247,7 @@ pub(super) fn adjust_arg_for_abi<'tcx>( /// Create a [`CValue`] containing the value of a function parameter adding clif function parameters /// as necessary. pub(super) fn cvalue_for_param<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, #[cfg_attr(not(debug_assertions), allow(unused_variables))] local: Option, #[cfg_attr(not(debug_assertions), allow(unused_variables))] local_field: Option, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, @@ -294,10 +258,7 @@ pub(super) fn cvalue_for_param<'tcx>( .into_iter() .map(|abi_param| { let block_param = block_params_iter.next().unwrap(); - assert_eq!( - fx.bcx.func.dfg.value_type(block_param), - abi_param.value_type - ); + assert_eq!(fx.bcx.func.dfg.value_type(block_param), abi_param.value_type); block_param }) .collect::>(); @@ -321,29 +282,14 @@ pub(super) fn cvalue_for_param<'tcx>( } PassMode::Pair(_, _) => { assert_eq!(block_params.len(), 2, "{:?}", block_params); - Some(CValue::by_val_pair( - block_params[0], - block_params[1], - arg_abi.layout, - )) + Some(CValue::by_val_pair(block_params[0], block_params[1], arg_abi.layout)) } PassMode::Cast(cast) => Some(from_casted_value(fx, &block_params, arg_abi.layout, cast)), - PassMode::Indirect { - attrs: _, - extra_attrs: None, - on_stack: _, - } => { + PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { assert_eq!(block_params.len(), 1, "{:?}", block_params); - Some(CValue::by_ref( - Pointer::new(block_params[0]), - arg_abi.layout, - )) + Some(CValue::by_ref(Pointer::new(block_params[0]), arg_abi.layout)) } - PassMode::Indirect { - attrs: _, - extra_attrs: Some(_), - on_stack: _, - } => { + PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { assert_eq!(block_params.len(), 2, "{:?}", block_params); Some(CValue::by_ref_unsized( Pointer::new(block_params[0]), diff --git a/src/abi/returning.rs b/src/abi/returning.rs index a382963bf1e..9fa066df69b 100644 --- a/src/abi/returning.rs +++ b/src/abi/returning.rs @@ -8,14 +8,13 @@ use smallvec::{smallvec, SmallVec}; /// Can the given type be returned into an ssa var or does it need to be returned on the stack. pub(crate) fn can_return_to_ssa_var<'tcx>( - fx: &FunctionCx<'_, 'tcx, impl Module>, + fx: &FunctionCx<'_, '_, 'tcx>, func: &mir::Operand<'tcx>, args: &[mir::Operand<'tcx>], ) -> bool { let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx)); - let fn_sig = fx - .tcx - .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx)); + let fn_sig = + fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx)); // Handle special calls like instrinsics and empty drop glue. let instance = if let ty::FnDef(def_id, substs) = *fn_ty.kind() { @@ -42,11 +41,7 @@ pub(crate) fn can_return_to_ssa_var<'tcx>( let fn_abi = if let Some(instance) = instance { FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), instance, &extra_args) } else { - FnAbi::of_fn_ptr( - &RevealAllLayoutCx(fx.tcx), - fn_ty.fn_sig(fx.tcx), - &extra_args, - ) + FnAbi::of_fn_ptr(&RevealAllLayoutCx(fx.tcx), fn_ty.fn_sig(fx.tcx), &extra_args) }; match fn_abi.ret.mode { PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) => true, @@ -58,15 +53,12 @@ pub(crate) fn can_return_to_ssa_var<'tcx>( /// Return a place where the return value of the current function can be written to. If necessary /// this adds an extra parameter pointing to where the return value needs to be stored. pub(super) fn codegen_return_param<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, ssa_analyzed: &rustc_index::vec::IndexVec, block_params_iter: &mut impl Iterator, ) -> CPlace<'tcx> { let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode { - PassMode::Ignore => ( - CPlace::no_place(fx.fn_abi.as_ref().unwrap().ret.layout), - smallvec![], - ), + PassMode::Ignore => (CPlace::no_place(fx.fn_abi.as_ref().unwrap().ret.layout), smallvec![]), PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => { let is_ssa = ssa_analyzed[RETURN_PLACE] == crate::analyze::SsaKind::Ssa; ( @@ -79,26 +71,17 @@ pub(super) fn codegen_return_param<'tcx>( smallvec![], ) } - PassMode::Indirect { - attrs: _, - extra_attrs: None, - on_stack: _, - } => { + PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { let ret_param = block_params_iter.next().unwrap(); assert_eq!(fx.bcx.func.dfg.value_type(ret_param), pointer_ty(fx.tcx)); ( - CPlace::for_ptr( - Pointer::new(ret_param), - fx.fn_abi.as_ref().unwrap().ret.layout, - ), + CPlace::for_ptr(Pointer::new(ret_param), fx.fn_abi.as_ref().unwrap().ret.layout), smallvec![ret_param], ) } - PassMode::Indirect { - attrs: _, - extra_attrs: Some(_), - on_stack: _, - } => unreachable!("unsized return value"), + PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + unreachable!("unsized return value") + } }; #[cfg(not(debug_assertions))] @@ -120,27 +103,21 @@ pub(super) fn codegen_return_param<'tcx>( /// Invokes the closure with if necessary a value representing the return pointer. When the closure /// returns the call return value(s) if any are written to the correct place. -pub(super) fn codegen_with_call_return_arg<'tcx, M: Module, T>( - fx: &mut FunctionCx<'_, 'tcx, M>, +pub(super) fn codegen_with_call_return_arg<'tcx, T>( + fx: &mut FunctionCx<'_, '_, 'tcx>, ret_arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, ret_place: Option>, - f: impl FnOnce(&mut FunctionCx<'_, 'tcx, M>, Option) -> (Inst, T), + f: impl FnOnce(&mut FunctionCx<'_, '_, 'tcx>, Option) -> (Inst, T), ) -> (Inst, T) { let return_ptr = match ret_arg_abi.mode { PassMode::Ignore => None, - PassMode::Indirect { - attrs: _, - extra_attrs: None, - on_stack: _, - } => match ret_place { + PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => match ret_place { Some(ret_place) => Some(ret_place.to_ptr().get_addr(fx)), None => Some(fx.bcx.ins().iconst(fx.pointer_type, 43)), // FIXME allocate temp stack slot }, - PassMode::Indirect { - attrs: _, - extra_attrs: Some(_), - on_stack: _, - } => unreachable!("unsized return value"), + PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + unreachable!("unsized return value") + } PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => None, }; @@ -177,37 +154,24 @@ pub(super) fn codegen_with_call_return_arg<'tcx, M: Module, T>( ret_place.write_cvalue(fx, result); } } - PassMode::Indirect { - attrs: _, - extra_attrs: None, - on_stack: _, - } => {} - PassMode::Indirect { - attrs: _, - extra_attrs: Some(_), - on_stack: _, - } => unreachable!("unsized return value"), + PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {} + PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + unreachable!("unsized return value") + } } (call_inst, meta) } /// Codegen a return instruction with the right return value(s) if any. -pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, impl Module>) { +pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) { match fx.fn_abi.as_ref().unwrap().ret.mode { - PassMode::Ignore - | PassMode::Indirect { - attrs: _, - extra_attrs: None, - on_stack: _, - } => { + PassMode::Ignore | PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { fx.bcx.ins().return_(&[]); } - PassMode::Indirect { - attrs: _, - extra_attrs: Some(_), - on_stack: _, - } => unreachable!("unsized return value"), + PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + unreachable!("unsized return value") + } PassMode::Direct(_) => { let place = fx.get_local_place(RETURN_PLACE); let ret_val = place.to_cvalue(fx).load_scalar(fx); diff --git a/src/allocator.rs b/src/allocator.rs index 6c5916550ff..efb64233ef2 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -66,13 +66,9 @@ fn codegen_inner( let callee_name = kind.fn_name(method.name); //eprintln!("Codegen allocator shim {} -> {} ({:?} -> {:?})", caller_name, callee_name, sig.params, sig.returns); - let func_id = module - .declare_function(&caller_name, Linkage::Export, &sig) - .unwrap(); + let func_id = module.declare_function(&caller_name, Linkage::Export, &sig).unwrap(); - let callee_func_id = module - .declare_function(&callee_name, Linkage::Import, &sig) - .unwrap(); + let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap(); let mut ctx = Context::new(); ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig.clone()); @@ -96,11 +92,7 @@ fn codegen_inner( bcx.finalize(); } module - .define_function( - func_id, - &mut ctx, - &mut cranelift_codegen::binemit::NullTrapSink {}, - ) + .define_function(func_id, &mut ctx, &mut cranelift_codegen::binemit::NullTrapSink {}) .unwrap(); unwind_context.add_function(func_id, &ctx, module.isa()); } @@ -114,13 +106,10 @@ fn codegen_inner( let callee_name = kind.fn_name(sym::oom); //eprintln!("Codegen allocator shim {} -> {} ({:?} -> {:?})", caller_name, callee_name, sig.params, sig.returns); - let func_id = module - .declare_function("__rust_alloc_error_handler", Linkage::Export, &sig) - .unwrap(); + let func_id = + module.declare_function("__rust_alloc_error_handler", Linkage::Export, &sig).unwrap(); - let callee_func_id = module - .declare_function(&callee_name, Linkage::Import, &sig) - .unwrap(); + let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap(); let mut ctx = Context::new(); ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig); @@ -143,11 +132,7 @@ fn codegen_inner( bcx.finalize(); } module - .define_function( - func_id, - &mut ctx, - &mut cranelift_codegen::binemit::NullTrapSink {}, - ) + .define_function(func_id, &mut ctx, &mut cranelift_codegen::binemit::NullTrapSink {}) .unwrap(); unwind_context.add_function(func_id, &ctx, module.isa()); } diff --git a/src/analyze.rs b/src/analyze.rs index 62fbcfe3f7a..efead25552f 100644 --- a/src/analyze.rs +++ b/src/analyze.rs @@ -11,7 +11,7 @@ pub(crate) enum SsaKind { Ssa, } -pub(crate) fn analyze(fx: &FunctionCx<'_, '_, impl Module>) -> IndexVec { +pub(crate) fn analyze(fx: &FunctionCx<'_, '_, '_>) -> IndexVec { let mut flag_map = fx .mir .local_decls @@ -40,12 +40,7 @@ pub(crate) fn analyze(fx: &FunctionCx<'_, '_, impl Module>) -> IndexVec { + TerminatorKind::Call { destination, func, args, .. } => { if let Some((dest_place, _dest_bb)) = destination { if !crate::abi::can_return_to_ssa_var(fx, func, args) { not_ssa(&mut flag_map, dest_place.local) diff --git a/src/archive.rs b/src/archive.rs index 96579054389..7583fc42407 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -12,10 +12,7 @@ use object::{Object, ObjectSymbol, SymbolKind}; #[derive(Debug)] enum ArchiveEntry { - FromArchive { - archive_index: usize, - entry_index: usize, - }, + FromArchive { archive_index: usize, entry_index: usize }, File(PathBuf), } @@ -30,7 +27,6 @@ pub(crate) struct ArArchiveBuilder<'a> { // Don't use `HashMap` here, as the order is important. `rust.metadata.bin` must always be at // the end of an archive for linkers to not get confused. entries: Vec<(String, ArchiveEntry)>, - update_symbols: bool, } impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { @@ -46,10 +42,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { let entry = entry.unwrap(); entries.push(( String::from_utf8(entry.header().identifier().to_vec()).unwrap(), - ArchiveEntry::FromArchive { - archive_index: 0, - entry_index: i, - }, + ArchiveEntry::FromArchive { archive_index: 0, entry_index: i }, )); i += 1; } @@ -69,7 +62,6 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { src_archives, entries, - update_symbols: false, } } @@ -95,14 +87,9 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { fn add_native_library(&mut self, name: rustc_span::symbol::Symbol) { let location = find_library(name, &self.lib_search_paths, self.sess); - self.add_archive(location.clone(), |_| false) - .unwrap_or_else(|e| { - panic!( - "failed to add native library {}: {}", - location.to_string_lossy(), - e - ); - }); + self.add_archive(location.clone(), |_| false).unwrap_or_else(|e| { + panic!("failed to add native library {}: {}", location.to_string_lossy(), e); + }); } fn add_rlib( @@ -136,9 +123,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { }) } - fn update_symbols(&mut self) { - self.update_symbols = true; - } + fn update_symbols(&mut self) {} fn build(mut self) { enum BuilderKind { @@ -156,10 +141,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { // FIXME only read the symbol table of the object files to avoid having to keep all // object files in memory at once, or read them twice. let data = match entry { - ArchiveEntry::FromArchive { - archive_index, - entry_index, - } => { + ArchiveEntry::FromArchive { archive_index, entry_index } => { // FIXME read symbols from symtab use std::io::Read; let (ref _src_archive_path, ref mut src_archive) = @@ -225,10 +207,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { err )); }), - entries - .iter() - .map(|(name, _)| name.as_bytes().to_vec()) - .collect(), + entries.iter().map(|(name, _)| name.as_bytes().to_vec()).collect(), ar::GnuSymbolTableFormat::Size32, symbol_table, ) @@ -271,8 +250,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { .expect("Couldn't run ranlib"); if !status.success() { - self.sess - .fatal(&format!("Ranlib exited with code {:?}", status.code())); + self.sess.fatal(&format!("Ranlib exited with code {:?}", status.code())); } } } @@ -292,13 +270,8 @@ impl<'a> ArArchiveBuilder<'a> { let file_name = String::from_utf8(entry.header().identifier().to_vec()) .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?; if !skip(&file_name) { - self.entries.push(( - file_name, - ArchiveEntry::FromArchive { - archive_index, - entry_index: i, - }, - )); + self.entries + .push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i })); } i += 1; } diff --git a/src/atomic_shim.rs b/src/atomic_shim.rs deleted file mode 100644 index 674e6d90751..00000000000 --- a/src/atomic_shim.rs +++ /dev/null @@ -1,185 +0,0 @@ -//! Atomic intrinsics are implemented using a global lock for now, as Cranelift doesn't support -//! atomic operations yet. - -// FIXME implement atomic instructions in Cranelift. - -use crate::prelude::*; - -#[cfg(all(feature = "jit", unix))] -#[no_mangle] -static mut __cg_clif_global_atomic_mutex: libc::pthread_mutex_t = libc::PTHREAD_MUTEX_INITIALIZER; - -pub(crate) fn init_global_lock( - module: &mut impl Module, - bcx: &mut FunctionBuilder<'_>, - use_jit: bool, -) { - if use_jit { - // When using JIT, dylibs won't find the __cg_clif_global_atomic_mutex data object defined here, - // so instead we define it in the cg_clif dylib. - - return; - } - - let mut data_ctx = DataContext::new(); - data_ctx.define_zeroinit(1024); // 1024 bytes should be big enough on all platforms. - data_ctx.set_align(16); - let atomic_mutex = module - .declare_data( - "__cg_clif_global_atomic_mutex", - Linkage::Export, - true, - false, - ) - .unwrap(); - module.define_data(atomic_mutex, &data_ctx).unwrap(); - - let pthread_mutex_init = module - .declare_function( - "pthread_mutex_init", - Linkage::Import, - &cranelift_codegen::ir::Signature { - call_conv: module.target_config().default_call_conv, - params: vec![ - AbiParam::new( - module.target_config().pointer_type(), /* *mut pthread_mutex_t */ - ), - AbiParam::new( - module.target_config().pointer_type(), /* *const pthread_mutex_attr_t */ - ), - ], - returns: vec![AbiParam::new(types::I32 /* c_int */)], - }, - ) - .unwrap(); - - let pthread_mutex_init = module.declare_func_in_func(pthread_mutex_init, bcx.func); - - let atomic_mutex = module.declare_data_in_func(atomic_mutex, bcx.func); - let atomic_mutex = bcx - .ins() - .global_value(module.target_config().pointer_type(), atomic_mutex); - - let nullptr = bcx.ins().iconst(module.target_config().pointer_type(), 0); - - bcx.ins().call(pthread_mutex_init, &[atomic_mutex, nullptr]); -} - -pub(crate) fn init_global_lock_constructor( - module: &mut impl Module, - constructor_name: &str, -) -> FuncId { - let sig = Signature::new(CallConv::SystemV); - let init_func_id = module - .declare_function(constructor_name, Linkage::Export, &sig) - .unwrap(); - - let mut ctx = Context::new(); - ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig); - { - let mut func_ctx = FunctionBuilderContext::new(); - let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); - - let block = bcx.create_block(); - bcx.switch_to_block(block); - - crate::atomic_shim::init_global_lock(module, &mut bcx, false); - - bcx.ins().return_(&[]); - bcx.seal_all_blocks(); - bcx.finalize(); - } - module - .define_function( - init_func_id, - &mut ctx, - &mut cranelift_codegen::binemit::NullTrapSink {}, - ) - .unwrap(); - - init_func_id -} - -pub(crate) fn lock_global_lock(fx: &mut FunctionCx<'_, '_, impl Module>) { - let atomic_mutex = fx - .cx - .module - .declare_data( - "__cg_clif_global_atomic_mutex", - Linkage::Import, - true, - false, - ) - .unwrap(); - - let pthread_mutex_lock = fx - .cx - .module - .declare_function( - "pthread_mutex_lock", - Linkage::Import, - &cranelift_codegen::ir::Signature { - call_conv: fx.cx.module.target_config().default_call_conv, - params: vec![AbiParam::new( - fx.cx.module.target_config().pointer_type(), /* *mut pthread_mutex_t */ - )], - returns: vec![AbiParam::new(types::I32 /* c_int */)], - }, - ) - .unwrap(); - - let pthread_mutex_lock = fx - .cx - .module - .declare_func_in_func(pthread_mutex_lock, fx.bcx.func); - - let atomic_mutex = fx.cx.module.declare_data_in_func(atomic_mutex, fx.bcx.func); - let atomic_mutex = fx - .bcx - .ins() - .global_value(fx.cx.module.target_config().pointer_type(), atomic_mutex); - - fx.bcx.ins().call(pthread_mutex_lock, &[atomic_mutex]); -} - -pub(crate) fn unlock_global_lock(fx: &mut FunctionCx<'_, '_, impl Module>) { - let atomic_mutex = fx - .cx - .module - .declare_data( - "__cg_clif_global_atomic_mutex", - Linkage::Import, - true, - false, - ) - .unwrap(); - - let pthread_mutex_unlock = fx - .cx - .module - .declare_function( - "pthread_mutex_unlock", - Linkage::Import, - &cranelift_codegen::ir::Signature { - call_conv: fx.cx.module.target_config().default_call_conv, - params: vec![AbiParam::new( - fx.cx.module.target_config().pointer_type(), /* *mut pthread_mutex_t */ - )], - returns: vec![AbiParam::new(types::I32 /* c_int */)], - }, - ) - .unwrap(); - - let pthread_mutex_unlock = fx - .cx - .module - .declare_func_in_func(pthread_mutex_unlock, fx.bcx.func); - - let atomic_mutex = fx.cx.module.declare_data_in_func(atomic_mutex, fx.bcx.func); - let atomic_mutex = fx - .bcx - .ins() - .global_value(fx.cx.module.target_config().pointer_type(), atomic_mutex); - - fx.bcx.ins().call(pthread_mutex_unlock, &[atomic_mutex]); -} diff --git a/src/backend.rs b/src/backend.rs index 0ce34c904bd..eb7927fc4ad 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -8,7 +8,7 @@ use rustc_session::Session; use cranelift_module::FuncId; use object::write::*; -use object::{RelocationEncoding, RelocationKind, SectionKind, SymbolFlags}; +use object::{RelocationEncoding, SectionKind, SymbolFlags}; use cranelift_object::{ObjectBuilder, ObjectModule, ObjectProduct}; @@ -22,9 +22,7 @@ pub(crate) trait WriteMetadata { impl WriteMetadata for object::write::Object { fn add_rustc_section(&mut self, symbol_name: String, data: Vec, _is_like_osx: bool) { - let segment = self - .segment_name(object::write::StandardSegment::Data) - .to_vec(); + let segment = self.segment_name(object::write::StandardSegment::Data).to_vec(); let section_id = self.add_section(segment, b".rustc".to_vec(), object::SectionKind::Data); let offset = self.append_section_data(section_id, &data, 1); // For MachO and probably PE this is necessary to prevent the linker from throwing away the @@ -74,11 +72,7 @@ impl WriteDebugInfo for ObjectProduct { let section_id = self.object.add_section( segment, name, - if id == SectionId::EhFrame { - SectionKind::ReadOnlyData - } else { - SectionKind::Debug - }, + if id == SectionId::EhFrame { SectionKind::ReadOnlyData } else { SectionKind::Debug }, ); self.object .section_mut(section_id) @@ -118,49 +112,6 @@ impl WriteDebugInfo for ObjectProduct { } } -// FIXME remove once atomic instructions are implemented in Cranelift. -pub(crate) trait AddConstructor { - fn add_constructor(&mut self, func_id: FuncId); -} - -impl AddConstructor for ObjectProduct { - fn add_constructor(&mut self, func_id: FuncId) { - let symbol = self.function_symbol(func_id); - let segment = self - .object - .segment_name(object::write::StandardSegment::Data); - let init_array_section = - self.object - .add_section(segment.to_vec(), b".init_array".to_vec(), SectionKind::Data); - let address_size = self - .object - .architecture() - .address_size() - .expect("address_size must be known") - .bytes(); - self.object.append_section_data( - init_array_section, - &std::iter::repeat(0) - .take(address_size.into()) - .collect::>(), - 8, - ); - self.object - .add_relocation( - init_array_section, - object::write::Relocation { - offset: 0, - size: address_size * 8, - kind: RelocationKind::Absolute, - encoding: RelocationEncoding::Generic, - symbol, - addend: 0, - }, - ) - .unwrap(); - } -} - pub(crate) fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object)) -> Vec { let triple = crate::build_isa(sess).triple().clone(); @@ -175,10 +126,9 @@ pub(crate) fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object target_lexicon::Architecture::X86_64 => object::Architecture::X86_64, target_lexicon::Architecture::Arm(_) => object::Architecture::Arm, target_lexicon::Architecture::Aarch64(_) => object::Architecture::Aarch64, - architecture => sess.fatal(&format!( - "target architecture {:?} is unsupported", - architecture, - )), + architecture => { + sess.fatal(&format!("target architecture {:?} is unsupported", architecture,)) + } }; let endian = match triple.endianness().unwrap() { target_lexicon::Endianness::Little => object::Endianness::Little, diff --git a/src/base.rs b/src/base.rs index 4842628a99d..0a7734d6a04 100644 --- a/src/base.rs +++ b/src/base.rs @@ -8,7 +8,7 @@ use rustc_target::abi::call::FnAbi; use crate::prelude::*; pub(crate) fn codegen_fn<'tcx>( - cx: &mut crate::CodegenCx<'tcx, impl Module>, + cx: &mut crate::CodegenCx<'_, 'tcx>, instance: Instance<'tcx>, linkage: Linkage, ) { @@ -38,9 +38,8 @@ pub(crate) fn codegen_fn<'tcx>( // Predefine blocks let start_block = bcx.create_block(); - let block_map: IndexVec = (0..mir.basic_blocks().len()) - .map(|_| bcx.create_block()) - .collect(); + let block_map: IndexVec = + (0..mir.basic_blocks().len()).map(|_| bcx.create_block()).collect(); // Make FunctionCx let pointer_type = cx.module.target_config().pointer_type(); @@ -68,22 +67,23 @@ pub(crate) fn codegen_fn<'tcx>( inline_asm_index: 0, }; - let arg_uninhabited = fx.mir.args_iter().any(|arg| { - fx.layout_of(fx.monomorphize(&fx.mir.local_decls[arg].ty)) - .abi - .is_uninhabited() - }); + let arg_uninhabited = fx + .mir + .args_iter() + .any(|arg| fx.layout_of(fx.monomorphize(&fx.mir.local_decls[arg].ty)).abi.is_uninhabited()); - if arg_uninhabited { - fx.bcx - .append_block_params_for_function_params(fx.block_map[START_BLOCK]); + if !crate::constant::check_constants(&mut fx) { + fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]); + fx.bcx.switch_to_block(fx.block_map[START_BLOCK]); + crate::trap::trap_unreachable(&mut fx, "compilation should have been aborted"); + } else if arg_uninhabited { + fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]); fx.bcx.switch_to_block(fx.block_map[START_BLOCK]); crate::trap::trap_unreachable(&mut fx, "function has uninhabited argument"); } else { tcx.sess.time("codegen clif ir", || { - tcx.sess.time("codegen prelude", || { - crate::abi::codegen_fn_prelude(&mut fx, start_block) - }); + tcx.sess + .time("codegen prelude", || crate::abi::codegen_fn_prelude(&mut fx, start_block)); codegen_fn_content(&mut fx); }); } @@ -131,11 +131,7 @@ pub(crate) fn codegen_fn<'tcx>( let module = &mut cx.module; tcx.sess.time("define function", || { module - .define_function( - func_id, - context, - &mut cranelift_codegen::binemit::NullTrapSink {}, - ) + .define_function(func_id, context, &mut cranelift_codegen::binemit::NullTrapSink {}) .unwrap() }); @@ -149,14 +145,12 @@ pub(crate) fn codegen_fn<'tcx>( &clif_comments, ); - if let Some(mach_compile_result) = &context.mach_compile_result { - if let Some(disasm) = &mach_compile_result.disasm { - crate::pretty_clif::write_ir_file( - tcx, - &format!("{}.vcode", tcx.symbol_name(instance).name), - |file| file.write_all(disasm.as_bytes()), - ) - } + if let Some(disasm) = &context.mach_compile_result.as_ref().unwrap().disasm { + crate::pretty_clif::write_ir_file( + tcx, + &format!("{}.vcode", tcx.symbol_name(instance).name), + |file| file.write_all(disasm.as_bytes()), + ) } // Define debuginfo for function @@ -199,16 +193,13 @@ pub(crate) fn verify_func( Some(Box::new(writer)), err, ); - tcx.sess - .fatal(&format!("cranelift verify error:\n{}", pretty_error)); + tcx.sess.fatal(&format!("cranelift verify error:\n{}", pretty_error)); } } }); } -fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) { - crate::constant::check_constants(fx); - +fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) { for (bb, bb_data) in fx.mir.basic_blocks().iter_enumerated() { let block = fx.get_block(bb); fx.bcx.switch_to_block(block); @@ -231,11 +222,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) { #[cfg(debug_assertions)] { let mut terminator_head = "\n".to_string(); - bb_data - .terminator() - .kind - .fmt_head(&mut terminator_head) - .unwrap(); + bb_data.terminator().kind.fmt_head(&mut terminator_head).unwrap(); let inst = fx.bcx.func.layout.last_inst(block).unwrap(); fx.add_comment(inst, terminator_head); } @@ -267,13 +254,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) { TerminatorKind::Return => { crate::abi::codegen_return(fx); } - TerminatorKind::Assert { - cond, - expected, - msg, - target, - cleanup: _, - } => { + TerminatorKind::Assert { cond, expected, msg, target, cleanup: _ } => { if !fx.tcx.sess.overflow_checks() { if let mir::AssertKind::OverflowNeg(_) = *msg { let target = fx.get_block(*target); @@ -319,11 +300,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) { } } - TerminatorKind::SwitchInt { - discr, - switch_ty, - targets, - } => { + TerminatorKind::SwitchInt { discr, switch_ty, targets } => { let discr = codegen_operand(fx, discr).load_scalar(fx); let use_bool_opt = switch_ty.kind() == fx.tcx.types.bool.kind() @@ -433,11 +410,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) { | TerminatorKind::GeneratorDrop => { bug!("shouldn't exist at codegen {:?}", bb_data.terminator()); } - TerminatorKind::Drop { - place, - target, - unwind: _, - } => { + TerminatorKind::Drop { place, target, unwind: _ } => { let drop_place = codegen_place(fx, *place); crate::abi::codegen_drop(fx, bb_data.terminator().source_info.span, drop_place); @@ -452,7 +425,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) { } fn codegen_stmt<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, #[allow(unused_variables)] cur_block: Block, stmt: &Statement<'tcx>, ) { @@ -470,10 +443,7 @@ fn codegen_stmt<'tcx>( } match &stmt.kind { - StatementKind::SetDiscriminant { - place, - variant_index, - } => { + StatementKind::SetDiscriminant { place, variant_index } => { let place = codegen_place(fx, **place); crate::discriminant::codegen_set_discriminant(fx, place, *variant_index); } @@ -594,19 +564,11 @@ fn codegen_stmt<'tcx>( let from_ty = operand.layout().ty; let to_ty = fx.monomorphize(to_ty); - fn is_fat_ptr<'tcx>( - fx: &FunctionCx<'_, 'tcx, impl Module>, - ty: Ty<'tcx>, - ) -> bool { + fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool { ty.builtin_deref(true) - .map( - |ty::TypeAndMut { - ty: pointee_ty, - mutbl: _, - }| { - has_ptr_meta(fx.tcx, pointee_ty) - }, - ) + .map(|ty::TypeAndMut { ty: pointee_ty, mutbl: _ }| { + has_ptr_meta(fx.tcx, pointee_ty) + }) .unwrap_or(false) } @@ -626,50 +588,22 @@ fn codegen_stmt<'tcx>( ty::Uint(_) | ty::Int(_) => {} _ => unreachable!("cast adt {} -> {}", from_ty, to_ty), } + let to_clif_ty = fx.clif_type(to_ty).unwrap(); - use rustc_target::abi::{Int, TagEncoding, Variants}; + let discriminant = crate::discriminant::codegen_get_discriminant( + fx, + operand, + fx.layout_of(operand.layout().ty.discriminant_ty(fx.tcx)), + ) + .load_scalar(fx); - match operand.layout().variants { - Variants::Single { index } => { - let discr = operand - .layout() - .ty - .discriminant_for_variant(fx.tcx, index) - .unwrap(); - let discr = if discr.ty.is_signed() { - fx.layout_of(discr.ty).size.sign_extend(discr.val) - } else { - discr.val - }; - let discr = discr.into(); - - let discr = CValue::const_val(fx, fx.layout_of(to_ty), discr); - lval.write_cvalue(fx, discr); - } - Variants::Multiple { - ref tag, - tag_field, - tag_encoding: TagEncoding::Direct, - variants: _, - } => { - let cast_to = fx.clif_type(dest_layout.ty).unwrap(); - - // Read the tag/niche-encoded discriminant from memory. - let encoded_discr = - operand.value_field(fx, mir::Field::new(tag_field)); - let encoded_discr = encoded_discr.load_scalar(fx); - - // Decode the discriminant (specifically if it's niche-encoded). - let signed = match tag.value { - Int(_, signed) => signed, - _ => false, - }; - let val = clif_intcast(fx, encoded_discr, cast_to, signed); - let val = CValue::by_val(val, dest_layout); - lval.write_cvalue(fx, val); - } - Variants::Multiple { .. } => unreachable!(), - } + let res = crate::cast::clif_intcast( + fx, + discriminant, + to_clif_ty, + to_ty.is_signed(), + ); + lval.write_cvalue(fx, CValue::by_val(res, dest_layout)); } else { let to_clif_ty = fx.clif_type(to_ty).unwrap(); let from = operand.load_scalar(fx); @@ -730,8 +664,7 @@ fn codegen_stmt<'tcx>( // FIXME use emit_small_memset where possible let addr = lval.to_ptr().get_addr(fx); let val = operand.load_scalar(fx); - fx.bcx - .call_memset(fx.cx.module.target_config(), addr, val, times); + fx.bcx.call_memset(fx.cx.module.target_config(), addr, val, times); } else { let loop_block = fx.bcx.create_block(); let loop_block2 = fx.bcx.create_block(); @@ -766,25 +699,19 @@ fn codegen_stmt<'tcx>( let content_ty = fx.monomorphize(content_ty); let layout = fx.layout_of(content_ty); let llsize = fx.bcx.ins().iconst(usize_type, layout.size.bytes() as i64); - let llalign = fx - .bcx - .ins() - .iconst(usize_type, layout.align.abi.bytes() as i64); + let llalign = fx.bcx.ins().iconst(usize_type, layout.align.abi.bytes() as i64); let box_layout = fx.layout_of(fx.tcx.mk_box(content_ty)); // Allocate space: - let def_id = match fx - .tcx - .lang_items() - .require(rustc_hir::LangItem::ExchangeMalloc) - { - Ok(id) => id, - Err(s) => { - fx.tcx - .sess - .fatal(&format!("allocation of `{}` {}", box_layout.ty, s)); - } - }; + let def_id = + match fx.tcx.lang_items().require(rustc_hir::LangItem::ExchangeMalloc) { + Ok(id) => id, + Err(s) => { + fx.tcx + .sess + .fatal(&format!("allocation of `{}` {}", box_layout.ty, s)); + } + }; let instance = ty::Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); let func_ref = fx.get_function_ref(instance); let call = fx.bcx.ins().call(func_ref, &[llsize, llalign]); @@ -792,10 +719,11 @@ fn codegen_stmt<'tcx>( lval.write_cvalue(fx, CValue::by_val(ptr, box_layout)); } Rvalue::NullaryOp(NullOp::SizeOf, ty) => { - assert!(lval - .layout() - .ty - .is_sized(fx.tcx.at(stmt.source_info.span), ParamEnv::reveal_all())); + assert!( + lval.layout() + .ty + .is_sized(fx.tcx.at(stmt.source_info.span), ParamEnv::reveal_all()) + ); let ty_size = fx.layout_of(fx.monomorphize(ty)).size.bytes(); let val = CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), ty_size.into()); @@ -823,11 +751,7 @@ fn codegen_stmt<'tcx>( StatementKind::LlvmInlineAsm(asm) => { use rustc_span::symbol::Symbol; - let LlvmInlineAsm { - asm, - outputs, - inputs, - } = &**asm; + let LlvmInlineAsm { asm, outputs, inputs } = &**asm; let rustc_hir::LlvmInlineAsmInner { asm: asm_code, // Name outputs: output_names, // Vec @@ -843,15 +767,9 @@ fn codegen_stmt<'tcx>( // Black box } "mov %rbx, %rsi\n cpuid\n xchg %rbx, %rsi" => { - assert_eq!( - input_names, - &[Symbol::intern("{eax}"), Symbol::intern("{ecx}")] - ); + assert_eq!(input_names, &[Symbol::intern("{eax}"), Symbol::intern("{ecx}")]); assert_eq!(output_names.len(), 4); - for (i, c) in (&["={eax}", "={esi}", "={ecx}", "={edx}"]) - .iter() - .enumerate() - { + for (i, c) in (&["={eax}", "={esi}", "={ecx}", "={edx}"]).iter().enumerate() { assert_eq!(&output_names[i].constraint.as_str(), c); assert!(!output_names[i].is_rw); assert!(!output_names[i].is_indirect); @@ -897,12 +815,7 @@ fn codegen_stmt<'tcx>( crate::trap::trap_unimplemented(fx, "_xgetbv arch intrinsic is not supported"); } // ___chkstk, ___chkstk_ms and __alloca are only used on Windows - _ if fx - .tcx - .symbol_name(fx.instance) - .name - .starts_with("___chkstk") => - { + _ if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") => { crate::trap::trap_unimplemented(fx, "Stack probes are not supported"); } _ if fx.tcx.symbol_name(fx.instance).name == "__alloca" => { @@ -922,27 +835,21 @@ fn codegen_stmt<'tcx>( } } -fn codegen_array_len<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - place: CPlace<'tcx>, -) -> Value { +fn codegen_array_len<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, place: CPlace<'tcx>) -> Value { match *place.layout().ty.kind() { ty::Array(_elem_ty, len) => { - let len = fx - .monomorphize(len) - .eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64; + let len = fx.monomorphize(len).eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64; fx.bcx.ins().iconst(fx.pointer_type, len) } - ty::Slice(_elem_ty) => place - .to_ptr_maybe_unsized() - .1 - .expect("Length metadata for slice place"), + ty::Slice(_elem_ty) => { + place.to_ptr_maybe_unsized().1.expect("Length metadata for slice place") + } _ => bug!("Rvalue::Len({:?})", place), } } pub(crate) fn codegen_place<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, place: Place<'tcx>, ) -> CPlace<'tcx> { let mut cplace = fx.get_local_place(place.local); @@ -959,11 +866,7 @@ pub(crate) fn codegen_place<'tcx>( let index = fx.get_local_place(local).to_cvalue(fx).load_scalar(fx); cplace = cplace.place_index(fx, index); } - PlaceElem::ConstantIndex { - offset, - min_length: _, - from_end, - } => { + PlaceElem::ConstantIndex { offset, min_length: _, from_end } => { let offset: u64 = offset; let index = if !from_end { fx.bcx.ins().iconst(fx.pointer_type, offset as i64) @@ -1014,7 +917,7 @@ pub(crate) fn codegen_place<'tcx>( } pub(crate) fn codegen_operand<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, operand: &Operand<'tcx>, ) -> CValue<'tcx> { match operand { @@ -1026,34 +929,24 @@ pub(crate) fn codegen_operand<'tcx>( } } -pub(crate) fn codegen_panic<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - msg_str: &str, - span: Span, -) { +pub(crate) fn codegen_panic<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, msg_str: &str, span: Span) { let location = fx.get_caller_location(span).load_scalar(fx); let msg_ptr = fx.anonymous_str("assert", msg_str); - let msg_len = fx - .bcx - .ins() - .iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap()); + let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap()); let args = [msg_ptr, msg_len, location]; codegen_panic_inner(fx, rustc_hir::LangItem::Panic, &args, span); } pub(crate) fn codegen_panic_inner<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, lang_item: rustc_hir::LangItem, args: &[Value], span: Span, ) { - let def_id = fx - .tcx - .lang_items() - .require(lang_item) - .unwrap_or_else(|s| fx.tcx.sess.span_fatal(span, &s)); + let def_id = + fx.tcx.lang_items().require(lang_item).unwrap_or_else(|s| fx.tcx.sess.span_fatal(span, &s)); let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); let symbol_name = fx.tcx.symbol_name(instance).name; diff --git a/src/bin/cg_clif.rs b/src/bin/cg_clif.rs index be369b07fdd..983839d48d2 100644 --- a/src/bin/cg_clif.rs +++ b/src/bin/cg_clif.rs @@ -27,13 +27,7 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks { config.opts.cg.panic = Some(PanicStrategy::Abort); config.opts.debugging_opts.panic_abort_tests = true; config.opts.maybe_sysroot = Some(config.opts.maybe_sysroot.clone().unwrap_or_else(|| { - std::env::current_exe() - .unwrap() - .parent() - .unwrap() - .parent() - .unwrap() - .to_owned() + std::env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_owned() })); } } diff --git a/src/bin/cg_clif_build_sysroot.rs b/src/bin/cg_clif_build_sysroot.rs index 83e5dc6e672..e7cd5edbbf6 100644 --- a/src/bin/cg_clif_build_sysroot.rs +++ b/src/bin/cg_clif_build_sysroot.rs @@ -46,15 +46,8 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks { config.opts.cg.panic = Some(PanicStrategy::Abort); config.opts.debugging_opts.panic_abort_tests = true; - config.opts.maybe_sysroot = Some( - std::env::current_exe() - .unwrap() - .parent() - .unwrap() - .parent() - .unwrap() - .to_owned(), - ); + config.opts.maybe_sysroot = + Some(std::env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_owned()); } } diff --git a/src/cast.rs b/src/cast.rs index 57204de1135..74c5e09f08d 100644 --- a/src/cast.rs +++ b/src/cast.rs @@ -3,7 +3,7 @@ use crate::prelude::*; pub(crate) fn clif_intcast( - fx: &mut FunctionCx<'_, '_, impl Module>, + fx: &mut FunctionCx<'_, '_, '_>, val: Value, to: Type, signed: bool, @@ -40,18 +40,14 @@ pub(crate) fn clif_intcast( // reduce (types::I128, _) => { let (lsb, _msb) = fx.bcx.ins().isplit(val); - if to == types::I64 { - lsb - } else { - fx.bcx.ins().ireduce(to, lsb) - } + if to == types::I64 { lsb } else { fx.bcx.ins().ireduce(to, lsb) } } (_, _) => fx.bcx.ins().ireduce(to, val), } } pub(crate) fn clif_int_or_float_cast( - fx: &mut FunctionCx<'_, '_, impl Module>, + fx: &mut FunctionCx<'_, '_, '_>, from: Value, from_signed: bool, to_ty: Type, @@ -87,11 +83,7 @@ pub(crate) fn clif_int_or_float_cast( }, ); - let from_rust_ty = if from_signed { - fx.tcx.types.i128 - } else { - fx.tcx.types.u128 - }; + let from_rust_ty = if from_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; let to_rust_ty = match to_ty { types::F32 => fx.tcx.types.f32, @@ -100,11 +92,7 @@ pub(crate) fn clif_int_or_float_cast( }; return fx - .easy_call( - &name, - &[CValue::by_val(from, fx.layout_of(from_rust_ty))], - to_rust_ty, - ) + .easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty) .load_scalar(fx); } @@ -138,18 +126,10 @@ pub(crate) fn clif_int_or_float_cast( _ => unreachable!(), }; - let to_rust_ty = if to_signed { - fx.tcx.types.i128 - } else { - fx.tcx.types.u128 - }; + let to_rust_ty = if to_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; return fx - .easy_call( - &name, - &[CValue::by_val(from, fx.layout_of(from_rust_ty))], - to_rust_ty, - ) + .easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty) .load_scalar(fx); } diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index 866ba90e4ae..ae75e6508cb 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -5,13 +5,17 @@ use cranelift_codegen::ir::ArgumentPurpose; use crate::prelude::*; pub(crate) fn maybe_codegen<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, checked: bool, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ) -> Option> { - if lhs.layout().ty != fx.tcx.types.u128 && lhs.layout().ty != fx.tcx.types.i128 { + if lhs.layout().ty != fx.tcx.types.u128 + && lhs.layout().ty != fx.tcx.types.i128 + && rhs.layout().ty != fx.tcx.types.u128 + && rhs.layout().ty != fx.tcx.types.i128 + { return None; } @@ -27,11 +31,7 @@ pub(crate) fn maybe_codegen<'tcx>( } BinOp::Add | BinOp::Sub if !checked => None, BinOp::Mul if !checked => { - let val_ty = if is_signed { - fx.tcx.types.i128 - } else { - fx.tcx.types.u128 - }; + let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty)) } BinOp::Add | BinOp::Sub | BinOp::Mul => { @@ -43,11 +43,7 @@ pub(crate) fn maybe_codegen<'tcx>( AbiParam::new(types::I128), AbiParam::new(types::I128), ]; - let args = [ - out_place.to_ptr().get_addr(fx), - lhs.load_scalar(fx), - rhs.load_scalar(fx), - ]; + let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)]; let name = match (bin_op, is_signed) { (BinOp::Add, false) => "__rust_u128_addo", (BinOp::Add, true) => "__rust_i128_addo", @@ -97,70 +93,23 @@ pub(crate) fn maybe_codegen<'tcx>( None }; - // Optimize `val >> 64`, because compiler_builtins uses it to deconstruct an 128bit - // integer into its lsb and msb. - // https://github.com/rust-lang-nursery/compiler-builtins/blob/79a6a1603d5672cbb9187ff41ff4d9b5048ac1cb/src/int/mod.rs#L217 - if resolve_value_imm(fx.bcx.func, rhs_val) == Some(64) { - let (lhs_lsb, lhs_msb) = fx.bcx.ins().isplit(lhs_val); - let all_zeros = fx.bcx.ins().iconst(types::I64, 0); - let val = match (bin_op, is_signed) { - (BinOp::Shr, false) => { - let val = fx.bcx.ins().iconcat(lhs_msb, all_zeros); - Some(CValue::by_val(val, fx.layout_of(fx.tcx.types.u128))) - } - (BinOp::Shr, true) => { - let sign = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, lhs_msb, 0); - let all_ones = fx.bcx.ins().iconst(types::I64, u64::MAX as i64); - let all_sign_bits = fx.bcx.ins().select(sign, all_zeros, all_ones); - - let val = fx.bcx.ins().iconcat(lhs_msb, all_sign_bits); - Some(CValue::by_val(val, fx.layout_of(fx.tcx.types.i128))) - } - (BinOp::Shl, _) => { - let val_ty = if is_signed { - fx.tcx.types.i128 - } else { - fx.tcx.types.u128 - }; - let val = fx.bcx.ins().iconcat(all_zeros, lhs_lsb); - Some(CValue::by_val(val, fx.layout_of(val_ty))) - } - _ => None, - }; - if let Some(val) = val { - if let Some(is_overflow) = is_overflow { - let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); - let val = val.load_scalar(fx); - return Some(CValue::by_val_pair(val, is_overflow, fx.layout_of(out_ty))); - } else { - return Some(val); - } - } - } - let truncated_rhs = clif_intcast(fx, rhs_val, types::I32, false); - let truncated_rhs = CValue::by_val(truncated_rhs, fx.layout_of(fx.tcx.types.u32)); - let val = match (bin_op, is_signed) { - (BinOp::Shl, false) => { - fx.easy_call("__ashlti3", &[lhs, truncated_rhs], fx.tcx.types.u128) + let val = match bin_op { + BinOp::Shl => fx.bcx.ins().ishl(lhs_val, truncated_rhs), + BinOp::Shr => { + if is_signed { + fx.bcx.ins().sshr(lhs_val, truncated_rhs) + } else { + fx.bcx.ins().ushr(lhs_val, truncated_rhs) + } } - (BinOp::Shl, true) => { - fx.easy_call("__ashlti3", &[lhs, truncated_rhs], fx.tcx.types.i128) - } - (BinOp::Shr, false) => { - fx.easy_call("__lshrti3", &[lhs, truncated_rhs], fx.tcx.types.u128) - } - (BinOp::Shr, true) => { - fx.easy_call("__ashrti3", &[lhs, truncated_rhs], fx.tcx.types.i128) - } - (_, _) => unreachable!(), + _ => unreachable!(), }; if let Some(is_overflow) = is_overflow { let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); - let val = val.load_scalar(fx); Some(CValue::by_val_pair(val, is_overflow, fx.layout_of(out_ty))) } else { - Some(val) + Some(CValue::by_val(val, lhs.layout())) } } } diff --git a/src/common.rs b/src/common.rs index fbee84e09f7..6a4a6744a5c 100644 --- a/src/common.rs +++ b/src/common.rs @@ -3,8 +3,6 @@ use rustc_target::abi::call::FnAbi; use rustc_target::abi::{Integer, Primitive}; use rustc_target::spec::{HasTargetSpec, Target}; -use cranelift_codegen::ir::{InstructionData, Opcode, ValueDef}; - use crate::prelude::*; pub(crate) fn pointer_ty(tcx: TyCtxt<'_>) -> types::Type { @@ -56,11 +54,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option types::F64, }, ty::FnPtr(_) => pointer_ty(tcx), - ty::RawPtr(TypeAndMut { - ty: pointee_ty, - mutbl: _, - }) - | ty::Ref(_, pointee_ty, _) => { + ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => { if has_ptr_meta(tcx, pointee_ty) { return None; } else { @@ -99,11 +93,7 @@ fn clif_pair_type_from_ty<'tcx>( } (a, b) } - ty::RawPtr(TypeAndMut { - ty: pointee_ty, - mutbl: _, - }) - | ty::Ref(_, pointee_ty, _) => { + ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => { if has_ptr_meta(tcx, pointee_ty) { (pointer_ty(tcx), pointer_ty(tcx)) } else { @@ -116,15 +106,8 @@ fn clif_pair_type_from_ty<'tcx>( /// Is a pointer to this type a fat ptr? pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { - let ptr_ty = tcx.mk_ptr(TypeAndMut { - ty, - mutbl: rustc_hir::Mutability::Not, - }); - match &tcx - .layout_of(ParamEnv::reveal_all().and(ptr_ty)) - .unwrap() - .abi - { + let ptr_ty = tcx.mk_ptr(TypeAndMut { ty, mutbl: rustc_hir::Mutability::Not }); + match &tcx.layout_of(ParamEnv::reveal_all().and(ptr_ty)).unwrap().abi { Abi::Scalar(_) => false, Abi::ScalarPair(_, _) => true, abi => unreachable!("Abi of ptr to {:?} is {:?}???", ty, abi), @@ -132,7 +115,7 @@ pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { } pub(crate) fn codegen_icmp_imm( - fx: &mut FunctionCx<'_, '_, impl Module>, + fx: &mut FunctionCx<'_, '_, '_>, intcc: IntCC, lhs: Value, rhs: i128, @@ -175,51 +158,6 @@ pub(crate) fn codegen_icmp_imm( } } -fn resolve_normal_value_imm(func: &Function, val: Value) -> Option { - if let ValueDef::Result(inst, 0 /*param*/) = func.dfg.value_def(val) { - if let InstructionData::UnaryImm { - opcode: Opcode::Iconst, - imm, - } = func.dfg[inst] - { - Some(imm.into()) - } else { - None - } - } else { - None - } -} - -fn resolve_128bit_value_imm(func: &Function, val: Value) -> Option { - let (lsb, msb) = if let ValueDef::Result(inst, 0 /*param*/) = func.dfg.value_def(val) { - if let InstructionData::Binary { - opcode: Opcode::Iconcat, - args: [lsb, msb], - } = func.dfg[inst] - { - (lsb, msb) - } else { - return None; - } - } else { - return None; - }; - - let lsb = u128::from(resolve_normal_value_imm(func, lsb)? as u64); - let msb = u128::from(resolve_normal_value_imm(func, msb)? as u64); - - Some(msb << 64 | lsb) -} - -pub(crate) fn resolve_value_imm(func: &Function, val: Value) -> Option { - if func.dfg.value_type(val) == types::I128 { - resolve_128bit_value_imm(func, val) - } else { - resolve_normal_value_imm(func, val).map(|imm| u128::from(imm as u64)) - } -} - pub(crate) fn type_min_max_value( bcx: &mut FunctionBuilder<'_>, ty: Type, @@ -288,8 +226,8 @@ pub(crate) fn type_sign(ty: Ty<'_>) -> bool { } } -pub(crate) struct FunctionCx<'clif, 'tcx, M: Module> { - pub(crate) cx: &'clif mut crate::CodegenCx<'tcx, M>, +pub(crate) struct FunctionCx<'m, 'clif, 'tcx> { + pub(crate) cx: &'clif mut crate::CodegenCx<'m, 'tcx>, pub(crate) tcx: TyCtxt<'tcx>, pub(crate) pointer_type: Type, // Cached from module @@ -316,7 +254,7 @@ pub(crate) struct FunctionCx<'clif, 'tcx, M: Module> { pub(crate) inline_asm_index: u32, } -impl<'tcx, M: Module> LayoutOf for FunctionCx<'_, 'tcx, M> { +impl<'tcx> LayoutOf for FunctionCx<'_, '_, 'tcx> { type Ty = Ty<'tcx>; type TyAndLayout = TyAndLayout<'tcx>; @@ -325,31 +263,31 @@ impl<'tcx, M: Module> LayoutOf for FunctionCx<'_, 'tcx, M> { } } -impl<'tcx, M: Module> layout::HasTyCtxt<'tcx> for FunctionCx<'_, 'tcx, M> { +impl<'tcx> layout::HasTyCtxt<'tcx> for FunctionCx<'_, '_, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } } -impl<'tcx, M: Module> rustc_target::abi::HasDataLayout for FunctionCx<'_, 'tcx, M> { +impl<'tcx> rustc_target::abi::HasDataLayout for FunctionCx<'_, '_, 'tcx> { fn data_layout(&self) -> &rustc_target::abi::TargetDataLayout { &self.tcx.data_layout } } -impl<'tcx, M: Module> layout::HasParamEnv<'tcx> for FunctionCx<'_, 'tcx, M> { +impl<'tcx> layout::HasParamEnv<'tcx> for FunctionCx<'_, '_, 'tcx> { fn param_env(&self) -> ParamEnv<'tcx> { ParamEnv::reveal_all() } } -impl<'tcx, M: Module> HasTargetSpec for FunctionCx<'_, 'tcx, M> { +impl<'tcx> HasTargetSpec for FunctionCx<'_, '_, 'tcx> { fn target_spec(&self) -> &Target { &self.tcx.sess.target } } -impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { +impl<'tcx> FunctionCx<'_, '_, 'tcx> { pub(crate) fn monomorphize(&self, value: T) -> T where T: TypeFoldable<'tcx> + Copy, @@ -416,12 +354,7 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { let msg_id = self .cx .module - .declare_data( - &format!("__{}_{:08x}", prefix, msg_hash), - Linkage::Local, - false, - false, - ) + .declare_data(&format!("__{}_{:08x}", prefix, msg_hash), Linkage::Local, false, false) .unwrap(); // Ignore DuplicateDefinition error, as the data will be the same @@ -444,15 +377,13 @@ impl<'tcx> LayoutOf for RevealAllLayoutCx<'tcx> { fn layout_of(&self, ty: Ty<'tcx>) -> TyAndLayout<'tcx> { assert!(!ty.still_further_specializable()); - self.0 - .layout_of(ParamEnv::reveal_all().and(&ty)) - .unwrap_or_else(|e| { - if let layout::LayoutError::SizeOverflow(_) = e { - self.0.sess.fatal(&e.to_string()) - } else { - bug!("failed to get layout for `{}`: {}", ty, e) - } - }) + self.0.layout_of(ParamEnv::reveal_all().and(&ty)).unwrap_or_else(|e| { + if let layout::LayoutError::SizeOverflow(_) = e { + self.0.sess.fatal(&e.to_string()) + } else { + bug!("failed to get layout for `{}`: {}", ty, e) + } + }) } } diff --git a/src/constant.rs b/src/constant.rs index 5702832bcb6..b0639cf9e15 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -28,7 +28,7 @@ enum TodoItem { } impl ConstantCx { - pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut impl Module) { + pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut dyn Module) { //println!("todo {:?}", self.todo); define_all_allocs(tcx, module, &mut self); //println!("done {:?}", self.done); @@ -36,21 +36,20 @@ impl ConstantCx { } } -pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, impl Module>) { +pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { + let mut all_constants_ok = true; for constant in &fx.mir.required_consts { let const_ = fx.monomorphize(constant.literal); match const_.val { ConstKind::Value(_) => {} ConstKind::Unevaluated(def, ref substs, promoted) => { if let Err(err) = - fx.tcx - .const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) + fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) { + all_constants_ok = false; match err { ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => { - fx.tcx - .sess - .span_err(constant.span, "erroneous constant encountered"); + fx.tcx.sess.span_err(constant.span, "erroneous constant encountered"); } ErrorHandled::TooGeneric => { span_bug!( @@ -69,6 +68,7 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, impl Module>) { | ConstKind::Error(_) => unreachable!("{:?}", const_), } } + all_constants_ok } pub(crate) fn codegen_static(constants_cx: &mut ConstantCx, def_id: DefId) { @@ -76,11 +76,11 @@ pub(crate) fn codegen_static(constants_cx: &mut ConstantCx, def_id: DefId) { } pub(crate) fn codegen_tls_ref<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, def_id: DefId, layout: TyAndLayout<'tcx>, ) -> CValue<'tcx> { - let data_id = data_id_for_static(fx.tcx, &mut fx.cx.module, def_id, false); + let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); #[cfg(debug_assertions)] fx.add_comment(local_data_id, format!("tls {:?}", def_id)); @@ -89,11 +89,11 @@ pub(crate) fn codegen_tls_ref<'tcx>( } fn codegen_static_ref<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, def_id: DefId, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { - let data_id = data_id_for_static(fx.tcx, &mut fx.cx.module, def_id, false); + let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); #[cfg(debug_assertions)] fx.add_comment(local_data_id, format!("{:?}", def_id)); @@ -110,7 +110,7 @@ fn codegen_static_ref<'tcx>( } pub(crate) fn codegen_constant<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, constant: &Constant<'tcx>, ) -> CValue<'tcx> { let const_ = fx.monomorphize(constant.literal); @@ -128,20 +128,10 @@ pub(crate) fn codegen_constant<'tcx>( .to_cvalue(fx); } ConstKind::Unevaluated(def, ref substs, promoted) => { - match fx - .tcx - .const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) - { + match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) { Ok(const_val) => const_val, Err(_) => { - fx.tcx - .sess - .span_err(constant.span, "erroneous constant encountered"); - return crate::trap::trap_unreachable_ret_value( - fx, - fx.layout_of(const_.ty), - "erroneous constant encountered", - ); + span_bug!(constant.span, "erroneous constant not captured by required_consts"); } } } @@ -156,7 +146,7 @@ pub(crate) fn codegen_constant<'tcx>( } pub(crate) fn codegen_const_value<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, const_val: ConstValue<'tcx>, ty: Ty<'tcx>, ) -> CValue<'tcx> { @@ -172,9 +162,7 @@ pub(crate) fn codegen_const_value<'tcx>( if fx.clif_type(layout.ty).is_none() { let (size, align) = (layout.size, layout.align.pref); let mut alloc = Allocation::from_bytes( - std::iter::repeat(0) - .take(size.bytes_usize()) - .collect::>(), + std::iter::repeat(0).take(size.bytes_usize()).collect::>(), align, ); let ptr = Pointer::new(AllocId(!0), Size::ZERO); // The alloc id is never used @@ -190,11 +178,8 @@ pub(crate) fn codegen_const_value<'tcx>( let base_addr = match alloc_kind { Some(GlobalAlloc::Memory(alloc)) => { fx.cx.constants_cx.todo.push(TodoItem::Alloc(ptr.alloc_id)); - let data_id = data_id_for_alloc_id( - &mut fx.cx.module, - ptr.alloc_id, - alloc.mutability, - ); + let data_id = + data_id_for_alloc_id(fx.cx.module, ptr.alloc_id, alloc.mutability); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); #[cfg(debug_assertions)] @@ -203,15 +188,14 @@ pub(crate) fn codegen_const_value<'tcx>( } Some(GlobalAlloc::Function(instance)) => { let func_id = - crate::abi::import_function(fx.tcx, &mut fx.cx.module, instance); + crate::abi::import_function(fx.tcx, fx.cx.module, instance); let local_func_id = fx.cx.module.declare_func_in_func(func_id, &mut fx.bcx.func); fx.bcx.ins().func_addr(fx.pointer_type, local_func_id) } Some(GlobalAlloc::Static(def_id)) => { assert!(fx.tcx.is_static(def_id)); - let data_id = - data_id_for_static(fx.tcx, &mut fx.cx.module, def_id, false); + let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); #[cfg(debug_assertions)] @@ -221,9 +205,7 @@ pub(crate) fn codegen_const_value<'tcx>( None => bug!("missing allocation {:?}", ptr.alloc_id), }; let val = if ptr.offset.bytes() != 0 { - fx.bcx - .ins() - .iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap()) + fx.bcx.ins().iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap()) } else { base_addr }; @@ -240,22 +222,22 @@ pub(crate) fn codegen_const_value<'tcx>( let ptr = pointer_for_allocation(fx, data) .offset_i64(fx, i64::try_from(start).unwrap()) .get_addr(fx); - let len = fx.bcx.ins().iconst( - fx.pointer_type, - i64::try_from(end.checked_sub(start).unwrap()).unwrap(), - ); + let len = fx + .bcx + .ins() + .iconst(fx.pointer_type, i64::try_from(end.checked_sub(start).unwrap()).unwrap()); CValue::by_val_pair(ptr, len, layout) } } } fn pointer_for_allocation<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, alloc: &'tcx Allocation, ) -> crate::pointer::Pointer { let alloc_id = fx.tcx.create_memory_alloc(alloc); fx.cx.constants_cx.todo.push(TodoItem::Alloc(alloc_id)); - let data_id = data_id_for_alloc_id(&mut fx.cx.module, alloc_id, alloc.mutability); + let data_id = data_id_for_alloc_id(fx.cx.module, alloc_id, alloc.mutability); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); #[cfg(debug_assertions)] @@ -265,7 +247,7 @@ fn pointer_for_allocation<'tcx>( } fn data_id_for_alloc_id( - module: &mut impl Module, + module: &mut dyn Module, alloc_id: AllocId, mutability: rustc_hir::Mutability, ) -> DataId { @@ -281,7 +263,7 @@ fn data_id_for_alloc_id( fn data_id_for_static( tcx: TyCtxt<'_>, - module: &mut impl Module, + module: &mut dyn Module, def_id: DefId, definition: bool, ) -> DataId { @@ -304,12 +286,7 @@ fn data_id_for_static( } else { !ty.is_freeze(tcx.at(DUMMY_SP), ParamEnv::reveal_all()) }; - let align = tcx - .layout_of(ParamEnv::reveal_all().and(ty)) - .unwrap() - .align - .pref - .bytes(); + let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes(); let attrs = tcx.codegen_fn_attrs(def_id); @@ -332,17 +309,11 @@ fn data_id_for_static( // zero. let ref_name = format!("_rust_extern_with_linkage_{}", symbol_name); - let ref_data_id = module - .declare_data(&ref_name, Linkage::Local, false, false) - .unwrap(); + let ref_data_id = module.declare_data(&ref_name, Linkage::Local, false, false).unwrap(); let mut data_ctx = DataContext::new(); data_ctx.set_align(align); let data = module.declare_data_in_data(data_id, &mut data_ctx); - data_ctx.define( - std::iter::repeat(0) - .take(pointer_ty(tcx).bytes() as usize) - .collect(), - ); + data_ctx.define(std::iter::repeat(0).take(pointer_ty(tcx).bytes() as usize).collect()); data_ctx.write_data_addr(0, data, 0); match module.define_data(ref_data_id, &data_ctx) { // Every time the static is referenced there will be another definition of this global, @@ -356,7 +327,7 @@ fn data_id_for_static( } } -fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut ConstantCx) { +fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut ConstantCx) { while let Some(todo_item) = cx.todo.pop() { let (data_id, alloc, section_name) = match todo_item { TodoItem::Alloc(alloc_id) => { @@ -371,10 +342,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut Constan TodoItem::Static(def_id) => { //println!("static {:?}", def_id); - let section_name = tcx - .codegen_fn_attrs(def_id) - .link_section - .map(|s| s.as_str()); + let section_name = tcx.codegen_fn_attrs(def_id).link_section.map(|s| s.as_str()); let alloc = tcx.eval_static_initializer(def_id).unwrap(); @@ -396,9 +364,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut Constan data_ctx.set_segment_section("", &*section_name); } - let bytes = alloc - .inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()) - .to_vec(); + let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec(); data_ctx.define(bytes.into_boxed_slice()); for &(offset, (_tag, reloc)) in alloc.relocations().iter() { @@ -426,10 +392,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut Constan data_id_for_alloc_id(module, reloc, target_alloc.mutability) } GlobalAlloc::Static(def_id) => { - if tcx - .codegen_fn_attrs(def_id) - .flags - .contains(CodegenFnAttrFlags::THREAD_LOCAL) + if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) { tcx.sess.fatal(&format!( "Allocation {:?} contains reference to TLS value {:?}", @@ -457,14 +420,13 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut Constan } pub(crate) fn mir_operand_get_const_val<'tcx>( - fx: &FunctionCx<'_, 'tcx, impl Module>, + fx: &FunctionCx<'_, '_, 'tcx>, operand: &Operand<'tcx>, ) -> Option<&'tcx Const<'tcx>> { match operand { Operand::Copy(_) | Operand::Move(_) => None, - Operand::Constant(const_) => Some( - fx.monomorphize(const_.literal) - .eval(fx.tcx, ParamEnv::reveal_all()), - ), + Operand::Constant(const_) => { + Some(fx.monomorphize(const_.literal).eval(fx.tcx, ParamEnv::reveal_all())) + } } } diff --git a/src/debuginfo/emit.rs b/src/debuginfo/emit.rs index 6160f9b78d8..6018eefcd42 100644 --- a/src/debuginfo/emit.rs +++ b/src/debuginfo/emit.rs @@ -14,10 +14,7 @@ impl DebugContext<'_> { let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone()); let root = self.dwarf.unit.root(); let root = self.dwarf.unit.get_mut(root); - root.set( - gimli::DW_AT_ranges, - AttributeValue::RangeListRef(unit_range_list_id), - ); + root.set(gimli::DW_AT_ranges, AttributeValue::RangeListRef(unit_range_list_id)); let mut sections = Sections::new(WriterRelocate::new(self.endian)); self.dwarf.write(&mut sections).unwrap(); @@ -66,10 +63,7 @@ pub(super) struct WriterRelocate { impl WriterRelocate { pub(super) fn new(endian: RunTimeEndian) -> Self { - WriterRelocate { - relocs: Vec::new(), - writer: EndianVec::new(endian), - } + WriterRelocate { relocs: Vec::new(), writer: EndianVec::new(endian) } } /// Perform the collected relocations to be usable for JIT usage. @@ -85,9 +79,7 @@ impl WriterRelocate { cranelift_module::FuncId::from_u32(sym.try_into().unwrap()), ); let val = (addr as u64 as i64 + reloc.addend) as u64; - self.writer - .write_udata_at(reloc.offset as usize, val, reloc.size) - .unwrap(); + self.writer.write_udata_at(reloc.offset as usize, val, reloc.size).unwrap(); } } } diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index d226755d85d..30ed356c762 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -53,11 +53,7 @@ pub(crate) fn make_file_info(hash: SourceFileHash) -> Option { if hash.kind == SourceFileHashAlgorithm::Md5 { let mut buf = [0u8; MD5_LEN]; buf.copy_from_slice(hash.hash_bytes()); - Some(FileInfo { - timestamp: 0, - size: 0, - md5: buf, - }) + Some(FileInfo { timestamp: 0, size: 0, md5: buf }) } else { None } @@ -112,24 +108,14 @@ impl<'tcx> DebugContext<'tcx> { let entry = self.dwarf.unit.get_mut(entry_id); - entry.set( - gimli::DW_AT_decl_file, - AttributeValue::FileIndex(Some(file_id)), - ); - entry.set( - gimli::DW_AT_decl_line, - AttributeValue::Udata(loc.line as u64), - ); + entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); + entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(loc.line as u64)); // FIXME: probably omit this - entry.set( - gimli::DW_AT_decl_column, - AttributeValue::Udata(loc.col.to_usize() as u64), - ); + entry.set(gimli::DW_AT_decl_column, AttributeValue::Udata(loc.col.to_usize() as u64)); } pub(super) fn create_debug_lines( &mut self, - isa: &dyn cranelift_codegen::isa::TargetIsa, symbol: usize, entry_id: UnitEntryId, context: &Context, @@ -138,7 +124,6 @@ impl<'tcx> DebugContext<'tcx> { ) -> CodeOffset { let tcx = self.tcx; let line_program = &mut self.dwarf.unit.line_program; - let func = &context.func; let line_strings = &mut self.dwarf.line_strings; let mut last_span = None; @@ -202,43 +187,22 @@ impl<'tcx> DebugContext<'tcx> { let mut func_end = 0; - if let Some(ref mcr) = &context.mach_compile_result { - for &MachSrcLoc { start, end, loc } in mcr.buffer.get_srclocs_sorted() { - line_program.row().address_offset = u64::from(start); - if !loc.is_default() { - let source_info = *source_info_set.get_index(loc.bits() as usize).unwrap(); - create_row_for_span(line_program, source_info.span); - } else { - create_row_for_span(line_program, function_span); - } - func_end = end; + let mcr = context.mach_compile_result.as_ref().unwrap(); + for &MachSrcLoc { start, end, loc } in mcr.buffer.get_srclocs_sorted() { + line_program.row().address_offset = u64::from(start); + if !loc.is_default() { + let source_info = *source_info_set.get_index(loc.bits() as usize).unwrap(); + create_row_for_span(line_program, source_info.span); + } else { + create_row_for_span(line_program, function_span); } - - line_program.end_sequence(u64::from(func_end)); - - func_end = mcr.buffer.total_size(); - } else { - let encinfo = isa.encoding_info(); - let mut blocks = func.layout.blocks().collect::>(); - blocks.sort_by_key(|block| func.offsets[*block]); // Ensure inst offsets always increase - - for block in blocks { - for (offset, inst, size) in func.inst_offsets(block, &encinfo) { - let srcloc = func.srclocs[inst]; - line_program.row().address_offset = u64::from(offset); - if !srcloc.is_default() { - let source_info = - *source_info_set.get_index(srcloc.bits() as usize).unwrap(); - create_row_for_span(line_program, source_info.span); - } else { - create_row_for_span(line_program, function_span); - } - func_end = offset + size; - } - } - line_program.end_sequence(u64::from(func_end)); + func_end = end; } + line_program.end_sequence(u64::from(func_end)); + + let func_end = mcr.buffer.total_size(); + assert_ne!(func_end, 0); let entry = self.dwarf.unit.get_mut(entry_id); @@ -246,10 +210,7 @@ impl<'tcx> DebugContext<'tcx> { gimli::DW_AT_low_pc, AttributeValue::Address(Address::Symbol { symbol, addend: 0 }), ); - entry.set( - gimli::DW_AT_high_pc, - AttributeValue::Udata(u64::from(func_end)), - ); + entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end))); self.emit_location(entry_id, function_span); diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index a6f4ded41b6..dc8bc8d9cb7 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -9,7 +9,7 @@ use crate::prelude::*; use rustc_index::vec::IndexVec; use cranelift_codegen::entity::EntityRef; -use cranelift_codegen::ir::{StackSlots, ValueLabel, ValueLoc}; +use cranelift_codegen::ir::{LabelValueLoc, StackSlots, ValueLabel, ValueLoc}; use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::ValueLocRange; @@ -39,7 +39,6 @@ pub(crate) struct DebugContext<'tcx> { dwarf: DwarfUnit, unit_range_list: RangeList, - clif_types: FxHashMap, types: FxHashMap, UnitEntryId>, } @@ -91,20 +90,11 @@ impl<'tcx> DebugContext<'tcx> { let root = dwarf.unit.root(); let root = dwarf.unit.get_mut(root); - root.set( - gimli::DW_AT_producer, - AttributeValue::StringRef(dwarf.strings.add(producer)), - ); - root.set( - gimli::DW_AT_language, - AttributeValue::Language(gimli::DW_LANG_Rust), - ); + root.set(gimli::DW_AT_producer, AttributeValue::StringRef(dwarf.strings.add(producer))); + root.set(gimli::DW_AT_language, AttributeValue::Language(gimli::DW_LANG_Rust)); root.set(gimli::DW_AT_name, AttributeValue::StringRef(name)); root.set(gimli::DW_AT_comp_dir, AttributeValue::StringRef(comp_dir)); - root.set( - gimli::DW_AT_low_pc, - AttributeValue::Address(Address::Constant(0)), - ); + root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0))); } DebugContext { @@ -115,48 +105,10 @@ impl<'tcx> DebugContext<'tcx> { dwarf, unit_range_list: RangeList(Vec::new()), - clif_types: FxHashMap::default(), types: FxHashMap::default(), } } - fn dwarf_ty_for_clif_ty(&mut self, ty: Type) -> UnitEntryId { - if let Some(type_id) = self.clif_types.get(&ty) { - return *type_id; - } - - let new_entry = |dwarf: &mut DwarfUnit, tag| dwarf.unit.add(dwarf.unit.root(), tag); - - let primitive = |dwarf: &mut DwarfUnit, ate| { - let type_id = new_entry(dwarf, gimli::DW_TAG_base_type); - let type_entry = dwarf.unit.get_mut(type_id); - type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(ate)); - type_id - }; - - let type_id = if ty.is_bool() { - primitive(&mut self.dwarf, gimli::DW_ATE_boolean) - } else if ty.is_int() { - primitive(&mut self.dwarf, gimli::DW_ATE_address) - } else if ty.is_float() { - primitive(&mut self.dwarf, gimli::DW_ATE_float) - } else { - new_entry(&mut self.dwarf, gimli::DW_TAG_structure_type) - }; - - let type_entry = self.dwarf.unit.get_mut(type_id); - type_entry.set( - gimli::DW_AT_name, - AttributeValue::String(format!("{}", ty).replace('i', "u").into_bytes()), - ); - type_entry.set( - gimli::DW_AT_byte_size, - AttributeValue::Udata(u64::from(ty.bytes())), - ); - - type_id - } - fn dwarf_ty(&mut self, ty: Ty<'tcx>) -> UnitEntryId { if let Some(type_id) = self.types.get(ty) { return *type_id; @@ -181,10 +133,7 @@ impl<'tcx> DebugContext<'tcx> { ty::Int(_) => primitive(&mut self.dwarf, gimli::DW_ATE_signed), ty::Float(_) => primitive(&mut self.dwarf, gimli::DW_ATE_float), ty::Ref(_, pointee_ty, _mutbl) - | ty::RawPtr(ty::TypeAndMut { - ty: pointee_ty, - mutbl: _mutbl, - }) => { + | ty::RawPtr(ty::TypeAndMut { ty: pointee_ty, mutbl: _mutbl }) => { let type_id = new_entry(&mut self.dwarf, gimli::DW_TAG_pointer_type); // Ensure that type is inserted before recursing to avoid duplicates @@ -211,10 +160,7 @@ impl<'tcx> DebugContext<'tcx> { let field_offset = layout.fields.offset(field_idx); let field_layout = layout .field( - &layout::LayoutCx { - tcx: self.tcx, - param_env: ParamEnv::reveal_all(), - }, + &layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() }, field_idx, ) .unwrap(); @@ -243,10 +189,7 @@ impl<'tcx> DebugContext<'tcx> { let type_entry = self.dwarf.unit.get_mut(type_id); type_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes())); - type_entry.set( - gimli::DW_AT_byte_size, - AttributeValue::Udata(layout.size.bytes()), - ); + type_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(layout.size.bytes())); self.types.insert(ty, type_id); @@ -286,23 +229,15 @@ impl<'tcx> DebugContext<'tcx> { let name_id = self.dwarf.strings.add(name); // Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped. entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); - entry.set( - gimli::DW_AT_linkage_name, - AttributeValue::StringRef(name_id), - ); + entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(name_id)); - let end = - self.create_debug_lines(isa, symbol, entry_id, context, mir.span, source_info_set); + let end = self.create_debug_lines(symbol, entry_id, context, mir.span, source_info_set); self.unit_range_list.0.push(Range::StartLength { begin: Address::Symbol { symbol, addend: 0 }, length: u64::from(end), }); - if isa.get_mach_backend().is_some() { - return; // Not yet implemented for the AArch64 backend. - } - let func_entry = self.dwarf.unit.get_mut(entry_id); // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped. func_entry.set( @@ -312,51 +247,6 @@ impl<'tcx> DebugContext<'tcx> { // Using Udata for DW_AT_high_pc requires at least DWARF4 func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end))); - // FIXME Remove once actual debuginfo for locals works. - for (i, (param, &val)) in context - .func - .signature - .params - .iter() - .zip( - context - .func - .dfg - .block_params(context.func.layout.entry_block().unwrap()), - ) - .enumerate() - { - use cranelift_codegen::ir::ArgumentPurpose; - let base_name = match param.purpose { - ArgumentPurpose::Normal => "arg", - ArgumentPurpose::StructArgument(_) => "struct_arg", - ArgumentPurpose::StructReturn => "sret", - ArgumentPurpose::Link - | ArgumentPurpose::FramePointer - | ArgumentPurpose::CalleeSaved => continue, - ArgumentPurpose::VMContext - | ArgumentPurpose::SignatureId - | ArgumentPurpose::CallerTLS - | ArgumentPurpose::CalleeTLS - | ArgumentPurpose::StackLimit => unreachable!(), - }; - let name = format!("{}{}", base_name, i); - - let dw_ty = self.dwarf_ty_for_clif_ty(param.value_type); - let loc = - translate_loc(isa, context.func.locations[val], &context.func.stack_slots).unwrap(); - - let arg_id = self - .dwarf - .unit - .add(entry_id, gimli::DW_TAG_formal_parameter); - let var_entry = self.dwarf.unit.get_mut(arg_id); - - var_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes())); - var_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty)); - var_entry.set(gimli::DW_AT_location, AttributeValue::Exprloc(loc)); - } - // FIXME make it more reliable and implement scopes before re-enabling this. if false { let value_labels_ranges = context.build_value_labels_ranges(isa).unwrap(); @@ -376,10 +266,7 @@ impl<'tcx> DebugContext<'tcx> { context, &local_map, &value_labels_ranges, - Place { - local, - projection: ty::List::empty(), - }, + Place { local, projection: ty::List::empty() }, ); let var_entry = self.dwarf.unit.get_mut(var_id); @@ -417,10 +304,7 @@ fn place_location<'tcx>( symbol, addend: i64::from(value_loc_range.start), }, - end: Address::Symbol { - symbol, - addend: i64::from(value_loc_range.end), - }, + end: Address::Symbol { symbol, addend: i64::from(value_loc_range.end) }, data: translate_loc( isa, value_loc_range.loc, @@ -463,17 +347,17 @@ fn place_location<'tcx>( // Adapted from https://github.com/CraneStation/wasmtime/blob/5a1845b4caf7a5dba8eda1fef05213a532ed4259/crates/debug/src/transform/expression.rs#L59-L137 fn translate_loc( isa: &dyn TargetIsa, - loc: ValueLoc, + loc: LabelValueLoc, stack_slots: &StackSlots, ) -> Option { match loc { - ValueLoc::Reg(reg) => { + LabelValueLoc::ValueLoc(ValueLoc::Reg(reg)) => { let machine_reg = isa.map_dwarf_register(reg).unwrap(); let mut expr = Expression::new(); expr.op_reg(gimli::Register(machine_reg)); Some(expr) } - ValueLoc::Stack(ss) => { + LabelValueLoc::ValueLoc(ValueLoc::Stack(ss)) => { if let Some(ss_offset) = stack_slots[ss].offset { let mut expr = Expression::new(); expr.op_breg(X86_64::RBP, i64::from(ss_offset) + 16); @@ -482,6 +366,17 @@ fn translate_loc( None } } - _ => None, + LabelValueLoc::ValueLoc(ValueLoc::Unassigned) => unreachable!(), + LabelValueLoc::Reg(reg) => { + let machine_reg = isa.map_regalloc_reg_to_dwarf(reg).unwrap(); + let mut expr = Expression::new(); + expr.op_reg(gimli::Register(machine_reg)); + Some(expr) + } + LabelValueLoc::SPOffset(offset) => { + let mut expr = Expression::new(); + expr.op_breg(X86_64::RSP, offset); + Some(expr) + } } } diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs index 49de927cdba..357c9fe6ed8 100644 --- a/src/debuginfo/unwind.rs +++ b/src/debuginfo/unwind.rs @@ -28,11 +28,7 @@ impl<'tcx> UnwindContext<'tcx> { None }; - UnwindContext { - tcx, - frame_table, - cie_id, - } + UnwindContext { tcx, frame_table, cie_id } } pub(crate) fn add_function(&mut self, func_id: FuncId, context: &Context, isa: &dyn TargetIsa) { @@ -46,10 +42,8 @@ impl<'tcx> UnwindContext<'tcx> { UnwindInfo::SystemV(unwind_info) => { self.frame_table.add_fde( self.cie_id.unwrap(), - unwind_info.to_fde(Address::Symbol { - symbol: func_id.as_u32() as usize, - addend: 0, - }), + unwind_info + .to_fde(Address::Symbol { symbol: func_id.as_u32() as usize, addend: 0 }), ); } UnwindInfo::WindowsX64(_) => { @@ -60,9 +54,8 @@ impl<'tcx> UnwindContext<'tcx> { } pub(crate) fn emit(self, product: &mut P) { - let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(super::target_endian( - self.tcx, - ))); + let mut eh_frame = + EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(self.tcx))); self.frame_table.write_eh_frame(&mut eh_frame).unwrap(); if !eh_frame.0.writer.slice().is_empty() { @@ -82,9 +75,8 @@ impl<'tcx> UnwindContext<'tcx> { self, jit_module: &cranelift_jit::JITModule, ) -> Option { - let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(super::target_endian( - self.tcx, - ))); + let mut eh_frame = + EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(self.tcx))); self.frame_table.write_eh_frame(&mut eh_frame).unwrap(); if eh_frame.0.writer.slice().is_empty() { @@ -130,10 +122,7 @@ impl<'tcx> UnwindContext<'tcx> { registrations.push(ptr as usize); } - Some(UnwindRegistry { - _frame_table: eh_frame, - registrations, - }) + Some(UnwindRegistry { _frame_table: eh_frame, registrations }) } } diff --git a/src/discriminant.rs b/src/discriminant.rs index ad635016a91..3326f87f000 100644 --- a/src/discriminant.rs +++ b/src/discriminant.rs @@ -7,7 +7,7 @@ use rustc_target::abi::{Int, TagEncoding, Variants}; use crate::prelude::*; pub(crate) fn codegen_set_discriminant<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, place: CPlace<'tcx>, variant_index: VariantIdx, ) { @@ -26,11 +26,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>( variants: _, } => { let ptr = place.place_field(fx, mir::Field::new(tag_field)); - let to = layout - .ty - .discriminant_for_variant(fx.tcx, variant_index) - .unwrap() - .val; + 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( ptr.layout().size.sign_extend(to) as i128, @@ -46,12 +42,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>( Variants::Multiple { tag: _, tag_field, - tag_encoding: - TagEncoding::Niche { - dataful_variant, - ref niche_variants, - niche_start, - }, + tag_encoding: TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start }, variants: _, } => { if variant_index != dataful_variant { @@ -70,7 +61,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>( } pub(crate) fn codegen_get_discriminant<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, value: CValue<'tcx>, dest_layout: TyAndLayout<'tcx>, ) -> CValue<'tcx> { @@ -101,12 +92,9 @@ pub(crate) fn codegen_get_discriminant<'tcx>( }; return CValue::const_val(fx, dest_layout, discr_val); } - Variants::Multiple { - tag, - tag_field, - tag_encoding, - variants: _, - } => (tag, *tag_field, tag_encoding), + Variants::Multiple { tag, tag_field, tag_encoding, variants: _ } => { + (tag, *tag_field, tag_encoding) + } }; let cast_to = fx.clif_type(dest_layout.ty).unwrap(); @@ -125,11 +113,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>( let val = clif_intcast(fx, tag, cast_to, signed); CValue::by_val(val, dest_layout) } - TagEncoding::Niche { - dataful_variant, - ref niche_variants, - niche_start, - } => { + TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => { // Rebase from niche values to discriminants, and check // whether the result is in range for the niche variants. @@ -146,9 +130,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>( tag } else { // FIXME handle niche_start > i64::MAX - fx.bcx - .ins() - .iadd_imm(tag, -i64::try_from(niche_start).unwrap()) + fx.bcx.ins().iadd_imm(tag, -i64::try_from(niche_start).unwrap()) }; let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32(); let is_niche = { @@ -176,15 +158,10 @@ pub(crate) fn codegen_get_discriminant<'tcx>( } else { clif_intcast(fx, relative_discr, cast_to, false) }; - fx.bcx - .ins() - .iadd_imm(relative_discr, i64::from(niche_variants.start().as_u32())) + fx.bcx.ins().iadd_imm(relative_discr, i64::from(niche_variants.start().as_u32())) }; - let dataful_variant = fx - .bcx - .ins() - .iconst(cast_to, i64::from(dataful_variant.as_u32())); + let dataful_variant = fx.bcx.ins().iconst(cast_to, i64::from(dataful_variant.as_u32())); let discr = fx.bcx.ins().select(is_niche, niche_discr, dataful_variant); CValue::by_val(discr, dest_layout) } diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 39781e2482a..b87dcc41928 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -12,11 +12,9 @@ use rustc_middle::mir::mono::{CodegenUnit, MonoItem}; use rustc_session::cgu_reuse_tracker::CguReuse; use rustc_session::config::{DebugInfo, OutputType}; -use cranelift_object::{ObjectModule, ObjectProduct}; +use cranelift_object::ObjectModule; -use crate::prelude::*; - -use crate::backend::AddConstructor; +use crate::{prelude::*, BackendConfig}; fn new_module(tcx: TyCtxt<'_>, name: String) -> ObjectModule { let module = crate::backend::make_module(tcx.sess, name); @@ -39,7 +37,6 @@ fn emit_module( module: ObjectModule, debug: Option>, unwind_context: UnwindContext<'_>, - map_product: impl FnOnce(ObjectProduct) -> ObjectProduct, ) -> ModuleCodegenResult { let mut product = module.finish(); @@ -49,15 +46,10 @@ fn emit_module( unwind_context.emit(&mut product); - let product = map_product(product); - - let tmp_file = tcx - .output_filenames(LOCAL_CRATE) - .temp_path(OutputType::Object, Some(&name)); + let tmp_file = tcx.output_filenames(LOCAL_CRATE).temp_path(OutputType::Object, Some(&name)); let obj = product.object.write().unwrap(); if let Err(err) = std::fs::write(&tmp_file, obj) { - tcx.sess - .fatal(&format!("error writing object file: {}", err)); + tcx.sess.fatal(&format!("error writing object file: {}", err)); } let work_product = if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() { @@ -71,13 +63,7 @@ fn emit_module( }; ModuleCodegenResult( - CompiledModule { - name, - kind, - object: Some(tmp_file), - dwarf_object: None, - bytecode: None, - }, + CompiledModule { name, kind, object: Some(tmp_file), dwarf_object: None, bytecode: None }, work_product, ) } @@ -117,49 +103,27 @@ fn reuse_workproduct_for_cgu( } } -fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodegenResult { +fn module_codegen( + tcx: TyCtxt<'_>, + (backend_config, cgu_name): (BackendConfig, rustc_span::Symbol), +) -> ModuleCodegenResult { let cgu = tcx.codegen_unit(cgu_name); let mono_items = cgu.items_in_deterministic_order(tcx); let mut module = new_module(tcx, cgu_name.as_str().to_string()); - // Initialize the global atomic mutex using a constructor for proc-macros. - // FIXME implement atomic instructions in Cranelift. - let mut init_atomics_mutex_from_constructor = None; - if tcx - .sess - .crate_types() - .contains(&rustc_session::config::CrateType::ProcMacro) - { - if mono_items.iter().any(|(mono_item, _)| match mono_item { - rustc_middle::mir::mono::MonoItem::Static(def_id) => tcx - .symbol_name(Instance::mono(tcx, *def_id)) - .name - .contains("__rustc_proc_macro_decls_"), - _ => false, - }) { - init_atomics_mutex_from_constructor = - Some(crate::atomic_shim::init_global_lock_constructor( - &mut module, - &format!("{}_init_atomics_mutex", cgu_name.as_str()), - )); - } - } - let mut cx = crate::CodegenCx::new( tcx, - module, + backend_config, + &mut module, tcx.sess.opts.debuginfo != DebugInfo::None, - true, ); super::predefine_mono_items(&mut cx, &mono_items); for (mono_item, (linkage, visibility)) in mono_items { let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility); match mono_item { MonoItem::Fn(inst) => { - cx.tcx.sess.time("codegen fn", || { - crate::base::codegen_fn(&mut cx, inst, linkage) - }); + cx.tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, inst, linkage)); } MonoItem::Static(def_id) => { crate::constant::codegen_static(&mut cx.constants_cx, def_id) @@ -175,9 +139,9 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege } } } - let (mut module, global_asm, debug, mut unwind_context) = + let (global_asm, debug, mut unwind_context) = tcx.sess.time("finalize CodegenCx", || cx.finalize()); - crate::main_shim::maybe_create_entry_wrapper(tcx, &mut module, &mut unwind_context, false); + crate::main_shim::maybe_create_entry_wrapper(tcx, &mut module, &mut unwind_context); let codegen_result = emit_module( tcx, @@ -186,13 +150,6 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege module, debug, unwind_context, - |mut product| { - if let Some(func_id) = init_atomics_mutex_from_constructor { - product.add_constructor(func_id); - } - - product - }, ); codegen_global_asm(tcx, &cgu.name().as_str(), &global_asm); @@ -202,6 +159,7 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege pub(super) fn run_aot( tcx: TyCtxt<'_>, + backend_config: BackendConfig, metadata: EncodedMetadata, need_metadata_module: bool, ) -> Box<(CodegenResults, FxHashMap)> { @@ -225,9 +183,7 @@ pub(super) fn run_aot( cgus.iter() .map(|cgu| { let cgu_reuse = determine_cgu_reuse(tcx, cgu); - tcx.sess - .cgu_reuse_tracker - .set_actual_reuse(&cgu.name().as_str(), cgu_reuse); + tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse); match cgu_reuse { _ if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() => {} @@ -242,7 +198,7 @@ pub(super) fn run_aot( let (ModuleCodegenResult(module, work_product), _) = tcx.dep_graph.with_task( dep_node, tcx, - cgu.name(), + (backend_config, cgu.name()), module_codegen, rustc_middle::dep_graph::hash_result, ); @@ -271,7 +227,6 @@ pub(super) fn run_aot( allocator_module, None, allocator_unwind_context, - |product| product, ); if let Some((id, product)) = work_product { work_products.insert(id, product); @@ -301,8 +256,7 @@ pub(super) fn run_aot( }); if let Err(err) = std::fs::write(&tmp_file, obj) { - tcx.sess - .fatal(&format!("error writing metadata object file: {}", err)); + tcx.sess.fatal(&format!("error writing metadata object file: {}", err)); } (metadata_cgu_name, tmp_file) @@ -356,8 +310,7 @@ fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) { "asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift", ); } else { - tcx.sess - .fatal("asm! and global_asm! are not yet supported on macOS and Windows"); + tcx.sess.fatal("asm! and global_asm! are not yet supported on macOS and Windows"); } } @@ -367,19 +320,12 @@ fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) { // Remove all LLVM style comments let global_asm = global_asm .lines() - .map(|line| { - if let Some(index) = line.find("//") { - &line[0..index] - } else { - line - } - }) + .map(|line| if let Some(index) = line.find("//") { &line[0..index] } else { line }) .collect::>() .join("\n"); - let output_object_file = tcx - .output_filenames(LOCAL_CRATE) - .temp_path(OutputType::Object, Some(cgu_name)); + let output_object_file = + tcx.output_filenames(LOCAL_CRATE).temp_path(OutputType::Object, Some(cgu_name)); // Assemble `global_asm` let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm"); @@ -389,16 +335,10 @@ fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) { .stdin(Stdio::piped()) .spawn() .expect("Failed to spawn `as`."); - child - .stdin - .take() - .unwrap() - .write_all(global_asm.as_bytes()) - .unwrap(); + child.stdin.take().unwrap().write_all(global_asm.as_bytes()).unwrap(); let status = child.wait().expect("Failed to wait for `as`."); if !status.success() { - tcx.sess - .fatal(&format!("Failed to assemble `{}`", global_asm)); + tcx.sess.fatal(&format!("Failed to assemble `{}`", global_asm)); } // Link the global asm and main object file together @@ -442,11 +382,7 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR } let work_product_id = &cgu.work_product_id(); - if tcx - .dep_graph - .previous_work_product(work_product_id) - .is_none() - { + if tcx.dep_graph.previous_work_product(work_product_id).is_none() { // We don't have anything cached for this CGU. This can happen // if the CGU did not exist in the previous session. return CguReuse::No; diff --git a/src/driver/jit.rs b/src/driver/jit.rs index f784d8d27cc..245df03ffb8 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -10,43 +10,24 @@ use rustc_middle::mir::mono::MonoItem; use cranelift_jit::{JITBuilder, JITModule}; -use crate::prelude::*; +use crate::{prelude::*, BackendConfig}; use crate::{CodegenCx, CodegenMode}; thread_local! { + pub static BACKEND_CONFIG: RefCell> = RefCell::new(None); pub static CURRENT_MODULE: RefCell> = RefCell::new(None); } -pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { +pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { if !tcx.sess.opts.output_types.should_codegen() { tcx.sess.fatal("JIT mode doesn't work with `cargo check`."); } - #[cfg(unix)] - unsafe { - // When not using our custom driver rustc will open us without the RTLD_GLOBAL flag, so - // __cg_clif_global_atomic_mutex will not be exported. We fix this by opening ourself again - // as global. - // FIXME remove once atomic_shim is gone - - let mut dl_info: libc::Dl_info = std::mem::zeroed(); - assert_ne!( - libc::dladdr(run_jit as *const libc::c_void, &mut dl_info), - 0 - ); - assert_ne!( - libc::dlopen(dl_info.dli_fname, libc::RTLD_NOW | libc::RTLD_GLOBAL), - std::ptr::null_mut(), - ); - } - let imported_symbols = load_imported_symbols_for_jit(tcx); - let mut jit_builder = JITBuilder::with_isa( - crate::build_isa(tcx.sess), - cranelift_module::default_libcall_names(), - ); - jit_builder.hotswap(matches!(codegen_mode, CodegenMode::JitLazy)); + let mut jit_builder = + JITBuilder::with_isa(crate::build_isa(tcx.sess), cranelift_module::default_libcall_names()); + jit_builder.hotswap(matches!(backend_config.codegen_mode, CodegenMode::JitLazy)); jit_builder.symbols(imported_symbols); let mut jit_module = JITModule::new(jit_builder); assert_eq!(pointer_ty(tcx), jit_module.target_config().pointer_type()); @@ -56,14 +37,10 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { AbiParam::new(jit_module.target_config().pointer_type()), AbiParam::new(jit_module.target_config().pointer_type()), ], - returns: vec![AbiParam::new( - jit_module.target_config().pointer_type(), /*isize*/ - )], + returns: vec![AbiParam::new(jit_module.target_config().pointer_type() /*isize*/)], call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)), }; - let main_func_id = jit_module - .declare_function("main", Linkage::Import, &sig) - .unwrap(); + let main_func_id = jit_module.declare_function("main", Linkage::Import, &sig).unwrap(); let (_, cgus) = tcx.collect_and_partition_mono_items(LOCAL_CRATE); let mono_items = cgus @@ -74,19 +51,19 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { .into_iter() .collect::>(); - let mut cx = crate::CodegenCx::new(tcx, jit_module, false, false); + let mut cx = crate::CodegenCx::new(tcx, backend_config, &mut jit_module, false); super::time(tcx, "codegen mono items", || { super::predefine_mono_items(&mut cx, &mono_items); for (mono_item, (linkage, visibility)) in mono_items { let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility); match mono_item { - MonoItem::Fn(inst) => match codegen_mode { + MonoItem::Fn(inst) => match backend_config.codegen_mode { CodegenMode::Aot => unreachable!(), CodegenMode::Jit => { - cx.tcx.sess.time("codegen fn", || { - crate::base::codegen_fn(&mut cx, inst, linkage) - }); + cx.tcx + .sess + .time("codegen fn", || crate::base::codegen_fn(&mut cx, inst, linkage)); } CodegenMode::JitLazy => codegen_shim(&mut cx, inst), }, @@ -101,7 +78,7 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { } }); - let (mut jit_module, global_asm, _debug, mut unwind_context) = + let (global_asm, _debug, mut unwind_context) = tcx.sess.time("finalize CodegenCx", || cx.finalize()); jit_module.finalize_definitions(); @@ -109,7 +86,7 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { tcx.sess.fatal("Inline asm is not supported in JIT mode"); } - crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, &mut unwind_context, true); + crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, &mut unwind_context); crate::allocator::codegen(tcx, &mut jit_module, &mut unwind_context); tcx.sess.abort_if_errors(); @@ -120,7 +97,9 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id); - println!("Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed"); + println!( + "Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed" + ); let f: extern "C" fn(c_int, *const *const c_char) -> c_int = unsafe { ::std::mem::transmute(finalized_main) }; @@ -136,6 +115,9 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { // useful as some dynamic linkers use it as a marker to jump over. argv.push(std::ptr::null()); + BACKEND_CONFIG.with(|tls_backend_config| { + assert!(tls_backend_config.borrow_mut().replace(backend_config).is_none()) + }); CURRENT_MODULE .with(|current_module| assert!(current_module.borrow_mut().replace(jit_module).is_none())); @@ -153,21 +135,19 @@ extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>) -> *const u8 CURRENT_MODULE.with(|jit_module| { let mut jit_module = jit_module.borrow_mut(); let jit_module = jit_module.as_mut().unwrap(); - let mut cx = crate::CodegenCx::new(tcx, jit_module, false, false); + let backend_config = + BACKEND_CONFIG.with(|backend_config| backend_config.borrow().clone().unwrap()); let name = tcx.symbol_name(instance).name.to_string(); - let sig = crate::abi::get_function_sig(tcx, cx.module.isa().triple(), instance); - let func_id = cx - .module - .declare_function(&name, Linkage::Export, &sig) - .unwrap(); - cx.module.prepare_for_function_redefine(func_id).unwrap(); + let sig = crate::abi::get_function_sig(tcx, jit_module.isa().triple(), instance); + let func_id = jit_module.declare_function(&name, Linkage::Export, &sig).unwrap(); + jit_module.prepare_for_function_redefine(func_id).unwrap(); - tcx.sess.time("codegen fn", || { - crate::base::codegen_fn(&mut cx, instance, Linkage::Export) - }); + let mut cx = crate::CodegenCx::new(tcx, backend_config, jit_module, false); + tcx.sess + .time("codegen fn", || crate::base::codegen_fn(&mut cx, instance, Linkage::Export)); - let (jit_module, global_asm, _debug_context, unwind_context) = cx.finalize(); + let (global_asm, _debug_context, unwind_context) = cx.finalize(); assert!(global_asm.is_empty()); jit_module.finalize_definitions(); std::mem::forget(unsafe { unwind_context.register_jit(&jit_module) }); @@ -194,9 +174,8 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> { Linkage::NotLinked | Linkage::IncludedFromDylib => {} Linkage::Static => { let name = tcx.crate_name(cnum); - let mut err = tcx - .sess - .struct_err(&format!("Can't load static lib {}", name.as_str())); + let mut err = + tcx.sess.struct_err(&format!("Can't load static lib {}", name.as_str())); err.note("rustc_codegen_cranelift can only load dylibs in JIT mode."); err.emit(); } @@ -217,6 +196,11 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> { if name.is_empty() || !symbol.is_global() || symbol.is_undefined() { return None; } + if name.starts_with("rust_metadata_") { + // The metadata is part of a section that is not loaded by the dynamic linker in + // case of cg_llvm. + return None; + } let dlsym_name = if cfg!(target_os = "macos") { // On macOS `dlsym` expects the name without leading `_`. assert!(name.starts_with('_'), "{:?}", name); @@ -236,17 +220,14 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> { imported_symbols } -pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx, impl Module>, inst: Instance<'tcx>) { +pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'_, 'tcx>, inst: Instance<'tcx>) { let tcx = cx.tcx; let pointer_type = cx.module.target_config().pointer_type(); let name = tcx.symbol_name(inst).name.to_string(); let sig = crate::abi::get_function_sig(tcx, cx.module.isa().triple(), inst); - let func_id = cx - .module - .declare_function(&name, Linkage::Export, &sig) - .unwrap(); + let func_id = cx.module.declare_function(&name, Linkage::Export, &sig).unwrap(); let instance_ptr = Box::into_raw(Box::new(inst)); @@ -267,28 +248,18 @@ pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx, impl Module>, inst: In let mut builder_ctx = FunctionBuilderContext::new(); let mut trampoline_builder = FunctionBuilder::new(&mut trampoline, &mut builder_ctx); - let jit_fn = cx - .module - .declare_func_in_func(jit_fn, trampoline_builder.func); + let jit_fn = cx.module.declare_func_in_func(jit_fn, trampoline_builder.func); let sig_ref = trampoline_builder.func.import_signature(sig); let entry_block = trampoline_builder.create_block(); trampoline_builder.append_block_params_for_function_params(entry_block); - let fn_args = trampoline_builder - .func - .dfg - .block_params(entry_block) - .to_vec(); + let fn_args = trampoline_builder.func.dfg.block_params(entry_block).to_vec(); trampoline_builder.switch_to_block(entry_block); - let instance_ptr = trampoline_builder - .ins() - .iconst(pointer_type, instance_ptr as u64 as i64); + let instance_ptr = trampoline_builder.ins().iconst(pointer_type, instance_ptr as u64 as i64); let jitted_fn = trampoline_builder.ins().call(jit_fn, &[instance_ptr]); let jitted_fn = trampoline_builder.func.dfg.inst_results(jitted_fn)[0]; - let call_inst = trampoline_builder - .ins() - .call_indirect(sig_ref, jitted_fn, &fn_args); + let call_inst = trampoline_builder.ins().call_indirect(sig_ref, jitted_fn, &fn_args); let ret_vals = trampoline_builder.func.dfg.inst_results(call_inst).to_vec(); trampoline_builder.ins().return_(&ret_vals); diff --git a/src/driver/mod.rs b/src/driver/mod.rs index 2497f9dfdfb..b994f28ffef 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -17,33 +17,30 @@ pub(crate) fn codegen_crate( tcx: TyCtxt<'_>, metadata: EncodedMetadata, need_metadata_module: bool, - config: crate::BackendConfig, + backend_config: crate::BackendConfig, ) -> Box { tcx.sess.abort_if_errors(); - match config.codegen_mode { - CodegenMode::Aot => aot::run_aot(tcx, metadata, need_metadata_module), + match backend_config.codegen_mode { + CodegenMode::Aot => aot::run_aot(tcx, backend_config, metadata, need_metadata_module), CodegenMode::Jit | CodegenMode::JitLazy => { - let is_executable = tcx - .sess - .crate_types() - .contains(&rustc_session::config::CrateType::Executable); + let is_executable = + tcx.sess.crate_types().contains(&rustc_session::config::CrateType::Executable); if !is_executable { tcx.sess.fatal("can't jit non-executable crate"); } #[cfg(feature = "jit")] - let _: ! = jit::run_jit(tcx, config.codegen_mode); + let _: ! = jit::run_jit(tcx, backend_config); #[cfg(not(feature = "jit"))] - tcx.sess - .fatal("jit support was disabled when compiling rustc_codegen_cranelift"); + tcx.sess.fatal("jit support was disabled when compiling rustc_codegen_cranelift"); } } } fn predefine_mono_items<'tcx>( - cx: &mut crate::CodegenCx<'tcx, impl Module>, + cx: &mut crate::CodegenCx<'_, 'tcx>, mono_items: &[(MonoItem<'tcx>, (RLinkage, Visibility))], ) { cx.tcx.sess.time("predefine functions", || { @@ -63,21 +60,12 @@ fn predefine_mono_items<'tcx>( } fn time(tcx: TyCtxt<'_>, name: &'static str, f: impl FnOnce() -> R) -> R { - if std::env::var("CG_CLIF_DISPLAY_CG_TIME") - .as_ref() - .map(|val| &**val) - == Ok("1") - { + if std::env::var("CG_CLIF_DISPLAY_CG_TIME").as_ref().map(|val| &**val) == Ok("1") { println!("[{:<30}: {}] start", tcx.crate_name(LOCAL_CRATE), name); let before = std::time::Instant::now(); let res = tcx.sess.time(name, f); let after = std::time::Instant::now(); - println!( - "[{:<30}: {}] end time: {:?}", - tcx.crate_name(LOCAL_CRATE), - name, - after - before - ); + println!("[{:<30}: {}] end time: {:?}", tcx.crate_name(LOCAL_CRATE), name, after - before); res } else { tcx.sess.time(name, f) diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 04aac780125..5b3df2bd382 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -9,7 +9,7 @@ use rustc_middle::mir::InlineAsmOperand; use rustc_target::asm::*; pub(crate) fn codegen_inline_asm<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, _span: Span, template: &[InlineAsmTemplatePiece], operands: &[InlineAsmOperand<'tcx>], @@ -53,11 +53,7 @@ pub(crate) fn codegen_inline_asm<'tcx>( crate::base::codegen_operand(fx, value).load_scalar(fx), )); } - InlineAsmOperand::Out { - reg, - late: _, - place, - } => { + InlineAsmOperand::Out { reg, late: _, place } => { let reg = expect_reg(reg); clobbered_regs.push((reg, new_slot(reg.reg_class()))); if let Some(place) = place { @@ -68,12 +64,7 @@ pub(crate) fn codegen_inline_asm<'tcx>( )); } } - InlineAsmOperand::InOut { - reg, - late: _, - ref in_value, - out_place, - } => { + InlineAsmOperand::InOut { reg, late: _, ref in_value, out_place } => { let reg = expect_reg(reg); clobbered_regs.push((reg, new_slot(reg.reg_class()))); inputs.push(( @@ -97,11 +88,8 @@ pub(crate) fn codegen_inline_asm<'tcx>( let inline_asm_index = fx.inline_asm_index; fx.inline_asm_index += 1; - let asm_name = format!( - "{}__inline_asm_{}", - fx.tcx.symbol_name(fx.instance).name, - inline_asm_index - ); + let asm_name = + format!("{}__inline_asm_{}", fx.tcx.symbol_name(fx.instance).name, inline_asm_index); let generated_asm = generate_asm_wrapper( &asm_name, @@ -129,12 +117,7 @@ fn generate_asm_wrapper( let mut generated_asm = String::new(); writeln!(generated_asm, ".globl {}", asm_name).unwrap(); writeln!(generated_asm, ".type {},@function", asm_name).unwrap(); - writeln!( - generated_asm, - ".section .text.{},\"ax\",@progbits", - asm_name - ) - .unwrap(); + writeln!(generated_asm, ".section .text.{},\"ax\",@progbits", asm_name).unwrap(); writeln!(generated_asm, "{}:", asm_name).unwrap(); generated_asm.push_str(".intel_syntax noprefix\n"); @@ -164,11 +147,7 @@ fn generate_asm_wrapper( InlineAsmTemplatePiece::String(s) => { generated_asm.push_str(s); } - InlineAsmTemplatePiece::Placeholder { - operand_idx: _, - modifier: _, - span: _, - } => todo!(), + InlineAsmTemplatePiece::Placeholder { operand_idx: _, modifier: _, span: _ } => todo!(), } } generated_asm.push('\n'); @@ -203,7 +182,7 @@ fn generate_asm_wrapper( } fn call_inline_asm<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, asm_name: &str, slot_size: Size, inputs: Vec<(InlineAsmReg, Size, Value)>, @@ -230,17 +209,12 @@ fn call_inline_asm<'tcx>( }, ) .unwrap(); - let inline_asm_func = fx - .cx - .module - .declare_func_in_func(inline_asm_func, &mut fx.bcx.func); + let inline_asm_func = fx.cx.module.declare_func_in_func(inline_asm_func, &mut fx.bcx.func); #[cfg(debug_assertions)] fx.add_comment(inline_asm_func, asm_name); for (_reg, offset, value) in inputs { - fx.bcx - .ins() - .stack_store(value, stack_slot, i32::try_from(offset.bytes()).unwrap()); + fx.bcx.ins().stack_store(value, stack_slot, i32::try_from(offset.bytes()).unwrap()); } let stack_slot_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0); @@ -248,10 +222,7 @@ fn call_inline_asm<'tcx>( for (_reg, offset, place) in outputs { let ty = fx.clif_type(place.layout().ty).unwrap(); - let value = fx - .bcx - .ins() - .stack_load(ty, stack_slot, i32::try_from(offset.bytes()).unwrap()); + let value = fx.bcx.ins().stack_load(ty, stack_slot, i32::try_from(offset.bytes()).unwrap()); place.write_cvalue(fx, CValue::by_val(value, place.layout())); } } @@ -267,8 +238,7 @@ fn save_register(generated_asm: &mut String, arch: InlineAsmArch, reg: InlineAsm match arch { InlineAsmArch::X86_64 => { write!(generated_asm, " mov [rbp+0x{:x}], ", offset.bytes()).unwrap(); - reg.emit(generated_asm, InlineAsmArch::X86_64, None) - .unwrap(); + reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap(); generated_asm.push('\n'); } _ => unimplemented!("save_register for {:?}", arch), @@ -284,8 +254,7 @@ fn restore_register( match arch { InlineAsmArch::X86_64 => { generated_asm.push_str(" mov "); - reg.emit(generated_asm, InlineAsmArch::X86_64, None) - .unwrap(); + reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap(); writeln!(generated_asm, ", [rbp+0x{:x}]", offset.bytes()).unwrap(); } _ => unimplemented!("restore_register for {:?}", arch), diff --git a/src/intrinsics/cpuid.rs b/src/intrinsics/cpuid.rs index c1a1cdbe4eb..b27b0eddfba 100644 --- a/src/intrinsics/cpuid.rs +++ b/src/intrinsics/cpuid.rs @@ -6,7 +6,7 @@ use crate::prelude::*; /// /// This emulates an intel cpu with sse and sse2 support, but which doesn't support anything else. pub(crate) fn codegen_cpuid_call<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, leaf: Value, _subleaf: Value, ) -> (Value, Value, Value, Value) { @@ -31,54 +31,28 @@ pub(crate) fn codegen_cpuid_call<'tcx>( fx.bcx.switch_to_block(leaf_0); let max_basic_leaf = fx.bcx.ins().iconst(types::I32, 1); - let vend0 = fx - .bcx - .ins() - .iconst(types::I32, i64::from(u32::from_le_bytes(*b"Genu"))); - let vend2 = fx - .bcx - .ins() - .iconst(types::I32, i64::from(u32::from_le_bytes(*b"ineI"))); - let vend1 = fx - .bcx - .ins() - .iconst(types::I32, i64::from(u32::from_le_bytes(*b"ntel"))); - fx.bcx - .ins() - .jump(dest, &[max_basic_leaf, vend0, vend1, vend2]); + let vend0 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"Genu"))); + let vend2 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"ineI"))); + let vend1 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"ntel"))); + fx.bcx.ins().jump(dest, &[max_basic_leaf, vend0, vend1, vend2]); fx.bcx.switch_to_block(leaf_1); let cpu_signature = fx.bcx.ins().iconst(types::I32, 0); let additional_information = fx.bcx.ins().iconst(types::I32, 0); let ecx_features = fx.bcx.ins().iconst(types::I32, 0); - let edx_features = fx - .bcx - .ins() - .iconst(types::I32, 1 << 25 /* sse */ | 1 << 26 /* sse2 */); - fx.bcx.ins().jump( - dest, - &[ - cpu_signature, - additional_information, - ecx_features, - edx_features, - ], - ); + let edx_features = fx.bcx.ins().iconst(types::I32, 1 << 25 /* sse */ | 1 << 26 /* sse2 */); + fx.bcx.ins().jump(dest, &[cpu_signature, additional_information, ecx_features, edx_features]); fx.bcx.switch_to_block(leaf_8000_0000); let extended_max_basic_leaf = fx.bcx.ins().iconst(types::I32, 0); let zero = fx.bcx.ins().iconst(types::I32, 0); - fx.bcx - .ins() - .jump(dest, &[extended_max_basic_leaf, zero, zero, zero]); + fx.bcx.ins().jump(dest, &[extended_max_basic_leaf, zero, zero, zero]); fx.bcx.switch_to_block(leaf_8000_0001); let zero = fx.bcx.ins().iconst(types::I32, 0); let proc_info_ecx = fx.bcx.ins().iconst(types::I32, 0); let proc_info_edx = fx.bcx.ins().iconst(types::I32, 0); - fx.bcx - .ins() - .jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]); + fx.bcx.ins().jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]); fx.bcx.switch_to_block(unsupported_leaf); crate::trap::trap_unreachable( diff --git a/src/intrinsics/llvm.rs b/src/intrinsics/llvm.rs index d58e4d49958..0692da397eb 100644 --- a/src/intrinsics/llvm.rs +++ b/src/intrinsics/llvm.rs @@ -6,7 +6,7 @@ use crate::prelude::*; use rustc_middle::ty::subst::SubstsRef; pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, intrinsic: &str, substs: SubstsRef<'tcx>, args: &[mir::Operand<'tcx>], diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 8946ac43bc6..39e047a98f9 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -9,6 +9,7 @@ pub(crate) use cpuid::codegen_cpuid_call; pub(crate) use llvm::codegen_llvm_intrinsic_call; use crate::prelude::*; +use cranelift_codegen::ir::AtomicRmwOp; use rustc_middle::ty::print::with_no_trimmed_paths; macro intrinsic_pat { @@ -112,38 +113,6 @@ macro call_intrinsic_match { } } -macro atomic_binop_return_old($fx:expr, $op:ident<$T:ident>($ptr:ident, $src:ident) -> $ret:ident) { - crate::atomic_shim::lock_global_lock($fx); - - let clif_ty = $fx.clif_type($T).unwrap(); - let old = $fx.bcx.ins().load(clif_ty, MemFlags::new(), $ptr, 0); - let new = $fx.bcx.ins().$op(old, $src); - $fx.bcx.ins().store(MemFlags::new(), new, $ptr, 0); - $ret.write_cvalue($fx, CValue::by_val(old, $fx.layout_of($T))); - - crate::atomic_shim::unlock_global_lock($fx); -} - -macro atomic_minmax($fx:expr, $cc:expr, <$T:ident> ($ptr:ident, $src:ident) -> $ret:ident) { - crate::atomic_shim::lock_global_lock($fx); - - // Read old - let clif_ty = $fx.clif_type($T).unwrap(); - let old = $fx.bcx.ins().load(clif_ty, MemFlags::new(), $ptr, 0); - - // Compare - let is_eq = $fx.bcx.ins().icmp(IntCC::SignedGreaterThan, old, $src); - let new = $fx.bcx.ins().select(is_eq, old, $src); - - // Write new - $fx.bcx.ins().store(MemFlags::new(), new, $ptr, 0); - - let ret_val = CValue::by_val(old, $ret.layout()); - $ret.write_cvalue($fx, ret_val); - - crate::atomic_shim::unlock_global_lock($fx); -} - macro validate_atomic_type($fx:ident, $intrinsic:ident, $span:ident, $ty:expr) { match $ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} @@ -184,12 +153,12 @@ pub(crate) fn clif_vector_type<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx } } -fn simd_for_each_lane<'tcx, M: Module>( - fx: &mut FunctionCx<'_, 'tcx, M>, +fn simd_for_each_lane<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, val: CValue<'tcx>, ret: CPlace<'tcx>, f: impl Fn( - &mut FunctionCx<'_, 'tcx, M>, + &mut FunctionCx<'_, '_, 'tcx>, TyAndLayout<'tcx>, TyAndLayout<'tcx>, Value, @@ -213,13 +182,13 @@ fn simd_for_each_lane<'tcx, M: Module>( } } -fn simd_pair_for_each_lane<'tcx, M: Module>( - fx: &mut FunctionCx<'_, 'tcx, M>, +fn simd_pair_for_each_lane<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, x: CValue<'tcx>, y: CValue<'tcx>, ret: CPlace<'tcx>, f: impl Fn( - &mut FunctionCx<'_, 'tcx, M>, + &mut FunctionCx<'_, '_, 'tcx>, TyAndLayout<'tcx>, TyAndLayout<'tcx>, Value, @@ -246,11 +215,11 @@ fn simd_pair_for_each_lane<'tcx, M: Module>( } } -fn simd_reduce<'tcx, M: Module>( - fx: &mut FunctionCx<'_, 'tcx, M>, +fn simd_reduce<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, val: CValue<'tcx>, ret: CPlace<'tcx>, - f: impl Fn(&mut FunctionCx<'_, 'tcx, M>, TyAndLayout<'tcx>, Value, Value) -> Value, + f: impl Fn(&mut FunctionCx<'_, '_, 'tcx>, TyAndLayout<'tcx>, Value, Value) -> Value, ) { let (lane_count, lane_ty) = val.layout().ty.simd_size_and_type(fx.tcx); let lane_layout = fx.layout_of(lane_ty); @@ -258,20 +227,19 @@ fn simd_reduce<'tcx, M: Module>( let mut res_val = val.value_field(fx, mir::Field::new(0)).load_scalar(fx); for lane_idx in 1..lane_count { - let lane = val - .value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())) - .load_scalar(fx); + let lane = + val.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())).load_scalar(fx); res_val = f(fx, lane_layout, res_val, lane); } let res = CValue::by_val(res_val, lane_layout); ret.write_cvalue(fx, res); } -fn simd_reduce_bool<'tcx, M: Module>( - fx: &mut FunctionCx<'_, 'tcx, M>, +fn simd_reduce_bool<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, val: CValue<'tcx>, ret: CPlace<'tcx>, - f: impl Fn(&mut FunctionCx<'_, 'tcx, M>, Value, Value) -> Value, + f: impl Fn(&mut FunctionCx<'_, '_, 'tcx>, Value, Value) -> Value, ) { let (lane_count, _lane_ty) = val.layout().ty.simd_size_and_type(fx.tcx); assert!(ret.layout().ty.is_bool()); @@ -279,9 +247,8 @@ fn simd_reduce_bool<'tcx, M: Module>( let res_val = val.value_field(fx, mir::Field::new(0)).load_scalar(fx); let mut res_val = fx.bcx.ins().band_imm(res_val, 1); // mask to boolean for lane_idx in 1..lane_count { - let lane = val - .value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())) - .load_scalar(fx); + let lane = + val.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())).load_scalar(fx); let lane = fx.bcx.ins().band_imm(lane, 1); // mask to boolean res_val = f(fx, res_val, lane); } @@ -290,7 +257,7 @@ fn simd_reduce_bool<'tcx, M: Module>( } fn bool_to_zero_or_max_uint<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, val: Value, ) -> CValue<'tcx> { @@ -424,7 +391,7 @@ macro simd_flt_binop($fx:expr, $op:ident($x:ident, $y:ident) -> $ret:ident) { } pub(crate) fn codegen_intrinsic_call<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, instance: Instance<'tcx>, args: &[mir::Operand<'tcx>], destination: Option<(CPlace<'tcx>, BasicBlock)>, @@ -912,136 +879,175 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( }; _ if intrinsic.starts_with("atomic_fence"), () { - crate::atomic_shim::lock_global_lock(fx); - crate::atomic_shim::unlock_global_lock(fx); + fx.bcx.ins().fence(); }; _ if intrinsic.starts_with("atomic_singlethreadfence"), () { - crate::atomic_shim::lock_global_lock(fx); - crate::atomic_shim::unlock_global_lock(fx); + // FIXME use a compiler fence once Cranelift supports it + fx.bcx.ins().fence(); }; - _ if intrinsic.starts_with("atomic_load"), (c ptr) { - crate::atomic_shim::lock_global_lock(fx); + _ if intrinsic.starts_with("atomic_load"), (v ptr) { + validate_atomic_type!(fx, intrinsic, span, T); + let ty = fx.clif_type(T).unwrap(); - let inner_layout = - fx.layout_of(ptr.layout().ty.builtin_deref(true).unwrap().ty); - validate_atomic_type!(fx, intrinsic, span, inner_layout.ty); - let val = CValue::by_ref(Pointer::new(ptr.load_scalar(fx)), inner_layout); + let val = fx.bcx.ins().atomic_load(ty, MemFlags::trusted(), ptr); + + let val = CValue::by_val(val, fx.layout_of(T)); ret.write_cvalue(fx, val); - - crate::atomic_shim::unlock_global_lock(fx); }; _ if intrinsic.starts_with("atomic_store"), (v ptr, c val) { validate_atomic_type!(fx, intrinsic, span, val.layout().ty); - crate::atomic_shim::lock_global_lock(fx); + let val = val.load_scalar(fx); - let dest = CPlace::for_ptr(Pointer::new(ptr), val.layout()); - dest.write_cvalue(fx, val); - - crate::atomic_shim::unlock_global_lock(fx); + fx.bcx.ins().atomic_store(MemFlags::trusted(), val, ptr); }; - _ if intrinsic.starts_with("atomic_xchg"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, T); + _ if intrinsic.starts_with("atomic_xchg"), (v ptr, c new) { + let layout = new.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); - crate::atomic_shim::lock_global_lock(fx); + let new = new.load_scalar(fx); - // Read old - let clif_ty = fx.clif_type(T).unwrap(); - let old = fx.bcx.ins().load(clif_ty, MemFlags::new(), ptr, 0); - ret.write_cvalue(fx, CValue::by_val(old, fx.layout_of(T))); + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Xchg, ptr, new); - // Write new - let dest = CPlace::for_ptr(Pointer::new(ptr), src.layout()); - dest.write_cvalue(fx, src); - - crate::atomic_shim::unlock_global_lock(fx); + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_cxchg"), (v ptr, c test_old, c new) { // both atomic_cxchg_* and atomic_cxchgweak_* - validate_atomic_type!(fx, intrinsic, span, T); + _ if intrinsic.starts_with("atomic_cxchg"), (v ptr, c test_old, c new) { // both atomic_cxchg_* and atomic_cxchgweak_* + let layout = new.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); let test_old = test_old.load_scalar(fx); let new = new.load_scalar(fx); - crate::atomic_shim::lock_global_lock(fx); - - // Read old - let clif_ty = fx.clif_type(T).unwrap(); - let old = fx.bcx.ins().load(clif_ty, MemFlags::new(), ptr, 0); - - // Compare + let old = fx.bcx.ins().atomic_cas(MemFlags::trusted(), ptr, test_old, new); let is_eq = fx.bcx.ins().icmp(IntCC::Equal, old, test_old); - let new = fx.bcx.ins().select(is_eq, new, old); // Keep old if not equal to test_old - - // Write new - fx.bcx.ins().store(MemFlags::new(), new, ptr, 0); let ret_val = CValue::by_val_pair(old, fx.bcx.ins().bint(types::I8, is_eq), ret.layout()); - ret.write_cvalue(fx, ret_val); - - crate::atomic_shim::unlock_global_lock(fx); + ret.write_cvalue(fx, ret_val) }; - _ if intrinsic.starts_with("atomic_xadd"), (v ptr, c amount) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + _ if intrinsic.starts_with("atomic_xadd"), (v ptr, c amount) { + let layout = amount.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let amount = amount.load_scalar(fx); - atomic_binop_return_old! (fx, iadd(ptr, amount) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Add, ptr, amount); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_xsub"), (v ptr, c amount) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + _ if intrinsic.starts_with("atomic_xsub"), (v ptr, c amount) { + let layout = amount.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let amount = amount.load_scalar(fx); - atomic_binop_return_old! (fx, isub(ptr, amount) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Sub, ptr, amount); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_and"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); - let src = src.load_scalar(fx); - atomic_binop_return_old! (fx, band(ptr, src) -> ret); - }; - _ if intrinsic.starts_with("atomic_nand"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, T); + _ if intrinsic.starts_with("atomic_and"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); let src = src.load_scalar(fx); - crate::atomic_shim::lock_global_lock(fx); + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::And, ptr, src); - let clif_ty = fx.clif_type(T).unwrap(); - let old = fx.bcx.ins().load(clif_ty, MemFlags::new(), ptr, 0); - let and = fx.bcx.ins().band(old, src); - let new = fx.bcx.ins().bnot(and); - fx.bcx.ins().store(MemFlags::new(), new, ptr, 0); - ret.write_cvalue(fx, CValue::by_val(old, fx.layout_of(T))); + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); + }; + _ if intrinsic.starts_with("atomic_or"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); - crate::atomic_shim::unlock_global_lock(fx); - }; - _ if intrinsic.starts_with("atomic_or"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); let src = src.load_scalar(fx); - atomic_binop_return_old! (fx, bor(ptr, src) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Or, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_xor"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + _ if intrinsic.starts_with("atomic_xor"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let src = src.load_scalar(fx); - atomic_binop_return_old! (fx, bxor(ptr, src) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Xor, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_max"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + // FIXME https://github.com/bytecodealliance/wasmtime/issues/2647 + _ if intrinsic.starts_with("atomic_nand"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let src = src.load_scalar(fx); - atomic_minmax!(fx, IntCC::SignedGreaterThan, (ptr, src) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Nand, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_umax"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + _ if intrinsic.starts_with("atomic_max"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let src = src.load_scalar(fx); - atomic_minmax!(fx, IntCC::UnsignedGreaterThan, (ptr, src) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Smax, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_min"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + _ if intrinsic.starts_with("atomic_umax"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let src = src.load_scalar(fx); - atomic_minmax!(fx, IntCC::SignedLessThan, (ptr, src) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Umax, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_umin"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + _ if intrinsic.starts_with("atomic_min"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let src = src.load_scalar(fx); - atomic_minmax!(fx, IntCC::UnsignedLessThan, (ptr, src) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Smin, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); + }; + _ if intrinsic.starts_with("atomic_umin"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + + let src = src.load_scalar(fx); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Umin, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; minnumf32, (v a, v b) { diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index e0eb5c59590..1f8eeb1e714 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -4,7 +4,7 @@ use super::*; use crate::prelude::*; pub(super) fn codegen_simd_intrinsic_call<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, instance: Instance<'tcx>, args: &[mir::Operand<'tcx>], ret: CPlace<'tcx>, diff --git a/src/lib.rs b/src/lib.rs index 1480ab25133..e1927ad3a69 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,8 +11,6 @@ #![warn(unused_lifetimes)] #![warn(unreachable_pub)] -#[cfg(feature = "jit")] -extern crate libc; extern crate snap; #[macro_use] extern crate rustc_middle; @@ -53,7 +51,6 @@ mod abi; mod allocator; mod analyze; mod archive; -mod atomic_shim; mod backend; mod base; mod cast; @@ -129,9 +126,9 @@ impl String> Drop for PrintOnPanic { } } -struct CodegenCx<'tcx, M: Module> { +struct CodegenCx<'m, 'tcx: 'm> { tcx: TyCtxt<'tcx>, - module: M, + module: &'m mut dyn Module, global_asm: String, constants_cx: ConstantCx, cached_context: Context, @@ -140,14 +137,20 @@ struct CodegenCx<'tcx, M: Module> { unwind_context: UnwindContext<'tcx>, } -impl<'tcx, M: Module> CodegenCx<'tcx, M> { - fn new(tcx: TyCtxt<'tcx>, module: M, debug_info: bool, pic_eh_frame: bool) -> Self { - let unwind_context = UnwindContext::new(tcx, module.isa(), pic_eh_frame); - let debug_context = if debug_info { - Some(DebugContext::new(tcx, module.isa())) - } else { - None - }; +impl<'m, 'tcx> CodegenCx<'m, 'tcx> { + fn new( + tcx: TyCtxt<'tcx>, + backend_config: BackendConfig, + module: &'m mut dyn Module, + debug_info: bool, + ) -> Self { + let unwind_context = UnwindContext::new( + tcx, + module.isa(), + matches!(backend_config.codegen_mode, CodegenMode::Aot), + ); + let debug_context = + if debug_info { Some(DebugContext::new(tcx, module.isa())) } else { None }; CodegenCx { tcx, module, @@ -160,14 +163,9 @@ impl<'tcx, M: Module> CodegenCx<'tcx, M> { } } - fn finalize(mut self) -> (M, String, Option>, UnwindContext<'tcx>) { - self.constants_cx.finalize(self.tcx, &mut self.module); - ( - self.module, - self.global_asm, - self.debug_context, - self.unwind_context, - ) + fn finalize(self) -> (String, Option>, UnwindContext<'tcx>) { + self.constants_cx.finalize(self.tcx, self.module); + (self.global_asm, self.debug_context, self.unwind_context) } } @@ -302,14 +300,7 @@ fn build_isa(sess: &Session) -> Box { flags_builder.enable("is_pic").unwrap(); flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided flags_builder - .set( - "enable_verifier", - if cfg!(debug_assertions) { - "true" - } else { - "false" - }, - ) + .set("enable_verifier", if cfg!(debug_assertions) { "true" } else { "false" }) .unwrap(); let tls_model = match target_triple.binary_format { @@ -338,11 +329,7 @@ fn build_isa(sess: &Session) -> Box { let flags = settings::Flags::new(flags_builder); - let variant = if cfg!(feature = "oldbe") { - cranelift_codegen::isa::BackendVariant::Legacy - } else { - cranelift_codegen::isa::BackendVariant::MachInst - }; + let variant = cranelift_codegen::isa::BackendVariant::MachInst; let mut isa_builder = cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap(); // Don't use "haswell", as it implies `has_lzcnt`.macOS CI is still at Ivy Bridge EP, so `lzcnt` // is interpreted as `bsr`. diff --git a/src/main_shim.rs b/src/main_shim.rs index b193cea877d..62e551b186f 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -9,7 +9,6 @@ pub(crate) fn maybe_create_entry_wrapper( tcx: TyCtxt<'_>, module: &mut impl Module, unwind_context: &mut UnwindContext<'_>, - use_jit: bool, ) { let (main_def_id, use_start_lang_item) = match tcx.entry_fn(LOCAL_CRATE) { Some((def_id, entry_ty)) => ( @@ -27,14 +26,7 @@ pub(crate) fn maybe_create_entry_wrapper( return; } - create_entry_fn( - tcx, - module, - unwind_context, - main_def_id, - use_start_lang_item, - use_jit, - ); + create_entry_fn(tcx, module, unwind_context, main_def_id, use_start_lang_item); fn create_entry_fn( tcx: TyCtxt<'_>, @@ -42,7 +34,6 @@ pub(crate) fn maybe_create_entry_wrapper( unwind_context: &mut UnwindContext<'_>, rust_main_def_id: DefId, use_start_lang_item: bool, - use_jit: bool, ) { let main_ret_ty = tcx.fn_sig(rust_main_def_id).output(); // Given that `main()` has no arguments, @@ -57,23 +48,17 @@ pub(crate) fn maybe_create_entry_wrapper( AbiParam::new(m.target_config().pointer_type()), AbiParam::new(m.target_config().pointer_type()), ], - returns: vec![AbiParam::new( - m.target_config().pointer_type(), /*isize*/ - )], + returns: vec![AbiParam::new(m.target_config().pointer_type() /*isize*/)], call_conv: CallConv::triple_default(m.isa().triple()), }; - let cmain_func_id = m - .declare_function("main", Linkage::Export, &cmain_sig) - .unwrap(); + let cmain_func_id = m.declare_function("main", Linkage::Export, &cmain_sig).unwrap(); let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx); let main_name = tcx.symbol_name(instance).name.to_string(); let main_sig = get_function_sig(tcx, m.isa().triple(), instance); - let main_func_id = m - .declare_function(&main_name, Linkage::Import, &main_sig) - .unwrap(); + let main_func_id = m.declare_function(&main_name, Linkage::Import, &main_sig).unwrap(); let mut ctx = Context::new(); ctx.func = Function::with_name_signature(ExternalName::user(0, 0), cmain_sig); @@ -86,8 +71,6 @@ pub(crate) fn maybe_create_entry_wrapper( let arg_argc = bcx.append_block_param(block, m.target_config().pointer_type()); let arg_argv = bcx.append_block_param(block, m.target_config().pointer_type()); - crate::atomic_shim::init_global_lock(m, &mut bcx, use_jit); - let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func); let call_inst = if use_start_lang_item { @@ -103,9 +86,7 @@ pub(crate) fn maybe_create_entry_wrapper( .polymorphize(tcx); let start_func_id = import_function(tcx, m, start_instance); - let main_val = bcx - .ins() - .func_addr(m.target_config().pointer_type(), main_func_ref); + let main_val = bcx.ins().func_addr(m.target_config().pointer_type(), main_func_ref); let func_ref = m.declare_func_in_func(start_func_id, &mut bcx.func); bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv]) diff --git a/src/metadata.rs b/src/metadata.rs index 2e3b9fb8364..190c4f45cca 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -94,9 +94,7 @@ pub(crate) fn write_metadata( assert!(kind == MetadataKind::Compressed); let mut compressed = tcx.metadata_encoding_version(); - FrameEncoder::new(&mut compressed) - .write_all(&metadata.raw_data) - .unwrap(); + FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap(); product.add_rustc_section( rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx), diff --git a/src/num.rs b/src/num.rs index d1d2b3b872a..da49e1c6c91 100644 --- a/src/num.rs +++ b/src/num.rs @@ -41,7 +41,7 @@ pub(crate) fn bin_op_to_intcc(bin_op: BinOp, signed: bool) -> Option { } fn codegen_compare_bin_op<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, signed: bool, lhs: Value, @@ -54,7 +54,7 @@ fn codegen_compare_bin_op<'tcx>( } pub(crate) fn codegen_binop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, @@ -93,17 +93,12 @@ pub(crate) fn codegen_binop<'tcx>( ty::Uint(_) | ty::Int(_) => crate::num::codegen_int_binop(fx, bin_op, in_lhs, in_rhs), ty::Float(_) => crate::num::codegen_float_binop(fx, bin_op, in_lhs, in_rhs), ty::RawPtr(..) | ty::FnPtr(..) => crate::num::codegen_ptr_binop(fx, bin_op, in_lhs, in_rhs), - _ => unreachable!( - "{:?}({:?}, {:?})", - bin_op, - in_lhs.layout().ty, - in_rhs.layout().ty - ), + _ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty), } } pub(crate) fn codegen_bool_binop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, @@ -124,7 +119,7 @@ pub(crate) fn codegen_bool_binop<'tcx>( } pub(crate) fn codegen_int_binop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, @@ -185,19 +180,14 @@ pub(crate) fn codegen_int_binop<'tcx>( } } // Compare binops handles by `codegen_binop`. - _ => unreachable!( - "{:?}({:?}, {:?})", - bin_op, - in_lhs.layout().ty, - in_rhs.layout().ty - ), + _ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty), }; CValue::by_val(val, in_lhs.layout()) } pub(crate) fn codegen_checked_int_binop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, @@ -268,9 +258,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( let rhs = fx.bcx.ins().sextend(ty.double_width().unwrap(), rhs); let val = fx.bcx.ins().imul(lhs, rhs); let has_underflow = - fx.bcx - .ins() - .icmp_imm(IntCC::SignedLessThan, val, -(1 << (ty.bits() - 1))); + fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, val, -(1 << (ty.bits() - 1))); let has_overflow = fx.bcx.ins().icmp_imm( IntCC::SignedGreaterThan, val, @@ -309,10 +297,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( let val = fx.bcx.ins().ishl(lhs, actual_shift); let ty = fx.bcx.func.dfg.value_type(val); let max_shift = i64::from(ty.bits()) - 1; - let has_overflow = fx - .bcx - .ins() - .icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift); + let has_overflow = fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift); (val, has_overflow) } BinOp::Shr => { @@ -326,38 +311,20 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( }; let ty = fx.bcx.func.dfg.value_type(val); let max_shift = i64::from(ty.bits()) - 1; - let has_overflow = fx - .bcx - .ins() - .icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift); + let has_overflow = fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift); (val, has_overflow) } - _ => bug!( - "binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", - bin_op, - in_lhs, - in_rhs - ), + _ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs), }; let has_overflow = fx.bcx.ins().bint(types::I8, has_overflow); - // FIXME directly write to result place instead - let out_place = CPlace::new_stack_slot( - fx, - fx.layout_of( - fx.tcx - .mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter()), - ), - ); - let out_layout = out_place.layout(); - out_place.write_cvalue(fx, CValue::by_val_pair(res, has_overflow, out_layout)); - - out_place.to_cvalue(fx) + let out_layout = fx.layout_of(fx.tcx.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter())); + CValue::by_val_pair(res, has_overflow, out_layout) } pub(crate) fn codegen_float_binop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, @@ -402,7 +369,7 @@ pub(crate) fn codegen_float_binop<'tcx>( } pub(crate) fn codegen_ptr_binop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, @@ -452,9 +419,7 @@ pub(crate) fn codegen_ptr_binop<'tcx>( let ptr_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_ptr, rhs_ptr); let ptr_cmp = - fx.bcx - .ins() - .icmp(bin_op_to_intcc(bin_op, false).unwrap(), lhs_ptr, rhs_ptr); + fx.bcx.ins().icmp(bin_op_to_intcc(bin_op, false).unwrap(), lhs_ptr, rhs_ptr); let extra_cmp = fx.bcx.ins().icmp( bin_op_to_intcc(bin_op, false).unwrap(), lhs_extra, @@ -466,9 +431,6 @@ pub(crate) fn codegen_ptr_binop<'tcx>( _ => panic!("bin_op {:?} on ptr", bin_op), }; - CValue::by_val( - fx.bcx.ins().bint(types::I8, res), - fx.layout_of(fx.tcx.types.bool), - ) + CValue::by_val(fx.bcx.ins().bint(types::I8, res), fx.layout_of(fx.tcx.types.bool)) } } diff --git a/src/optimize/code_layout.rs b/src/optimize/code_layout.rs index f02732014d1..ca9ff15ec10 100644 --- a/src/optimize/code_layout.rs +++ b/src/optimize/code_layout.rs @@ -15,10 +15,7 @@ pub(super) fn optimize_function(ctx: &mut Context, cold_blocks: &EntitySet>(); for &inst in &insts { ctx.func.layout.remove_inst(inst); @@ -28,10 +25,7 @@ pub(super) fn optimize_function(ctx: &mut Context, cold_blocks: &EntitySet( if tcx.sess.opts.optimize == rustc_session::config::OptLevel::No { return; // FIXME classify optimizations over opt levels } - self::stack2reg::optimize_function(ctx, clif_comments); + + // FIXME(#1142) stack2reg miscompiles lewton + if false { + self::stack2reg::optimize_function(ctx, clif_comments); + } + crate::pretty_clif::write_clif_file(tcx, "stack2reg", None, instance, &ctx, &*clif_comments); crate::base::verify_func(tcx, &*clif_comments, &ctx.func); } diff --git a/src/optimize/peephole.rs b/src/optimize/peephole.rs index a575ed8dc35..b95e2d72877 100644 --- a/src/optimize/peephole.rs +++ b/src/optimize/peephole.rs @@ -10,10 +10,7 @@ use cranelift_frontend::FunctionBuilder; pub(crate) fn maybe_unwrap_bint(bcx: &mut FunctionBuilder<'_>, arg: Value) -> Value { if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) { match bcx.func.dfg[arg_inst] { - InstructionData::Unary { - opcode: Opcode::Bint, - arg, - } => arg, + InstructionData::Unary { opcode: Opcode::Bint, arg } => arg, _ => arg, } } else { @@ -54,12 +51,7 @@ pub(crate) fn make_branchable_value(bcx: &mut FunctionBuilder<'_>, arg: Value) - match bcx.func.dfg[arg_inst] { // This is the lowering of Rvalue::Not - InstructionData::Load { - opcode: Opcode::Load, - arg: ptr, - flags, - offset, - } => { + InstructionData::Load { opcode: Opcode::Load, arg: ptr, flags, offset } => { // Using `load.i8 + uextend.i32` would legalize to `uload8 + ireduce.i8 + // uextend.i32`. Just `uload8` is much faster. match bcx.func.dfg.ctrl_typevar(arg_inst) { @@ -95,20 +87,14 @@ pub(crate) fn maybe_known_branch_taken( }; match bcx.func.dfg[arg_inst] { - InstructionData::UnaryBool { - opcode: Opcode::Bconst, - imm, - } => { + InstructionData::UnaryBool { opcode: Opcode::Bconst, imm } => { if test_zero { Some(!imm) } else { Some(imm) } } - InstructionData::UnaryImm { - opcode: Opcode::Iconst, - imm, - } => { + InstructionData::UnaryImm { opcode: Opcode::Iconst, imm } => { if test_zero { Some(imm.bits() == 0) } else { diff --git a/src/optimize/stack2reg.rs b/src/optimize/stack2reg.rs index 3c939d5a586..d111f37f5e4 100644 --- a/src/optimize/stack2reg.rs +++ b/src/optimize/stack2reg.rs @@ -175,16 +175,14 @@ impl<'a> OptimizeContext<'a> { } } - OptimizeContext { - ctx, - stack_slot_usage_map, - } + OptimizeContext { ctx, stack_slot_usage_map } } } pub(super) fn optimize_function( ctx: &mut Context, - #[cfg_attr(not(debug_assertions), allow(unused_variables))] clif_comments: &mut crate::pretty_clif::CommentWriter, + #[cfg_attr(not(debug_assertions), allow(unused_variables))] + clif_comments: &mut crate::pretty_clif::CommentWriter, ) { combine_stack_addr_with_load_store(&mut ctx.func); @@ -296,12 +294,7 @@ fn combine_stack_addr_with_load_store(func: &mut Function) { while let Some(_block) = cursor.next_block() { while let Some(inst) = cursor.next_inst() { match cursor.func.dfg[inst] { - InstructionData::Load { - opcode: Opcode::Load, - arg: addr, - flags: _, - offset, - } => { + InstructionData::Load { opcode: Opcode::Load, arg: addr, flags: _, offset } => { if cursor.func.dfg.ctrl_typevar(inst) == types::I128 || cursor.func.dfg.ctrl_typevar(inst).is_vector() { @@ -391,20 +384,14 @@ fn remove_unused_stack_addr_and_stack_load(opt_ctx: &mut OptimizeContext<'_>) { stack_slot_users .stack_addr .drain_filter(|inst| { - stack_addr_load_insts_users - .get(inst) - .map(|users| users.is_empty()) - .unwrap_or(true) + stack_addr_load_insts_users.get(inst).map(|users| users.is_empty()).unwrap_or(true) }) .for_each(|inst| StackSlotUsage::remove_unused_stack_addr(&mut func, inst)); stack_slot_users .stack_load .drain_filter(|inst| { - stack_addr_load_insts_users - .get(inst) - .map(|users| users.is_empty()) - .unwrap_or(true) + stack_addr_load_insts_users.get(inst).map(|users| users.is_empty()).unwrap_or(true) }) .for_each(|inst| StackSlotUsage::remove_unused_load(&mut func, inst)); } @@ -415,11 +402,8 @@ fn try_get_stack_slot_and_offset_for_addr( addr: Value, ) -> Option<(StackSlot, Offset32)> { if let ValueDef::Result(addr_inst, 0) = func.dfg.value_def(addr) { - if let InstructionData::StackLoad { - opcode: Opcode::StackAddr, - stack_slot, - offset, - } = func.dfg[addr_inst] + if let InstructionData::StackLoad { opcode: Opcode::StackAddr, stack_slot, offset } = + func.dfg[addr_inst] { return Some((stack_slot, offset)); } @@ -437,16 +421,8 @@ enum SpatialOverlap { fn spatial_overlap(func: &Function, src: Inst, dest: Inst) -> SpatialOverlap { fn inst_info(func: &Function, inst: Inst) -> (StackSlot, Offset32, u32) { match func.dfg[inst] { - InstructionData::StackLoad { - opcode: Opcode::StackAddr, - stack_slot, - offset, - } - | InstructionData::StackLoad { - opcode: Opcode::StackLoad, - stack_slot, - offset, - } + InstructionData::StackLoad { opcode: Opcode::StackAddr, stack_slot, offset } + | InstructionData::StackLoad { opcode: Opcode::StackLoad, stack_slot, offset } | InstructionData::StackStore { opcode: Opcode::StackStore, stack_slot, @@ -471,10 +447,7 @@ fn spatial_overlap(func: &Function, src: Inst, dest: Inst) -> SpatialOverlap { } let src_end: i64 = src_offset.try_add_i64(i64::from(src_size)).unwrap().into(); - let dest_end: i64 = dest_offset - .try_add_i64(i64::from(dest_size)) - .unwrap() - .into(); + let dest_end: i64 = dest_offset.try_add_i64(i64::from(dest_size)).unwrap().into(); if src_end <= dest_offset.into() || dest_end <= src_offset.into() { return SpatialOverlap::No; } diff --git a/src/pointer.rs b/src/pointer.rs index b2036d7bcd4..88a78f3214d 100644 --- a/src/pointer.rs +++ b/src/pointer.rs @@ -23,35 +23,20 @@ pub(crate) enum PointerBase { impl Pointer { pub(crate) fn new(addr: Value) -> Self { - Pointer { - base: PointerBase::Addr(addr), - offset: Offset32::new(0), - } + Pointer { base: PointerBase::Addr(addr), offset: Offset32::new(0) } } pub(crate) fn stack_slot(stack_slot: StackSlot) -> Self { - Pointer { - base: PointerBase::Stack(stack_slot), - offset: Offset32::new(0), - } + Pointer { base: PointerBase::Stack(stack_slot), offset: Offset32::new(0) } } - pub(crate) fn const_addr<'a, 'tcx>( - fx: &mut FunctionCx<'a, 'tcx, impl Module>, - addr: i64, - ) -> Self { + pub(crate) fn const_addr(fx: &mut FunctionCx<'_, '_, '_>, addr: i64) -> Self { let addr = fx.bcx.ins().iconst(fx.pointer_type, addr); - Pointer { - base: PointerBase::Addr(addr), - offset: Offset32::new(0), - } + Pointer { base: PointerBase::Addr(addr), offset: Offset32::new(0) } } pub(crate) fn dangling(align: Align) -> Self { - Pointer { - base: PointerBase::Dangling(align), - offset: Offset32::new(0), - } + Pointer { base: PointerBase::Dangling(align), offset: Offset32::new(0) } } #[cfg(debug_assertions)] @@ -59,46 +44,28 @@ impl Pointer { (self.base, self.offset) } - pub(crate) fn get_addr<'a, 'tcx>(self, fx: &mut FunctionCx<'a, 'tcx, impl Module>) -> Value { + pub(crate) fn get_addr(self, fx: &mut FunctionCx<'_, '_, '_>) -> Value { match self.base { PointerBase::Addr(base_addr) => { let offset: i64 = self.offset.into(); - if offset == 0 { - base_addr - } else { - fx.bcx.ins().iadd_imm(base_addr, offset) - } + if offset == 0 { base_addr } else { fx.bcx.ins().iadd_imm(base_addr, offset) } } PointerBase::Stack(stack_slot) => { - fx.bcx - .ins() - .stack_addr(fx.pointer_type, stack_slot, self.offset) + fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, self.offset) + } + PointerBase::Dangling(align) => { + fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()) } - PointerBase::Dangling(align) => fx - .bcx - .ins() - .iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()), } } - pub(crate) fn offset<'a, 'tcx>( - self, - fx: &mut FunctionCx<'a, 'tcx, impl Module>, - extra_offset: Offset32, - ) -> Self { + pub(crate) fn offset(self, fx: &mut FunctionCx<'_, '_, '_>, extra_offset: Offset32) -> Self { self.offset_i64(fx, extra_offset.into()) } - pub(crate) fn offset_i64<'a, 'tcx>( - self, - fx: &mut FunctionCx<'a, 'tcx, impl Module>, - extra_offset: i64, - ) -> Self { + pub(crate) fn offset_i64(self, fx: &mut FunctionCx<'_, '_, '_>, extra_offset: i64) -> Self { if let Some(new_offset) = self.offset.try_add_i64(extra_offset) { - Pointer { - base: self.base, - offset: new_offset, - } + Pointer { base: self.base, offset: new_offset } } else { let base_offset: i64 = self.offset.into(); if let Some(new_offset) = base_offset.checked_add(extra_offset) { @@ -107,16 +74,12 @@ impl Pointer { PointerBase::Stack(stack_slot) => { fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0) } - PointerBase::Dangling(align) => fx - .bcx - .ins() - .iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()), + PointerBase::Dangling(align) => { + fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()) + } }; let addr = fx.bcx.ins().iadd_imm(base_addr, new_offset); - Pointer { - base: PointerBase::Addr(addr), - offset: Offset32::new(0), - } + Pointer { base: PointerBase::Addr(addr), offset: Offset32::new(0) } } else { panic!( "self.offset ({}) + extra_offset ({}) not representable in i64", @@ -126,31 +89,22 @@ impl Pointer { } } - pub(crate) fn offset_value<'a, 'tcx>( - self, - fx: &mut FunctionCx<'a, 'tcx, impl Module>, - extra_offset: Value, - ) -> Self { + pub(crate) fn offset_value(self, fx: &mut FunctionCx<'_, '_, '_>, extra_offset: Value) -> Self { match self.base { PointerBase::Addr(addr) => Pointer { base: PointerBase::Addr(fx.bcx.ins().iadd(addr, extra_offset)), offset: self.offset, }, PointerBase::Stack(stack_slot) => { - let base_addr = fx - .bcx - .ins() - .stack_addr(fx.pointer_type, stack_slot, self.offset); + let base_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, self.offset); Pointer { base: PointerBase::Addr(fx.bcx.ins().iadd(base_addr, extra_offset)), offset: Offset32::new(0), } } PointerBase::Dangling(align) => { - let addr = fx - .bcx - .ins() - .iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()); + let addr = + fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()); Pointer { base: PointerBase::Addr(fx.bcx.ins().iadd(addr, extra_offset)), offset: self.offset, @@ -159,46 +113,21 @@ impl Pointer { } } - pub(crate) fn load<'a, 'tcx>( - self, - fx: &mut FunctionCx<'a, 'tcx, impl Module>, - ty: Type, - flags: MemFlags, - ) -> Value { + pub(crate) fn load(self, fx: &mut FunctionCx<'_, '_, '_>, ty: Type, flags: MemFlags) -> Value { match self.base { PointerBase::Addr(base_addr) => fx.bcx.ins().load(ty, flags, base_addr, self.offset), - PointerBase::Stack(stack_slot) => { - if ty == types::I128 || ty.is_vector() { - // WORKAROUND for stack_load.i128 and stack_load.iXxY not being implemented - let base_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0); - fx.bcx.ins().load(ty, flags, base_addr, self.offset) - } else { - fx.bcx.ins().stack_load(ty, stack_slot, self.offset) - } - } + PointerBase::Stack(stack_slot) => fx.bcx.ins().stack_load(ty, stack_slot, self.offset), PointerBase::Dangling(_align) => unreachable!(), } } - pub(crate) fn store<'a, 'tcx>( - self, - fx: &mut FunctionCx<'a, 'tcx, impl Module>, - value: Value, - flags: MemFlags, - ) { + pub(crate) fn store(self, fx: &mut FunctionCx<'_, '_, '_>, value: Value, flags: MemFlags) { match self.base { PointerBase::Addr(base_addr) => { fx.bcx.ins().store(flags, value, base_addr, self.offset); } PointerBase::Stack(stack_slot) => { - let val_ty = fx.bcx.func.dfg.value_type(value); - if val_ty == types::I128 || val_ty.is_vector() { - // WORKAROUND for stack_store.i128 and stack_store.iXxY not being implemented - let base_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0); - fx.bcx.ins().store(flags, value, base_addr, self.offset); - } else { - fx.bcx.ins().stack_store(value, stack_slot, self.offset); - } + fx.bcx.ins().stack_store(value, stack_slot, self.offset); } PointerBase::Dangling(_align) => unreachable!(), } diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index f4a15ab12d5..9c91b92e515 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -79,20 +79,14 @@ impl CommentWriter { vec![ format!("symbol {}", tcx.symbol_name(instance).name), format!("instance {:?}", instance), - format!( - "abi {:?}", - FnAbi::of_instance(&RevealAllLayoutCx(tcx), instance, &[]) - ), + format!("abi {:?}", FnAbi::of_instance(&RevealAllLayoutCx(tcx), instance, &[])), String::new(), ] } else { vec![] }; - CommentWriter { - global_comments, - entity_comments: FxHashMap::default(), - } + CommentWriter { global_comments, entity_comments: FxHashMap::default() } } } @@ -186,7 +180,7 @@ impl FuncWriter for &'_ CommentWriter { } #[cfg(debug_assertions)] -impl FunctionCx<'_, '_, M> { +impl FunctionCx<'_, '_, '_> { pub(crate) fn add_global_comment>(&mut self, comment: S) { self.clif_comments.add_global_comment(comment); } @@ -201,12 +195,7 @@ impl FunctionCx<'_, '_, M> { } pub(crate) fn should_write_ir(tcx: TyCtxt<'_>) -> bool { - cfg!(debug_assertions) - || tcx - .sess - .opts - .output_types - .contains_key(&OutputType::LlvmAssembly) + tcx.sess.opts.output_types.contains_key(&OutputType::LlvmAssembly) } pub(crate) fn write_ir_file<'tcx>( @@ -245,40 +234,33 @@ pub(crate) fn write_clif_file<'tcx>( context: &cranelift_codegen::Context, mut clif_comments: &CommentWriter, ) { - write_ir_file( - tcx, - &format!("{}.{}.clif", tcx.symbol_name(instance).name, postfix), - |file| { - let value_ranges = isa.map(|isa| { - context - .build_value_labels_ranges(isa) - .expect("value location ranges") - }); + write_ir_file(tcx, &format!("{}.{}.clif", tcx.symbol_name(instance).name, postfix), |file| { + let value_ranges = + isa.map(|isa| context.build_value_labels_ranges(isa).expect("value location ranges")); - let mut clif = String::new(); - cranelift_codegen::write::decorate_function( - &mut clif_comments, - &mut clif, - &context.func, - &DisplayFunctionAnnotations { - isa: Some(&*crate::build_isa(tcx.sess)), - value_ranges: value_ranges.as_ref(), - }, - ) - .unwrap(); + let mut clif = String::new(); + cranelift_codegen::write::decorate_function( + &mut clif_comments, + &mut clif, + &context.func, + &DisplayFunctionAnnotations { + isa: Some(&*crate::build_isa(tcx.sess)), + value_ranges: value_ranges.as_ref(), + }, + ) + .unwrap(); - writeln!(file, "test compile")?; - writeln!(file, "set is_pic")?; - writeln!(file, "set enable_simd")?; - writeln!(file, "target {} haswell", crate::target_triple(tcx.sess))?; - writeln!(file)?; - file.write_all(clif.as_bytes())?; - Ok(()) - }, - ); + writeln!(file, "test compile")?; + writeln!(file, "set is_pic")?; + writeln!(file, "set enable_simd")?; + writeln!(file, "target {} haswell", crate::target_triple(tcx.sess))?; + writeln!(file)?; + file.write_all(clif.as_bytes())?; + Ok(()) + }); } -impl fmt::Debug for FunctionCx<'_, '_, M> { +impl fmt::Debug for FunctionCx<'_, '_, '_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(f, "{:?}", self.instance.substs)?; writeln!(f, "{:?}", self.local_map)?; diff --git a/src/toolchain.rs b/src/toolchain.rs index 735c59d70c1..484a9b699a0 100644 --- a/src/toolchain.rs +++ b/src/toolchain.rs @@ -71,12 +71,9 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { flavor, )), (Some(linker), None) => { - let stem = linker - .file_stem() - .and_then(|stem| stem.to_str()) - .unwrap_or_else(|| { - sess.fatal("couldn't extract file stem from specified linker") - }); + let stem = linker.file_stem().and_then(|stem| stem.to_str()).unwrap_or_else(|| { + sess.fatal("couldn't extract file stem from specified linker") + }); let flavor = if stem == "emcc" { LinkerFlavor::Em @@ -105,11 +102,7 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { // linker and linker flavor specified via command line have precedence over what the target // specification specifies - if let Some(ret) = infer_from( - sess, - sess.opts.cg.linker.clone(), - sess.opts.cg.linker_flavor, - ) { + if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), sess.opts.cg.linker_flavor) { return ret; } diff --git a/src/trap.rs b/src/trap.rs index 67495c74148..bb63d72addf 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -2,7 +2,7 @@ use crate::prelude::*; -fn codegen_print(fx: &mut FunctionCx<'_, '_, impl Module>, msg: &str) { +fn codegen_print(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) { let puts = fx .cx .module @@ -29,7 +29,7 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, impl Module>, msg: &str) { } /// Trap code: user1 -pub(crate) fn trap_abort(fx: &mut FunctionCx<'_, '_, impl Module>, msg: impl AsRef) { +pub(crate) fn trap_abort(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef) { codegen_print(fx, msg.as_ref()); fx.bcx.ins().trap(TrapCode::User(1)); } @@ -38,7 +38,7 @@ pub(crate) fn trap_abort(fx: &mut FunctionCx<'_, '_, impl Module>, msg: impl AsR /// so you can **not** add instructions to it afterwards. /// /// Trap code: user65535 -pub(crate) fn trap_unreachable(fx: &mut FunctionCx<'_, '_, impl Module>, msg: impl AsRef) { +pub(crate) fn trap_unreachable(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef) { codegen_print(fx, msg.as_ref()); fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); } @@ -47,7 +47,7 @@ pub(crate) fn trap_unreachable(fx: &mut FunctionCx<'_, '_, impl Module>, msg: im /// /// Trap code: user65535 pub(crate) fn trap_unreachable_ret_value<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, dest_layout: TyAndLayout<'tcx>, msg: impl AsRef, ) -> CValue<'tcx> { @@ -62,7 +62,7 @@ pub(crate) fn trap_unreachable_ret_value<'tcx>( /// to it afterwards. /// /// Trap code: user65535 -pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, impl Module>, msg: impl AsRef) { +pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef) { codegen_print(fx, msg.as_ref()); let true_ = fx.bcx.ins().iconst(types::I32, 1); fx.bcx.ins().trapnz(true_, TrapCode::User(!0)); @@ -72,7 +72,7 @@ pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, impl Module>, msg: /// /// Trap code: user65535 pub(crate) fn trap_unimplemented_ret_value<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, dest_layout: TyAndLayout<'tcx>, msg: impl AsRef, ) -> CValue<'tcx> { diff --git a/src/unsize.rs b/src/unsize.rs index c77ff5d56ba..042583cd572 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -13,19 +13,18 @@ use crate::prelude::*; /// in an upcast, where the new vtable for an object will be derived /// from the old one. pub(crate) fn unsized_info<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, source: Ty<'tcx>, target: Ty<'tcx>, old_info: Option, ) -> Value { let (source, target) = - fx.tcx - .struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all()); + fx.tcx.struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all()); match (&source.kind(), &target.kind()) { - (&ty::Array(_, len), &ty::Slice(_)) => fx.bcx.ins().iconst( - fx.pointer_type, - len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64, - ), + (&ty::Array(_, len), &ty::Slice(_)) => fx + .bcx + .ins() + .iconst(fx.pointer_type, len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64), (&ty::Dynamic(..), &ty::Dynamic(..)) => { // For now, upcasts are limited to changes in marker // traits, and hence never actually require an actual @@ -35,17 +34,13 @@ pub(crate) fn unsized_info<'tcx>( (_, &ty::Dynamic(ref data, ..)) => { crate::vtable::get_vtable(fx, fx.layout_of(source), data.principal()) } - _ => bug!( - "unsized_info: invalid unsizing {:?} -> {:?}", - source, - target - ), + _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target), } } /// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer. fn unsize_thin_ptr<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, src: Value, src_layout: TyAndLayout<'tcx>, dst_layout: TyAndLayout<'tcx>, @@ -89,24 +84,22 @@ fn unsize_thin_ptr<'tcx>( /// Coerce `src`, which is a reference to a value of type `src_ty`, /// to a value of type `dst_ty` and store the result in `dst` pub(crate) fn coerce_unsized_into<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, src: CValue<'tcx>, dst: CPlace<'tcx>, ) { let src_ty = src.layout().ty; let dst_ty = dst.layout().ty; let mut coerce_ptr = || { - let (base, info) = if fx - .layout_of(src.layout().ty.builtin_deref(true).unwrap().ty) - .is_unsized() - { - // fat-ptr to fat-ptr unsize preserves the vtable - // i.e., &'a fmt::Debug+Send => &'a fmt::Debug - src.load_scalar_pair(fx) - } else { - let base = src.load_scalar(fx); - unsize_thin_ptr(fx, base, src.layout(), dst.layout()) - }; + let (base, info) = + if fx.layout_of(src.layout().ty.builtin_deref(true).unwrap().ty).is_unsized() { + // fat-ptr to fat-ptr unsize preserves the vtable + // i.e., &'a fmt::Debug+Send => &'a fmt::Debug + src.load_scalar_pair(fx) + } else { + let base = src.load_scalar(fx); + unsize_thin_ptr(fx, base, src.layout(), dst.layout()) + }; dst.write_cvalue(fx, CValue::by_val_pair(base, info, dst.layout())); }; match (&src_ty.kind(), &dst_ty.kind()) { @@ -131,39 +124,26 @@ pub(crate) fn coerce_unsized_into<'tcx>( } } } - _ => bug!( - "coerce_unsized_into: invalid coercion {:?} -> {:?}", - src_ty, - dst_ty - ), + _ => bug!("coerce_unsized_into: invalid coercion {:?} -> {:?}", src_ty, dst_ty), } } // Adapted from https://github.com/rust-lang/rust/blob/2a663555ddf36f6b041445894a8c175cd1bc718c/src/librustc_codegen_ssa/glue.rs pub(crate) fn size_and_align_of_dst<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, info: Value, ) -> (Value, Value) { if !layout.is_unsized() { - let size = fx - .bcx - .ins() - .iconst(fx.pointer_type, layout.size.bytes() as i64); - let align = fx - .bcx - .ins() - .iconst(fx.pointer_type, layout.align.abi.bytes() as i64); + let size = fx.bcx.ins().iconst(fx.pointer_type, layout.size.bytes() as i64); + let align = fx.bcx.ins().iconst(fx.pointer_type, layout.align.abi.bytes() as i64); return (size, align); } match layout.ty.kind() { ty::Dynamic(..) => { // load size/align from vtable - ( - crate::vtable::size_of_obj(fx, info), - crate::vtable::min_align_of_obj(fx, info), - ) + (crate::vtable::size_of_obj(fx, info), crate::vtable::min_align_of_obj(fx, info)) } ty::Slice(_) | ty::Str => { let unit = layout.field(fx, 0); @@ -171,9 +151,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>( // times the unit size. ( fx.bcx.ins().imul_imm(info, unit.size.bytes() as i64), - fx.bcx - .ins() - .iconst(fx.pointer_type, unit.align.abi.bytes() as i64), + fx.bcx.ins().iconst(fx.pointer_type, unit.align.abi.bytes() as i64), ) } _ => { @@ -211,10 +189,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>( // Choose max of two known alignments (combined value must // be aligned according to more restrictive of the two). - let cmp = fx - .bcx - .ins() - .icmp(IntCC::UnsignedGreaterThan, sized_align, unsized_align); + let cmp = fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, sized_align, unsized_align); let align = fx.bcx.ins().select(cmp, sized_align, unsized_align); // Issue #27023: must add any necessary padding to `size` diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 765604e0f98..cffaf79ded1 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -6,7 +6,7 @@ use cranelift_codegen::entity::EntityRef; use cranelift_codegen::ir::immediates::Offset32; fn codegen_field<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, base: Pointer, extra: Option, layout: TyAndLayout<'tcx>, @@ -15,11 +15,8 @@ fn codegen_field<'tcx>( let field_offset = layout.fields.offset(field.index()); let field_layout = layout.field(&*fx, field.index()); - let simple = |fx: &mut FunctionCx<'_, '_, _>| { - ( - base.offset_i64(fx, i64::try_from(field_offset.bytes()).unwrap()), - field_layout, - ) + let simple = |fx: &mut FunctionCx<'_, '_, '_>| { + (base.offset_i64(fx, i64::try_from(field_offset.bytes()).unwrap()), field_layout) }; if let Some(extra) = extra { @@ -58,10 +55,7 @@ fn scalar_pair_calculate_b_offset( a_scalar: &Scalar, b_scalar: &Scalar, ) -> Offset32 { - let b_offset = a_scalar - .value - .size(&tcx) - .align_to(b_scalar.value.align(&tcx).abi); + let b_offset = a_scalar.value.size(&tcx).align_to(b_scalar.value.align(&tcx).abi); Offset32::new(b_offset.bytes().try_into().unwrap()) } @@ -106,10 +100,7 @@ impl<'tcx> CValue<'tcx> { } // FIXME remove - pub(crate) fn force_stack( - self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - ) -> (Pointer, Option) { + pub(crate) fn force_stack(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> (Pointer, Option) { let layout = self.1; match self.0 { CValueInner::ByRef(ptr, meta) => (ptr, meta), @@ -129,7 +120,7 @@ impl<'tcx> CValue<'tcx> { } /// Load a value with layout.abi of scalar - pub(crate) fn load_scalar(self, fx: &mut FunctionCx<'_, 'tcx, impl Module>) -> Value { + pub(crate) fn load_scalar(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> Value { let layout = self.1; match self.0 { CValueInner::ByRef(ptr, None) => { @@ -153,10 +144,7 @@ impl<'tcx> CValue<'tcx> { } /// Load a value pair with layout.abi of scalar pair - pub(crate) fn load_scalar_pair( - self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - ) -> (Value, Value) { + pub(crate) fn load_scalar_pair(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> (Value, Value) { let layout = self.1; match self.0 { CValueInner::ByRef(ptr, None) => { @@ -183,7 +171,7 @@ impl<'tcx> CValue<'tcx> { pub(crate) fn value_field( self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, field: mir::Field, ) -> CValue<'tcx> { let layout = self.1; @@ -219,21 +207,17 @@ impl<'tcx> CValue<'tcx> { } } - pub(crate) fn unsize_value( - self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - dest: CPlace<'tcx>, - ) { + pub(crate) fn unsize_value(self, fx: &mut FunctionCx<'_, '_, 'tcx>, dest: CPlace<'tcx>) { crate::unsize::coerce_unsized_into(fx, self, dest); } /// If `ty` is signed, `const_val` must already be sign extended. pub(crate) fn const_val( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, const_val: ty::ScalarInt, ) -> CValue<'tcx> { - assert_eq!(const_val.size(), layout.size); + assert_eq!(const_val.size(), layout.size, "{:#?}: {:?}", const_val, layout); use cranelift_codegen::ir::immediates::{Ieee32, Ieee64}; let clif_ty = fx.clif_type(layout.ty).unwrap(); @@ -250,18 +234,11 @@ impl<'tcx> CValue<'tcx> { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { let const_val = const_val.to_bits(layout.size).unwrap(); let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64); - let msb = fx - .bcx - .ins() - .iconst(types::I64, (const_val >> 64) as u64 as i64); + let msb = fx.bcx.ins().iconst(types::I64, (const_val >> 64) as u64 as i64); fx.bcx.ins().iconcat(lsb, msb) } - ty::Bool | ty::Char | ty::Uint(_) | ty::Int(_) | ty::Ref(..) - | ty::RawPtr(..) => { - fx - .bcx - .ins() - .iconst(clif_ty, const_val.to_bits(layout.size).unwrap() as i64) + ty::Bool | ty::Char | ty::Uint(_) | ty::Int(_) | ty::Ref(..) | ty::RawPtr(..) => { + fx.bcx.ins().iconst(clif_ty, const_val.to_bits(layout.size).unwrap() as i64) } ty::Float(FloatTy::F32) => { fx.bcx.ins().f32const(Ieee32::with_bits(u32::try_from(const_val).unwrap())) @@ -279,14 +256,8 @@ impl<'tcx> CValue<'tcx> { } pub(crate) fn cast_pointer_to(self, layout: TyAndLayout<'tcx>) -> Self { - assert!(matches!( - self.layout().ty.kind(), - ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..) - )); - assert!(matches!( - layout.ty.kind(), - ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..) - )); + assert!(matches!(self.layout().ty.kind(), ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..))); + assert!(matches!(layout.ty.kind(), ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..))); assert_eq!(self.layout().abi, layout.abi); CValue(self.0, layout) } @@ -317,14 +288,11 @@ impl<'tcx> CPlace<'tcx> { } pub(crate) fn no_place(layout: TyAndLayout<'tcx>) -> CPlace<'tcx> { - CPlace { - inner: CPlaceInner::Addr(Pointer::dangling(layout.align.pref), None), - layout, - } + CPlace { inner: CPlaceInner::Addr(Pointer::dangling(layout.align.pref), None), layout } } pub(crate) fn new_stack_slot( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { assert!(!layout.is_unsized()); @@ -339,28 +307,22 @@ impl<'tcx> CPlace<'tcx> { size: (u32::try_from(layout.size.bytes()).unwrap() + 15) / 16 * 16, offset: None, }); - CPlace { - inner: CPlaceInner::Addr(Pointer::stack_slot(stack_slot), None), - layout, - } + CPlace { inner: CPlaceInner::Addr(Pointer::stack_slot(stack_slot), None), layout } } pub(crate) fn new_var( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, local: Local, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { let var = Variable::with_u32(fx.next_ssa_var); fx.next_ssa_var += 1; fx.bcx.declare_var(var, fx.clif_type(layout.ty).unwrap()); - CPlace { - inner: CPlaceInner::Var(local, var), - layout, - } + CPlace { inner: CPlaceInner::Var(local, var), layout } } pub(crate) fn new_var_pair( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, local: Local, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { @@ -372,17 +334,11 @@ impl<'tcx> CPlace<'tcx> { let (ty1, ty2) = fx.clif_pair_type(layout.ty).unwrap(); fx.bcx.declare_var(var1, ty1); fx.bcx.declare_var(var2, ty2); - CPlace { - inner: CPlaceInner::VarPair(local, var1, var2), - layout, - } + CPlace { inner: CPlaceInner::VarPair(local, var1, var2), layout } } pub(crate) fn for_ptr(ptr: Pointer, layout: TyAndLayout<'tcx>) -> CPlace<'tcx> { - CPlace { - inner: CPlaceInner::Addr(ptr, None), - layout, - } + CPlace { inner: CPlaceInner::Addr(ptr, None), layout } } pub(crate) fn for_ptr_with_extra( @@ -390,34 +346,27 @@ impl<'tcx> CPlace<'tcx> { extra: Value, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { - CPlace { - inner: CPlaceInner::Addr(ptr, Some(extra)), - layout, - } + CPlace { inner: CPlaceInner::Addr(ptr, Some(extra)), layout } } - pub(crate) fn to_cvalue(self, fx: &mut FunctionCx<'_, 'tcx, impl Module>) -> CValue<'tcx> { + pub(crate) fn to_cvalue(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> CValue<'tcx> { let layout = self.layout(); match self.inner { CPlaceInner::Var(_local, var) => { let val = fx.bcx.use_var(var); - fx.bcx - .set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index())); + //fx.bcx.set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index())); CValue::by_val(val, layout) } CPlaceInner::VarPair(_local, var1, var2) => { let val1 = fx.bcx.use_var(var1); - fx.bcx - .set_val_label(val1, cranelift_codegen::ir::ValueLabel::new(var1.index())); + //fx.bcx.set_val_label(val1, cranelift_codegen::ir::ValueLabel::new(var1.index())); let val2 = fx.bcx.use_var(var2); - fx.bcx - .set_val_label(val2, cranelift_codegen::ir::ValueLabel::new(var2.index())); + //fx.bcx.set_val_label(val2, cranelift_codegen::ir::ValueLabel::new(var2.index())); CValue::by_val_pair(val1, val2, layout) } CPlaceInner::VarLane(_local, var, lane) => { let val = fx.bcx.use_var(var); - fx.bcx - .set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index())); + //fx.bcx.set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index())); let val = fx.bcx.ins().extractlane(val, lane); CValue::by_val(val, layout) } @@ -447,11 +396,7 @@ impl<'tcx> CPlace<'tcx> { } } - pub(crate) fn write_cvalue( - self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - from: CValue<'tcx>, - ) { + pub(crate) fn write_cvalue(self, fx: &mut FunctionCx<'_, '_, 'tcx>, from: CValue<'tcx>) { assert_assignable(fx, from.layout().ty, self.layout().ty); self.write_cvalue_maybe_transmute(fx, from, "write_cvalue"); @@ -459,7 +404,7 @@ impl<'tcx> CPlace<'tcx> { pub(crate) fn write_cvalue_transmute( self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, from: CValue<'tcx>, ) { self.write_cvalue_maybe_transmute(fx, from, "write_cvalue_transmute"); @@ -467,12 +412,12 @@ impl<'tcx> CPlace<'tcx> { fn write_cvalue_maybe_transmute( self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, from: CValue<'tcx>, #[cfg_attr(not(debug_assertions), allow(unused_variables))] method: &'static str, ) { fn transmute_value<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, var: Variable, data: Value, dst_ty: Type, @@ -511,8 +456,7 @@ impl<'tcx> CPlace<'tcx> { } _ => unreachable!("write_cvalue_transmute: {:?} -> {:?}", src_ty, dst_ty), }; - fx.bcx - .set_val_label(data, cranelift_codegen::ir::ValueLabel::new(var.index())); + //fx.bcx.set_val_label(data, cranelift_codegen::ir::ValueLabel::new(var.index())); fx.bcx.def_var(var, data); } @@ -558,15 +502,13 @@ impl<'tcx> CPlace<'tcx> { // First get the old vector let vector = fx.bcx.use_var(var); - fx.bcx - .set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index())); + //fx.bcx.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index())); // Next insert the written lane into the vector let vector = fx.bcx.ins().insertlane(vector, data, lane); // Finally write the new vector - fx.bcx - .set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index())); + //fx.bcx.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index())); fx.bcx.def_var(var, vector); return; @@ -604,10 +546,7 @@ impl<'tcx> CPlace<'tcx> { to_ptr.store(fx, val, flags); } CValueInner::ByValPair(_, _) => { - bug!( - "Non ScalarPair abi {:?} for ByValPair CValue", - dst_layout.abi - ); + bug!("Non ScalarPair abi {:?} for ByValPair CValue", dst_layout.abi); } CValueInner::ByRef(from_ptr, None) => { let from_addr = from_ptr.get_addr(fx); @@ -632,7 +571,7 @@ impl<'tcx> CPlace<'tcx> { pub(crate) fn place_field( self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, field: mir::Field, ) -> CPlace<'tcx> { let layout = self.layout(); @@ -650,18 +589,8 @@ impl<'tcx> CPlace<'tcx> { let layout = layout.field(&*fx, field.index()); match field.as_u32() { - 0 => { - return CPlace { - inner: CPlaceInner::Var(local, var1), - layout, - } - } - 1 => { - return CPlace { - inner: CPlaceInner::Var(local, var2), - layout, - } - } + 0 => return CPlace { inner: CPlaceInner::Var(local, var1), layout }, + 1 => return CPlace { inner: CPlaceInner::Var(local, var2), layout }, _ => unreachable!("field should be 0 or 1"), } } @@ -680,7 +609,7 @@ impl<'tcx> CPlace<'tcx> { pub(crate) fn place_index( self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, index: Value, ) -> CPlace<'tcx> { let (elem_layout, ptr) = match self.layout().ty.kind() { @@ -689,30 +618,24 @@ impl<'tcx> CPlace<'tcx> { _ => bug!("place_index({:?})", self.layout().ty), }; - let offset = fx - .bcx - .ins() - .imul_imm(index, elem_layout.size.bytes() as i64); + let offset = fx.bcx.ins().imul_imm(index, elem_layout.size.bytes() as i64); CPlace::for_ptr(ptr.offset_value(fx, offset), elem_layout) } - pub(crate) fn place_deref(self, fx: &mut FunctionCx<'_, 'tcx, impl Module>) -> CPlace<'tcx> { + pub(crate) fn place_deref(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> CPlace<'tcx> { let inner_layout = fx.layout_of(self.layout().ty.builtin_deref(true).unwrap().ty); if has_ptr_meta(fx.tcx, inner_layout.ty) { let (addr, extra) = self.to_cvalue(fx).load_scalar_pair(fx); CPlace::for_ptr_with_extra(Pointer::new(addr), extra, inner_layout) } else { - CPlace::for_ptr( - Pointer::new(self.to_cvalue(fx).load_scalar(fx)), - inner_layout, - ) + CPlace::for_ptr(Pointer::new(self.to_cvalue(fx).load_scalar(fx)), inner_layout) } } pub(crate) fn place_ref( self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, ) -> CValue<'tcx> { if has_ptr_meta(fx.tcx, self.layout().ty) { @@ -729,21 +652,18 @@ impl<'tcx> CPlace<'tcx> { pub(crate) fn downcast_variant( self, - fx: &FunctionCx<'_, 'tcx, impl Module>, + fx: &FunctionCx<'_, '_, 'tcx>, variant: VariantIdx, ) -> Self { assert!(!self.layout().is_unsized()); let layout = self.layout().for_variant(fx, variant); - CPlace { - inner: self.inner, - layout, - } + CPlace { inner: self.inner, layout } } } #[track_caller] pub(crate) fn assert_assignable<'tcx>( - fx: &FunctionCx<'_, 'tcx, impl Module>, + fx: &FunctionCx<'_, '_, 'tcx>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>, ) { @@ -776,12 +696,9 @@ pub(crate) fn assert_assignable<'tcx>( } (&ty::Dynamic(from_traits, _), &ty::Dynamic(to_traits, _)) => { for (from, to) in from_traits.iter().zip(to_traits) { - let from = fx - .tcx - .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from); - let to = fx - .tcx - .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to); + let from = + fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from); + let to = fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to); assert_eq!( from, to, "Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}", diff --git a/src/vtable.rs b/src/vtable.rs index 8f15586a9dc..4d2551a061b 100644 --- a/src/vtable.rs +++ b/src/vtable.rs @@ -15,7 +15,7 @@ fn vtable_memflags() -> MemFlags { flags } -pub(crate) fn drop_fn_of_obj(fx: &mut FunctionCx<'_, '_, impl Module>, vtable: Value) -> Value { +pub(crate) fn drop_fn_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Value { let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize; fx.bcx.ins().load( pointer_ty(fx.tcx), @@ -25,7 +25,7 @@ pub(crate) fn drop_fn_of_obj(fx: &mut FunctionCx<'_, '_, impl Module>, vtable: V ) } -pub(crate) fn size_of_obj(fx: &mut FunctionCx<'_, '_, impl Module>, vtable: Value) -> Value { +pub(crate) fn size_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Value { let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize; fx.bcx.ins().load( pointer_ty(fx.tcx), @@ -35,7 +35,7 @@ pub(crate) fn size_of_obj(fx: &mut FunctionCx<'_, '_, impl Module>, vtable: Valu ) } -pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, impl Module>, vtable: Value) -> Value { +pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Value { let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize; fx.bcx.ins().load( pointer_ty(fx.tcx), @@ -46,7 +46,7 @@ pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, impl Module>, vtable: } pub(crate) fn get_ptr_and_method_ref<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, arg: CValue<'tcx>, idx: usize, ) -> (Value, Value) { @@ -68,7 +68,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>( } pub(crate) fn get_vtable<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, trait_ref: Option>, ) -> Value { @@ -85,7 +85,7 @@ pub(crate) fn get_vtable<'tcx>( } fn build_vtable<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, trait_ref: Option>, ) -> DataId { @@ -94,7 +94,7 @@ fn build_vtable<'tcx>( let drop_in_place_fn = import_function( tcx, - &mut fx.cx.module, + fx.cx.module, Instance::resolve_drop_in_place(tcx, layout.ty).polymorphize(fx.tcx), ); @@ -111,7 +111,7 @@ fn build_vtable<'tcx>( opt_mth.map(|(def_id, substs)| { import_function( tcx, - &mut fx.cx.module, + fx.cx.module, Instance::resolve_for_vtable(tcx, ParamEnv::reveal_all(), def_id, substs) .unwrap() .polymorphize(fx.tcx), @@ -165,11 +165,8 @@ fn build_vtable<'tcx>( } fn write_usize(tcx: TyCtxt<'_>, buf: &mut [u8], idx: usize, num: u64) { - let pointer_size = tcx - .layout_of(ParamEnv::reveal_all().and(tcx.types.usize)) - .unwrap() - .size - .bytes() as usize; + let pointer_size = + tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.usize)).unwrap().size.bytes() as usize; let target = &mut buf[idx * pointer_size..(idx + 1) * pointer_size]; match tcx.data_layout.endian { diff --git a/test.sh b/test.sh index 5ab10e0e905..e222adc7b80 100755 --- a/test.sh +++ b/test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e ./build.sh --sysroot none "$@" From c825bc8e61c9a30adebacbe87d048324a5e1063a Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 5 Mar 2021 21:32:37 +0100 Subject: [PATCH 016/370] Update Cranelift This adds support for the WindowsFastcall calling convention --- Cargo.lock | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76d9f0d27ce..1ed186032ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,16 +39,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "byteorder", "cranelift-bforest", @@ -65,8 +65,8 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -74,18 +74,18 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" [[package]] name = "cranelift-entity" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" [[package]] name = "cranelift-frontend" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "cranelift-codegen", "log", @@ -95,8 +95,8 @@ dependencies = [ [[package]] name = "cranelift-jit" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "anyhow", "cranelift-codegen", @@ -113,8 +113,8 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "anyhow", "cranelift-codegen", @@ -125,8 +125,8 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "cranelift-codegen", "target-lexicon", @@ -134,8 +134,8 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "anyhow", "cranelift-codegen", From 1122f42e2872a4bb65adeb990fb73cc555f5c3cf Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 25 May 2020 21:43:22 +0200 Subject: [PATCH 017/370] Support cross-compiling to Windows using MinGW --- example/mini_core.rs | 1 + example/mini_core_hello_world.rs | 4 +- example/std_example.rs | 3 +- prepare.sh | 1 + src/codegen_i128.rs | 89 +++++++++++++++++++++++++------- src/inline_asm.rs | 4 ++ src/lib.rs | 2 + 7 files changed, 82 insertions(+), 22 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index 7c6d7fc106d..c4834c80408 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -621,6 +621,7 @@ struct PanicLocation { } #[no_mangle] +#[cfg(not(windows))] pub fn get_tls() -> u8 { #[thread_local] static A: u8 = 42; diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 237f4d11d57..08ceaeb6544 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -239,7 +239,7 @@ fn main() { assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42); - #[cfg(not(jit))] + #[cfg(not(any(jit, windows)))] { extern { #[linkage = "extern_weak"] @@ -292,7 +292,7 @@ fn main() { from_decimal_string(); - #[cfg(not(jit))] + #[cfg(not(any(jit, windows)))] test_tls(); #[cfg(all(not(jit), target_os = "linux"))] diff --git a/example/std_example.rs b/example/std_example.rs index 015bbdfed46..221b512e3bd 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -16,7 +16,8 @@ fn main() { let mut stderr = stderr.lock(); // FIXME support lazy jit when multi threading - #[cfg(not(lazy_jit))] + // FIXME support TLS on windows + #[cfg(not(any(lazy_jit, windows)))] std::thread::spawn(move || { println!("Hello from another thread!"); }); diff --git a/prepare.sh b/prepare.sh index ee995ffcfa9..d391399bee0 100755 --- a/prepare.sh +++ b/prepare.sh @@ -2,6 +2,7 @@ set -e rustup component add rust-src rustc-dev llvm-tools-preview +rustup target add x86_64-pc-windows-gnu ./build_sysroot/prepare_sysroot_src.sh cargo install hyperfine || echo "Skipping hyperfine install" diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index ae75e6508cb..ffe1922ab90 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -32,18 +32,56 @@ pub(crate) fn maybe_codegen<'tcx>( BinOp::Add | BinOp::Sub if !checked => None, BinOp::Mul if !checked => { let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; - Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty)) + if fx.tcx.sess.target.is_like_windows { + let ret_place = CPlace::new_stack_slot(fx, lhs.layout()); + let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); + let (rhs_ptr, rhs_extra) = rhs.force_stack(fx); + assert!(lhs_extra.is_none()); + assert!(rhs_extra.is_none()); + let args = + [ret_place.to_ptr().get_addr(fx), lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)]; + fx.lib_call( + "__multi3", + vec![ + AbiParam::special(pointer_ty(fx.tcx), ArgumentPurpose::StructReturn), + AbiParam::new(pointer_ty(fx.tcx)), + AbiParam::new(pointer_ty(fx.tcx)), + ], + vec![], + &args, + ); + Some(ret_place.to_cvalue(fx)) + } else { + Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty)) + } } BinOp::Add | BinOp::Sub | BinOp::Mul => { assert!(checked); let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty)); - let param_types = vec![ - AbiParam::special(pointer_ty(fx.tcx), ArgumentPurpose::StructReturn), - AbiParam::new(types::I128), - AbiParam::new(types::I128), - ]; - let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)]; + let (param_types, args) = if fx.tcx.sess.target.is_like_windows { + let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); + let (rhs_ptr, rhs_extra) = rhs.force_stack(fx); + assert!(lhs_extra.is_none()); + assert!(rhs_extra.is_none()); + ( + vec![ + AbiParam::special(pointer_ty(fx.tcx), ArgumentPurpose::StructReturn), + AbiParam::new(pointer_ty(fx.tcx)), + AbiParam::new(pointer_ty(fx.tcx)), + ], + [out_place.to_ptr().get_addr(fx), lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)], + ) + } else { + ( + vec![ + AbiParam::special(pointer_ty(fx.tcx), ArgumentPurpose::StructReturn), + AbiParam::new(types::I128), + AbiParam::new(types::I128), + ], + [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)], + ) + }; let name = match (bin_op, is_signed) { (BinOp::Add, false) => "__rust_u128_addo", (BinOp::Add, true) => "__rust_i128_addo", @@ -57,20 +95,33 @@ pub(crate) fn maybe_codegen<'tcx>( Some(out_place.to_cvalue(fx)) } BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"), - BinOp::Div => { + BinOp::Div | BinOp::Rem => { assert!(!checked); - if is_signed { - Some(fx.easy_call("__divti3", &[lhs, rhs], fx.tcx.types.i128)) + let name = match (bin_op, is_signed) { + (BinOp::Div, false) => "__udivti3", + (BinOp::Div, true) => "__divti3", + (BinOp::Rem, false) => "__umodti3", + (BinOp::Rem, true) => "__modti3", + _ => unreachable!(), + }; + if fx.tcx.sess.target.is_like_windows { + let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); + let (rhs_ptr, rhs_extra) = rhs.force_stack(fx); + assert!(lhs_extra.is_none()); + assert!(rhs_extra.is_none()); + let args = [lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)]; + let ret = fx.lib_call( + name, + vec![AbiParam::new(pointer_ty(fx.tcx)), AbiParam::new(pointer_ty(fx.tcx))], + vec![AbiParam::new(types::I64X2)], + &args, + )[0]; + // FIXME use bitcast instead of store to get from i64x2 to i128 + let ret_place = CPlace::new_stack_slot(fx, lhs.layout()); + ret_place.to_ptr().store(fx, ret, MemFlags::trusted()); + Some(ret_place.to_cvalue(fx)) } else { - Some(fx.easy_call("__udivti3", &[lhs, rhs], fx.tcx.types.u128)) - } - } - BinOp::Rem => { - assert!(!checked); - if is_signed { - Some(fx.easy_call("__modti3", &[lhs, rhs], fx.tcx.types.i128)) - } else { - Some(fx.easy_call("__umodti3", &[lhs, rhs], fx.tcx.types.u128)) + Some(fx.easy_call(name, &[lhs, rhs], lhs.layout().ty)) } } BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => { diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 5b3df2bd382..33234f820aa 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -20,6 +20,10 @@ pub(crate) fn codegen_inline_asm<'tcx>( if template.is_empty() { // Black box return; + } else if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) { + let true_ = fx.bcx.ins().iconst(types::I32, 1); + fx.bcx.ins().trapnz(true_, TrapCode::User(1)); + return; } let mut slot_size = Size::from_bytes(0); diff --git a/src/lib.rs b/src/lib.rs index e1927ad3a69..5db2499709a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -313,6 +313,8 @@ fn build_isa(sess: &Session) -> Box { flags_builder.set("enable_simd", "true").unwrap(); + flags_builder.set("enable_llvm_abi_extensions", "true").unwrap(); + use rustc_session::config::OptLevel; match sess.opts.optimize { OptLevel::No => { From d23b12fa62b30a30eba42a33fb2d1ff3932815db Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 25 Feb 2021 14:35:27 +0100 Subject: [PATCH 018/370] Build all tests when cross-compiling --- build.sh | 7 +++++++ scripts/tests.sh | 47 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/build.sh b/build.sh index 090349e54b1..76bc1884334 100755 --- a/build.sh +++ b/build.sh @@ -55,6 +55,7 @@ ln target/$CHANNEL/*rustc_codegen_cranelift* "$target_dir"/lib ln rust-toolchain scripts/config.sh scripts/cargo.sh "$target_dir" mkdir -p "$target_dir/lib/rustlib/$TARGET_TRIPLE/lib/" +mkdir -p "$target_dir/lib/rustlib/$HOST_TRIPLE/lib/" if [[ "$TARGET_TRIPLE" == "x86_64-pc-windows-gnu" ]]; then cp $(rustc --print sysroot)/lib/rustlib/$TARGET_TRIPLE/lib/*.o "$target_dir/lib/rustlib/$TARGET_TRIPLE/lib/" fi @@ -64,12 +65,18 @@ case "$build_sysroot" in ;; "llvm") cp -r $(rustc --print sysroot)/lib/rustlib/$TARGET_TRIPLE/lib "$target_dir/lib/rustlib/$TARGET_TRIPLE/" + if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then + cp -r $(rustc --print sysroot)/lib/rustlib/$HOST_TRIPLE/lib "$target_dir/lib/rustlib/$HOST_TRIPLE/" + fi ;; "clif") echo "[BUILD] sysroot" dir=$(pwd) cd "$target_dir" time "$dir/build_sysroot/build_sysroot.sh" + if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then + time TARGET_TRIPLE="$HOST_TRIPLE" "$dir/build_sysroot/build_sysroot.sh" + fi cp lib/rustlib/*/lib/libstd-* lib/ ;; *) diff --git a/scripts/tests.sh b/scripts/tests.sh index f9a9fb091fb..3afcea8f06b 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -71,14 +71,20 @@ function base_sysroot_tests() { echo "[AOT] mod_bench" $MY_RUSTC example/mod_bench.rs --crate-type bin --target "$TARGET_TRIPLE" $RUN_WRAPPER ./target/out/mod_bench - - pushd rand - rm -r ./target || true - ../build/cargo.sh test --workspace - popd } function extended_sysroot_tests() { + pushd rand + cargo clean + if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then + echo "[TEST] rust-random/rand" + ../build/cargo.sh test --workspace + else + echo "[AOT] rust-random/rand" + ../build/cargo.sh build --workspace --target $TARGET_TRIPLE --tests + fi + popd + pushd simple-raytracer if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then echo "[BENCH COMPILE] ebobby/simple-raytracer" @@ -92,27 +98,40 @@ function extended_sysroot_tests() { else echo "[BENCH COMPILE] ebobby/simple-raytracer (skipped)" echo "[COMPILE] ebobby/simple-raytracer" - ../cargo.sh build + ../build/cargo.sh build --target $TARGET_TRIPLE echo "[BENCH RUN] ebobby/simple-raytracer (skipped)" fi popd pushd build_sysroot/sysroot_src/library/core/tests echo "[TEST] libcore" - rm -r ./target || true - ../../../../../build/cargo.sh test + cargo clean + if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then + ../../../../../build/cargo.sh test + else + ../../../../../build/cargo.sh build --target $TARGET_TRIPLE --tests + fi popd pushd regex echo "[TEST] rust-lang/regex example shootout-regex-dna" - ../build/cargo.sh clean + cargo clean # Make sure `[codegen mono items] start` doesn't poison the diff - ../build/cargo.sh build --example shootout-regex-dna - cat examples/regexdna-input.txt | ../build/cargo.sh run --example shootout-regex-dna | grep -v "Spawned thread" > res.txt - diff -u res.txt examples/regexdna-output.txt + ../build/cargo.sh build --example shootout-regex-dna --target $TARGET_TRIPLE + if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then + cat examples/regexdna-input.txt \ + | ../build/cargo.sh run --example shootout-regex-dna --target $TARGET_TRIPLE \ + | grep -v "Spawned thread" > res.txt + diff -u res.txt examples/regexdna-output.txt + fi - echo "[TEST] rust-lang/regex tests" - ../build/cargo.sh test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q + if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then + echo "[TEST] rust-lang/regex tests" + ../build/cargo.sh test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q + else + echo "[AOT] rust-lang/regex tests" + ../build/cargo.sh build --tests --target $TARGET_TRIPLE + fi popd } From 00f1cddb9c8ecd82ada4ea30430cb6cf178c50ba Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 25 Feb 2021 14:54:52 +0100 Subject: [PATCH 019/370] Test Windows cross-compilation on CI --- .github/workflows/main.yml | 17 ++++++++++++++++- prepare.sh | 1 - 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e6d3375fb1b..e06a1fb88ba 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,7 +11,13 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + include: + - os: ubuntu-latest + - os: macos-latest + # cross-compile from Linux to Windows using mingw + - os: ubuntu-latest + env: + TARGET_TRIPLE: x86_64-pc-windows-gnu steps: - uses: actions/checkout@v2 @@ -36,6 +42,12 @@ jobs: path: target key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + - name: Install MinGW toolchain and wine + if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' + run: | + sudo apt-get install -y gcc-mingw-w64-x86-64 wine-stable + rustup target add x86_64-pc-windows-gnu + - name: Prepare dependencies run: | git config --global user.email "user@example.com" @@ -43,6 +55,8 @@ jobs: ./prepare.sh - name: Test + env: + TARGET_TRIPLE: ${{ matrix.env.TARGET_TRIPLE }} run: | # Enable backtraces for easier debugging export RUST_BACKTRACE=1 @@ -57,6 +71,7 @@ jobs: run: tar cvfJ cg_clif.tar.xz build - name: Upload prebuilt cg_clif + if: matrix.env.TARGET_TRIPLE != 'x86_64-pc-windows-gnu' uses: actions/upload-artifact@v2 with: name: cg_clif-${{ runner.os }} diff --git a/prepare.sh b/prepare.sh index d391399bee0..ee995ffcfa9 100755 --- a/prepare.sh +++ b/prepare.sh @@ -2,7 +2,6 @@ set -e rustup component add rust-src rustc-dev llvm-tools-preview -rustup target add x86_64-pc-windows-gnu ./build_sysroot/prepare_sysroot_src.sh cargo install hyperfine || echo "Skipping hyperfine install" From f43c02236d5c5bcf7c2cad98070ca9164cebfe54 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sun, 24 Jan 2021 21:04:18 +0100 Subject: [PATCH 020/370] Instruct LLVM that binary_search_by returns a valid index --- library/core/src/slice/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 5510bb0257e..0aaccaed416 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2204,6 +2204,8 @@ impl [T] { } else if cmp == Greater { right = mid; } else { + // SAFETY: same as the `get_unchecked` above + unsafe { crate::intrinsics::assume(mid < self.len()) }; return Ok(mid); } From c9d04c2b238dc5ab51bd8a92c41ba17bb5b00ed7 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sun, 24 Jan 2021 21:07:25 +0100 Subject: [PATCH 021/370] Add codegen test checking binary_search allows eliding bound checks --- .../binary-search-index-no-bound-check.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/test/codegen/binary-search-index-no-bound-check.rs diff --git a/src/test/codegen/binary-search-index-no-bound-check.rs b/src/test/codegen/binary-search-index-no-bound-check.rs new file mode 100644 index 00000000000..110d1d55626 --- /dev/null +++ b/src/test/codegen/binary-search-index-no-bound-check.rs @@ -0,0 +1,19 @@ +// min-llvm-version: 11.0.0 +// compile-flags: -O +// ignore-debug: the debug assertions get in the way +#![crate_type = "lib"] + +// Make sure no bounds checks are emitted when slicing or indexing +// with an index from `binary_search`. + +// CHECK-LABEL: @binary_search_index_no_bounds_check +#[no_mangle] +pub fn binary_search_index_no_bounds_check(s: &[u8]) -> u8 { + // CHECK-NOT: panic + // CHECK-NOT: slice_index_len_fail + if let Ok(idx) = s.binary_search(&b'\\') { + s[idx] + } else { + 42 + } +} From 0985044c75fff285928c451a3d43056b0955b761 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 14:46:38 +0100 Subject: [PATCH 022/370] Use --print file-names instead of a match on uname --- scripts/config.sh | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/scripts/config.sh b/scripts/config.sh index c2ed2bf256d..99b302ee1d9 100644 --- a/scripts/config.sh +++ b/scripts/config.sh @@ -2,15 +2,7 @@ set -e -unamestr=$(uname) -if [[ "$unamestr" == 'Linux' || "$unamestr" == 'FreeBSD' ]]; then - dylib_ext='so' -elif [[ "$unamestr" == 'Darwin' ]]; then - dylib_ext='dylib' -else - echo "Unsupported os" - exit 1 -fi +dylib=$(echo "" | rustc --print file-names --crate-type dylib --crate-name rustc_codegen_cranelift -) if echo "$RUSTC_WRAPPER" | grep sccache; then echo @@ -24,10 +16,10 @@ dir=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd) export RUSTC=$dir"/bin/cg_clif" export RUSTDOCFLAGS=$linker' -Cpanic=abort -Zpanic-abort-tests '\ -'-Zcodegen-backend='$dir'/lib/librustc_codegen_cranelift.'$dylib_ext' --sysroot '$dir +'-Zcodegen-backend='$dir'/lib/'$dylib' --sysroot '$dir # FIXME fix `#[linkage = "extern_weak"]` without this -if [[ "$unamestr" == 'Darwin' ]]; then +if [[ "$(uname)" == 'Darwin' ]]; then export RUSTFLAGS="$RUSTFLAGS -Clink-arg=-undefined -Clink-arg=dynamic_lookup" fi From 5f3d640d45d88410511f610796b9a36465899eee Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 14:49:55 +0100 Subject: [PATCH 023/370] Fix warning --- src/value_and_place.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index cffaf79ded1..c2c59773848 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -2,7 +2,6 @@ use crate::prelude::*; -use cranelift_codegen::entity::EntityRef; use cranelift_codegen::ir::immediates::Offset32; fn codegen_field<'tcx>( From bd1b1dd58e257322821267614ef6009d9c3ff5c8 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 14:58:29 +0100 Subject: [PATCH 024/370] Handle #![windows_subsystem] --- src/driver/aot.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index b87dcc41928..0f1da66170a 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -163,6 +163,22 @@ pub(super) fn run_aot( metadata: EncodedMetadata, need_metadata_module: bool, ) -> Box<(CodegenResults, FxHashMap)> { + use rustc_span::symbol::sym; + + let subsystem = tcx + .sess + .first_attr_value_str_by_name(&tcx.hir().krate().item.attrs, sym::windows_subsystem); + let windows_subsystem = subsystem.map(|subsystem| { + if subsystem != sym::windows && subsystem != sym::console { + tcx.sess.fatal(&format!( + "invalid windows subsystem `{}`, only \ + `windows` and `console` are allowed", + subsystem + )); + } + subsystem.to_string() + }); + let mut work_products = FxHashMap::default(); let cgus = if tcx.sess.opts.output_types.should_codegen() { @@ -280,7 +296,7 @@ pub(super) fn run_aot( allocator_module, metadata_module, metadata, - windows_subsystem: None, // Windows is not yet supported + windows_subsystem, linker_info: LinkerInfo::new(tcx), crate_info: CrateInfo::new(tcx), }, From 4ca3384db63fcc938b2ed58b9c6f42ef93442e47 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 15:33:47 +0100 Subject: [PATCH 025/370] Make it possible to enable the verifier in release mode --- .github/workflows/main.yml | 3 +++ docs/env_vars.md | 5 ++++- src/lib.rs | 6 +++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e06a1fb88ba..3b29225f601 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -65,6 +65,9 @@ jobs: export COMPILE_RUNS=2 export RUN_RUNS=2 + # Enable extra checks + export CG_CLIF_ENABLE_VERIFIER=1 + ./test.sh - name: Package prebuilt cg_clif diff --git a/docs/env_vars.md b/docs/env_vars.md index f0a0a6ad42e..f7fde1b4f3a 100644 --- a/docs/env_vars.md +++ b/docs/env_vars.md @@ -8,5 +8,8 @@ to make it possible to use incremental mode for all analyses performed by rustc without caching object files when their content should have been changed by a change to cg_clif.
CG_CLIF_DISPLAY_CG_TIME
-
If "1", display the time it took to perform codegen for a crate
+
If "1", display the time it took to perform codegen for a crate.
+
CG_CLIF_ENABLE_VERIFIER
+
Enable the Cranelift ir verifier for all compilation passes. If not set it will only run once + before passing the clif ir to Cranelift for compilation. diff --git a/src/lib.rs b/src/lib.rs index 5db2499709a..f38d943afbf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -299,9 +299,9 @@ fn build_isa(sess: &Session) -> Box { let mut flags_builder = settings::builder(); flags_builder.enable("is_pic").unwrap(); flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided - flags_builder - .set("enable_verifier", if cfg!(debug_assertions) { "true" } else { "false" }) - .unwrap(); + let enable_verifier = + cfg!(debug_assertions) || std::env::var("CG_CLIF_ENABLE_VERIFIER").is_ok(); + flags_builder.set("enable_verifier", if enable_verifier { "true" } else { "false" }).unwrap(); let tls_model = match target_triple.binary_format { BinaryFormat::Elf => "elf_gd", From cecd7a9ae69689a884b4baf0a0c871a5b9eb1bb4 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 18:45:04 +0100 Subject: [PATCH 026/370] Add clif comments when in release mode Fixes #1130 --- src/abi/comments.rs | 27 ++++++++---- src/abi/mod.rs | 19 +++------ src/abi/pass_mode.rs | 5 +-- src/abi/returning.rs | 4 -- src/base.rs | 11 ++--- src/common.rs | 3 +- src/constant.rs | 25 ++++++----- src/inline_asm.rs | 10 +++-- src/optimize/stack2reg.rs | 89 +++++++++++++++++++++------------------ src/pointer.rs | 3 +- src/pretty_clif.rs | 15 +++++-- src/trap.rs | 3 +- src/value_and_place.rs | 5 +-- 13 files changed, 117 insertions(+), 102 deletions(-) diff --git a/src/abi/comments.rs b/src/abi/comments.rs index c3cf90e1e70..5fbaed7283a 100644 --- a/src/abi/comments.rs +++ b/src/abi/comments.rs @@ -11,9 +11,11 @@ use cranelift_codegen::entity::EntityRef; use crate::prelude::*; pub(super) fn add_args_header_comment(fx: &mut FunctionCx<'_, '_, '_>) { - fx.add_global_comment( - "kind loc.idx param pass mode ty".to_string(), - ); + if fx.clif_comments.enabled() { + fx.add_global_comment( + "kind loc.idx param pass mode ty".to_string(), + ); + } } pub(super) fn add_arg_comment<'tcx>( @@ -25,6 +27,10 @@ pub(super) fn add_arg_comment<'tcx>( arg_abi_mode: PassMode, arg_layout: TyAndLayout<'tcx>, ) { + if !fx.clif_comments.enabled() { + return; + } + let local = if let Some(local) = local { Cow::Owned(format!("{:?}", local)) } else { @@ -59,10 +65,12 @@ pub(super) fn add_arg_comment<'tcx>( } pub(super) fn add_locals_header_comment(fx: &mut FunctionCx<'_, '_, '_>) { - fx.add_global_comment(String::new()); - fx.add_global_comment( - "kind local ty size align (abi,pref)".to_string(), - ); + if fx.clif_comments.enabled() { + fx.add_global_comment(String::new()); + fx.add_global_comment( + "kind local ty size align (abi,pref)".to_string(), + ); + } } pub(super) fn add_local_place_comments<'tcx>( @@ -70,6 +78,9 @@ pub(super) fn add_local_place_comments<'tcx>( place: CPlace<'tcx>, local: Local, ) { + if !fx.clif_comments.enabled() { + return; + } let TyAndLayout { ty, layout } = place.layout(); let rustc_target::abi::Layout { size, align, abi: _, variants: _, fields: _, largest_niche: _ } = layout; @@ -90,7 +101,7 @@ pub(super) fn add_local_place_comments<'tcx>( } else { Cow::Borrowed("") }; - match ptr.base_and_offset() { + match ptr.debug_base_and_offset() { (crate::pointer::PointerBase::Addr(addr), offset) => { ("reuse", format!("storage={}{}{}", addr, offset, meta).into()) } diff --git a/src/abi/mod.rs b/src/abi/mod.rs index c79889f8ca1..2328d40111a 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -1,6 +1,5 @@ //! Handling of everything related to the calling convention. Also fills `fx.local_map`. -#[cfg(debug_assertions)] mod comments; mod pass_mode; mod returning; @@ -75,8 +74,9 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { let func_id = import_function(self.tcx, self.cx.module, inst); let func_ref = self.cx.module.declare_func_in_func(func_id, &mut self.bcx.func); - #[cfg(debug_assertions)] - self.add_comment(func_ref, format!("{:?}", inst)); + if self.clif_comments.enabled() { + self.add_comment(func_ref, format!("{:?}", inst)); + } func_ref } @@ -92,8 +92,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { let func_id = self.cx.module.declare_function(&name, Linkage::Import, &sig).unwrap(); let func_ref = self.cx.module.declare_func_in_func(func_id, &mut self.bcx.func); let call_inst = self.bcx.ins().call(func_ref, args); - #[cfg(debug_assertions)] - { + if self.clif_comments.enabled() { self.add_comment(call_inst, format!("easy_call {}", name)); } let results = self.bcx.inst_results(call_inst); @@ -149,7 +148,6 @@ fn make_local_place<'tcx>( CPlace::new_stack_slot(fx, layout) }; - #[cfg(debug_assertions)] self::comments::add_local_place_comments(fx, place, local); place @@ -163,7 +161,6 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ let ssa_analyzed = crate::analyze::analyze(fx); - #[cfg(debug_assertions)] self::comments::add_args_header_comment(fx); let mut block_params_iter = fx.bcx.func.dfg.block_params(start_block).to_vec().into_iter(); @@ -228,7 +225,6 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ fx.fn_abi = Some(fn_abi); assert!(block_params_iter.next().is_none(), "arg_value left behind"); - #[cfg(debug_assertions)] self::comments::add_locals_header_comment(fx); for (local, arg_kind, ty) in func_params { @@ -256,7 +252,6 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ CPlace::for_ptr(addr, val.layout()) }; - #[cfg(debug_assertions)] self::comments::add_local_place_comments(fx, place, local); assert_eq!(fx.local_map.push(place), local); @@ -392,8 +387,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( let (func_ref, first_arg) = match instance { // Trait object call Some(Instance { def: InstanceDef::Virtual(_, idx), .. }) => { - #[cfg(debug_assertions)] - { + if fx.clif_comments.enabled() { let nop_inst = fx.bcx.ins().nop(); fx.add_comment( nop_inst, @@ -414,8 +408,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( // Indirect call None => { - #[cfg(debug_assertions)] - { + if fx.clif_comments.enabled() { let nop_inst = fx.bcx.ins().nop(); fx.add_comment(nop_inst, "indirect call"); } diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs index d58f952f53c..06b52168e65 100644 --- a/src/abi/pass_mode.rs +++ b/src/abi/pass_mode.rs @@ -248,8 +248,8 @@ pub(super) fn adjust_arg_for_abi<'tcx>( /// as necessary. pub(super) fn cvalue_for_param<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, - #[cfg_attr(not(debug_assertions), allow(unused_variables))] local: Option, - #[cfg_attr(not(debug_assertions), allow(unused_variables))] local_field: Option, + local: Option, + local_field: Option, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, block_params_iter: &mut impl Iterator, ) -> Option> { @@ -263,7 +263,6 @@ pub(super) fn cvalue_for_param<'tcx>( }) .collect::>(); - #[cfg(debug_assertions)] crate::abi::comments::add_arg_comment( fx, "arg", diff --git a/src/abi/returning.rs b/src/abi/returning.rs index 9fa066df69b..b68c3a053b3 100644 --- a/src/abi/returning.rs +++ b/src/abi/returning.rs @@ -84,10 +84,6 @@ pub(super) fn codegen_return_param<'tcx>( } }; - #[cfg(not(debug_assertions))] - let _ = ret_param; - - #[cfg(debug_assertions)] crate::abi::comments::add_arg_comment( fx, "ret", diff --git a/src/base.rs b/src/base.rs index 0a7734d6a04..76425309ed5 100644 --- a/src/base.rs +++ b/src/base.rs @@ -219,8 +219,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) { codegen_stmt(fx, block, stmt); } - #[cfg(debug_assertions)] - { + if fx.clif_comments.enabled() { let mut terminator_head = "\n".to_string(); bb_data.terminator().kind.fmt_head(&mut terminator_head).unwrap(); let inst = fx.bcx.func.layout.last_inst(block).unwrap(); @@ -433,12 +432,14 @@ fn codegen_stmt<'tcx>( fx.set_debug_loc(stmt.source_info); - #[cfg(false_debug_assertions)] + #[cfg(disabled)] match &stmt.kind { StatementKind::StorageLive(..) | StatementKind::StorageDead(..) => {} // Those are not very useful _ => { - let inst = fx.bcx.func.layout.last_inst(cur_block).unwrap(); - fx.add_comment(inst, format!("{:?}", stmt)); + if fx.clif_comments.enabled() { + let inst = fx.bcx.func.layout.last_inst(cur_block).unwrap(); + fx.add_comment(inst, format!("{:?}", stmt)); + } } } diff --git a/src/common.rs b/src/common.rs index 6a4a6744a5c..b5874f62535 100644 --- a/src/common.rs +++ b/src/common.rs @@ -361,8 +361,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { let _ = self.cx.module.define_data(msg_id, &data_ctx); let local_msg_id = self.cx.module.declare_data_in_func(msg_id, self.bcx.func); - #[cfg(debug_assertions)] - { + if self.clif_comments.enabled() { self.add_comment(local_msg_id, msg); } self.bcx.ins().global_value(self.pointer_type, local_msg_id) diff --git a/src/constant.rs b/src/constant.rs index b0639cf9e15..2f0687b0364 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -82,8 +82,9 @@ pub(crate) fn codegen_tls_ref<'tcx>( ) -> CValue<'tcx> { let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - #[cfg(debug_assertions)] - fx.add_comment(local_data_id, format!("tls {:?}", def_id)); + 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); CValue::by_val(tls_ptr, layout) } @@ -95,8 +96,9 @@ fn codegen_static_ref<'tcx>( ) -> CPlace<'tcx> { let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - #[cfg(debug_assertions)] - fx.add_comment(local_data_id, format!("{:?}", def_id)); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("{:?}", def_id)); + } let global_ptr = fx.bcx.ins().global_value(fx.pointer_type, local_data_id); assert!(!layout.is_unsized(), "unsized statics aren't supported"); assert!( @@ -182,8 +184,9 @@ pub(crate) fn codegen_const_value<'tcx>( data_id_for_alloc_id(fx.cx.module, ptr.alloc_id, alloc.mutability); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - #[cfg(debug_assertions)] - fx.add_comment(local_data_id, format!("{:?}", ptr.alloc_id)); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("{:?}", ptr.alloc_id)); + } fx.bcx.ins().global_value(fx.pointer_type, local_data_id) } Some(GlobalAlloc::Function(instance)) => { @@ -198,8 +201,9 @@ pub(crate) fn codegen_const_value<'tcx>( let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - #[cfg(debug_assertions)] - fx.add_comment(local_data_id, format!("{:?}", def_id)); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("{:?}", def_id)); + } fx.bcx.ins().global_value(fx.pointer_type, local_data_id) } None => bug!("missing allocation {:?}", ptr.alloc_id), @@ -240,8 +244,9 @@ fn pointer_for_allocation<'tcx>( let data_id = data_id_for_alloc_id(fx.cx.module, alloc_id, alloc.mutability); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - #[cfg(debug_assertions)] - fx.add_comment(local_data_id, format!("{:?}", alloc_id)); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("{:?}", alloc_id)); + } let global_ptr = fx.bcx.ins().global_value(fx.pointer_type, local_data_id); crate::pointer::Pointer::new(global_ptr) } diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 33234f820aa..1fb5e86aed7 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -197,8 +197,9 @@ fn call_inline_asm<'tcx>( offset: None, size: u32::try_from(slot_size.bytes()).unwrap(), }); - #[cfg(debug_assertions)] - fx.add_comment(stack_slot, "inline asm scratch slot"); + if fx.clif_comments.enabled() { + fx.add_comment(stack_slot, "inline asm scratch slot"); + } let inline_asm_func = fx .cx @@ -214,8 +215,9 @@ fn call_inline_asm<'tcx>( ) .unwrap(); let inline_asm_func = fx.cx.module.declare_func_in_func(inline_asm_func, &mut fx.bcx.func); - #[cfg(debug_assertions)] - fx.add_comment(inline_asm_func, asm_name); + if fx.clif_comments.enabled() { + fx.add_comment(inline_asm_func, asm_name); + } for (_reg, offset, value) in inputs { fx.bcx.ins().stack_store(value, stack_slot, i32::try_from(offset.bytes()).unwrap()); diff --git a/src/optimize/stack2reg.rs b/src/optimize/stack2reg.rs index d111f37f5e4..8bb02a3e558 100644 --- a/src/optimize/stack2reg.rs +++ b/src/optimize/stack2reg.rs @@ -181,7 +181,6 @@ impl<'a> OptimizeContext<'a> { pub(super) fn optimize_function( ctx: &mut Context, - #[cfg_attr(not(debug_assertions), allow(unused_variables))] clif_comments: &mut crate::pretty_clif::CommentWriter, ) { combine_stack_addr_with_load_store(&mut ctx.func); @@ -192,8 +191,7 @@ pub(super) fn optimize_function( remove_unused_stack_addr_and_stack_load(&mut opt_ctx); - #[cfg(debug_assertions)] - { + if clif_comments.enabled() { for (&OrdStackSlot(stack_slot), usage) in &opt_ctx.stack_slot_usage_map { clif_comments.add_comment(stack_slot, format!("used by: {:?}", usage)); } @@ -209,25 +207,27 @@ pub(super) fn optimize_function( for load in users.stack_load.clone().into_iter() { let potential_stores = users.potential_stores_for_load(&opt_ctx.ctx, load); - #[cfg(debug_assertions)] - for &store in &potential_stores { - clif_comments.add_comment( - load, - format!( - "Potential store -> load forwarding {} -> {} ({:?}, {:?})", - opt_ctx.ctx.func.dfg.display_inst(store, None), - opt_ctx.ctx.func.dfg.display_inst(load, None), - spatial_overlap(&opt_ctx.ctx.func, store, load), - temporal_order(&opt_ctx.ctx, store, load), - ), - ); + if clif_comments.enabled() { + for &store in &potential_stores { + clif_comments.add_comment( + load, + format!( + "Potential store -> load forwarding {} -> {} ({:?}, {:?})", + opt_ctx.ctx.func.dfg.display_inst(store, None), + opt_ctx.ctx.func.dfg.display_inst(load, None), + spatial_overlap(&opt_ctx.ctx.func, store, load), + temporal_order(&opt_ctx.ctx, store, load), + ), + ); + } } match *potential_stores { [] => { - #[cfg(debug_assertions)] - clif_comments - .add_comment(load, "[BUG?] Reading uninitialized memory".to_string()); + if clif_comments.enabled() { + clif_comments + .add_comment(load, "[BUG?] Reading uninitialized memory".to_string()); + } } [store] if spatial_overlap(&opt_ctx.ctx.func, store, load) == SpatialOverlap::Full @@ -237,9 +237,12 @@ pub(super) fn optimize_function( // Only one store could have been the origin of the value. let stored_value = opt_ctx.ctx.func.dfg.inst_args(store)[0]; - #[cfg(debug_assertions)] - clif_comments - .add_comment(load, format!("Store to load forward {} -> {}", store, load)); + if clif_comments.enabled() { + clif_comments.add_comment( + load, + format!("Store to load forward {} -> {}", store, load), + ); + } users.change_load_to_alias(&mut opt_ctx.ctx.func, load, stored_value); } @@ -250,33 +253,35 @@ pub(super) fn optimize_function( for store in users.stack_store.clone().into_iter() { let potential_loads = users.potential_loads_of_store(&opt_ctx.ctx, store); - #[cfg(debug_assertions)] - for &load in &potential_loads { - clif_comments.add_comment( - store, - format!( - "Potential load from store {} <- {} ({:?}, {:?})", - opt_ctx.ctx.func.dfg.display_inst(load, None), - opt_ctx.ctx.func.dfg.display_inst(store, None), - spatial_overlap(&opt_ctx.ctx.func, store, load), - temporal_order(&opt_ctx.ctx, store, load), - ), - ); + if clif_comments.enabled() { + for &load in &potential_loads { + clif_comments.add_comment( + store, + format!( + "Potential load from store {} <- {} ({:?}, {:?})", + opt_ctx.ctx.func.dfg.display_inst(load, None), + opt_ctx.ctx.func.dfg.display_inst(store, None), + spatial_overlap(&opt_ctx.ctx.func, store, load), + temporal_order(&opt_ctx.ctx, store, load), + ), + ); + } } if potential_loads.is_empty() { // Never loaded; can safely remove all stores and the stack slot. // FIXME also remove stores when there is always a next store before a load. - #[cfg(debug_assertions)] - clif_comments.add_comment( - store, - format!( - "Remove dead stack store {} of {}", - opt_ctx.ctx.func.dfg.display_inst(store, None), - stack_slot.0 - ), - ); + if clif_comments.enabled() { + clif_comments.add_comment( + store, + format!( + "Remove dead stack store {} of {}", + opt_ctx.ctx.func.dfg.display_inst(store, None), + stack_slot.0 + ), + ); + } users.remove_dead_store(&mut opt_ctx.ctx.func, store); } diff --git a/src/pointer.rs b/src/pointer.rs index 88a78f3214d..31d827f83bf 100644 --- a/src/pointer.rs +++ b/src/pointer.rs @@ -39,8 +39,7 @@ impl Pointer { Pointer { base: PointerBase::Dangling(align), offset: Offset32::new(0) } } - #[cfg(debug_assertions)] - pub(crate) fn base_and_offset(self) -> (PointerBase, Offset32) { + pub(crate) fn debug_base_and_offset(self) -> (PointerBase, Offset32) { (self.base, self.offset) } diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index 9c91b92e515..87f0e0c3738 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -69,13 +69,15 @@ use crate::prelude::*; #[derive(Debug)] pub(crate) struct CommentWriter { + enabled: bool, global_comments: Vec, entity_comments: FxHashMap, } impl CommentWriter { pub(crate) fn new<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self { - let global_comments = if cfg!(debug_assertions) { + let enabled = should_write_ir(tcx); + let global_comments = if enabled { vec![ format!("symbol {}", tcx.symbol_name(instance).name), format!("instance {:?}", instance), @@ -86,13 +88,17 @@ impl CommentWriter { vec![] }; - CommentWriter { global_comments, entity_comments: FxHashMap::default() } + CommentWriter { enabled, global_comments, entity_comments: FxHashMap::default() } } } -#[cfg(debug_assertions)] impl CommentWriter { + pub(crate) fn enabled(&self) -> bool { + self.enabled + } + pub(crate) fn add_global_comment>(&mut self, comment: S) { + debug_assert!(self.enabled); self.global_comments.push(comment.into()); } @@ -101,6 +107,8 @@ impl CommentWriter { entity: E, comment: S, ) { + debug_assert!(self.enabled); + use std::collections::hash_map::Entry; match self.entity_comments.entry(entity.into()) { Entry::Occupied(mut occ) => { @@ -179,7 +187,6 @@ impl FuncWriter for &'_ CommentWriter { } } -#[cfg(debug_assertions)] impl FunctionCx<'_, '_, '_> { pub(crate) fn add_global_comment>(&mut self, comment: S) { self.clif_comments.add_global_comment(comment); diff --git a/src/trap.rs b/src/trap.rs index bb63d72addf..1ab0703e981 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -17,8 +17,7 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) { ) .unwrap(); let puts = fx.cx.module.declare_func_in_func(puts, &mut fx.bcx.func); - #[cfg(debug_assertions)] - { + if fx.clif_comments.enabled() { fx.add_comment(puts, "puts"); } diff --git a/src/value_and_place.rs b/src/value_and_place.rs index c2c59773848..1a6a301a45b 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -413,7 +413,7 @@ impl<'tcx> CPlace<'tcx> { self, fx: &mut FunctionCx<'_, '_, 'tcx>, from: CValue<'tcx>, - #[cfg_attr(not(debug_assertions), allow(unused_variables))] method: &'static str, + method: &'static str, ) { fn transmute_value<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, @@ -461,8 +461,7 @@ impl<'tcx> CPlace<'tcx> { assert_eq!(self.layout().size, from.layout().size); - #[cfg(debug_assertions)] - { + if fx.clif_comments.enabled() { use cranelift_codegen::cursor::{Cursor, CursorPosition}; let cur_block = match fx.bcx.cursor().position() { CursorPosition::After(block) => block, From d194c707c82198864cd1493a9e104f904d354e16 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 18:59:01 +0100 Subject: [PATCH 027/370] Use jemalloc --- Cargo.toml | 3 ++- src/bin/cg_clif.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9861af1f8ea..79c9b57532d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,9 +35,10 @@ smallvec = "1.6.1" #gimli = { path = "../" } [features] -default = ["jit", "inline_asm"] +default = ["jit", "inline_asm", "jemalloc"] jit = ["cranelift-jit", "libloading"] inline_asm = [] +jemalloc = [] [profile.dev] # By compiling dependencies with optimizations, performing tests gets much faster. diff --git a/src/bin/cg_clif.rs b/src/bin/cg_clif.rs index 983839d48d2..b8d6958b3b2 100644 --- a/src/bin/cg_clif.rs +++ b/src/bin/cg_clif.rs @@ -1,5 +1,7 @@ #![feature(rustc_private)] +#[cfg(feature = "jemalloc")] +extern crate jemalloc_sys; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_interface; @@ -33,6 +35,46 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks { } fn main() { + // Pull in jemalloc when enabled. + // + // Note that we're pulling in a static copy of jemalloc which means that to + // pull it in we need to actually reference its symbols for it to get + // linked. The two crates we link to here, std and rustc_driver, are both + // dynamic libraries. That means to pull in jemalloc we need to actually + // reference allocation symbols one way or another (as this file is the only + // object code in the rustc executable). + #[cfg(feature = "jemalloc")] + { + use std::os::raw::{c_int, c_void}; + #[used] + static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; + #[used] + static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = + jemalloc_sys::posix_memalign; + #[used] + static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; + #[used] + static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; + #[used] + static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; + #[used] + static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; + + // On OSX, jemalloc doesn't directly override malloc/free, but instead + // registers itself with the allocator's zone APIs in a ctor. However, + // the linker doesn't seem to consider ctors as "used" when statically + // linking, so we need to explicitly depend on the function. + #[cfg(target_os = "macos")] + { + extern "C" { + fn _rjem_je_zone_register(); + } + + #[used] + static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; + } + } + let start_time = std::time::Instant::now(); let start_rss = get_resident_set_size(); rustc_driver::init_rustc_env_logger(); From 76bb1f173f35c4d0fa4de6c7d4651a1367e61bdb Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 19:19:29 +0100 Subject: [PATCH 028/370] Move the more advanced ways to use cg_clif to usage.md --- Readme.md | 59 ++++----------------------------------------- docs/usage.md | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 55 deletions(-) create mode 100644 docs/usage.md diff --git a/Readme.md b/Readme.md index 6fa5eebdc2f..6848ce78090 100644 --- a/Readme.md +++ b/Readme.md @@ -34,70 +34,19 @@ rustc_codegen_cranelift can be used as a near-drop-in replacement for `cargo bui Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`prepare.sh` and `build.sh` or `test.sh`). -### Cargo - In the directory with your project (where you can do the usual `cargo build`), run: ```bash -$ $cg_clif_dir/build/cargo.sh run +$ $cg_clif_dir/build/cargo.sh build ``` -This should build and run your project with rustc_codegen_cranelift instead of the usual LLVM backend. +This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend. -### Rustc - -> You should prefer using the Cargo method. - -```bash -$ $cg_clif_dir/build/bin/cg_clif my_crate.rs -``` - -### Jit mode - -In jit mode cg_clif will immediately execute your code without creating an executable file. - -> This requires all dependencies to be available as dynamic library. -> The jit mode will probably need cargo integration to make this possible. - -```bash -$ $cg_clif_dir/build/cargo.sh jit -``` - -or - -```bash -$ $cg_clif_dir/build/bin/cg_clif -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.rs -``` - -There is also an experimental lazy jit mode. In this mode functions are only compiled once they are -first called. It currently does not work with multi-threaded programs. When a not yet compiled -function is called from another thread than the main thread, you will get an ICE. - -```bash -$ $cg_clif_dir/build/cargo.sh lazy-jit -``` - -### Shell - -These are a few functions that allow you to easily run rust code from the shell using cg_clif as jit. - -```bash -function jit_naked() { - echo "$@" | $cg_clif_dir/build/bin/cg_clif - -Cllvm-args=mode=jit -Cprefer-dynamic -} - -function jit() { - jit_naked "fn main() { $@ }" -} - -function jit_calc() { - jit 'println!("0x{:x}", ' $@ ');'; -} -``` +For additional ways to use rustc_codegen_cranelift like the JIT mode see [full_usage.md](docs/full_usage.md). ## Env vars -[see env_vars.md](docs/env_vars.md) +See [env_vars.md](docs/env_vars.md) for all env vars used by rustc_codegen_cranelift. ## Not yet supported diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 00000000000..defe16ab3af --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,66 @@ +# Usage + +rustc_codegen_cranelift can be used as a near-drop-in replacement for `cargo build` or `cargo run` for existing projects. + +Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`prepare.sh` and `build.sh` or `test.sh`). + +## Cargo + +In the directory with your project (where you can do the usual `cargo build`), run: + +```bash +$ $cg_clif_dir/build/cargo.sh build +``` + +This will build and run your project with rustc_codegen_cranelift instead of the usual LLVM backend. + +## Rustc + +> You should prefer using the Cargo method. + +```bash +$ $cg_clif_dir/build/bin/cg_clif my_crate.rs +``` + +## Jit mode + +In jit mode cg_clif will immediately execute your code without creating an executable file. + +> This requires all dependencies to be available as dynamic library. +> The jit mode will probably need cargo integration to make this possible. + +```bash +$ $cg_clif_dir/build/cargo.sh jit +``` + +or + +```bash +$ $cg_clif_dir/build/bin/cg_clif -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.rs +``` + +There is also an experimental lazy jit mode. In this mode functions are only compiled once they are +first called. It currently does not work with multi-threaded programs. When a not yet compiled +function is called from another thread than the main thread, you will get an ICE. + +```bash +$ $cg_clif_dir/build/cargo.sh lazy-jit +``` + +## Shell + +These are a few functions that allow you to easily run rust code from the shell using cg_clif as jit. + +```bash +function jit_naked() { + echo "$@" | $cg_clif_dir/build/bin/cg_clif - -Cllvm-args=mode=jit -Cprefer-dynamic +} + +function jit() { + jit_naked "fn main() { $@ }" +} + +function jit_calc() { + jit 'println!("0x{:x}", ' $@ ');'; +} +``` From be3aa0689e7c5e58b1d8daa2e2b2ba90d5eccc46 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 19:21:30 +0100 Subject: [PATCH 029/370] Revert "Use jemalloc" This reverts commit d194c707c82198864cd1493a9e104f904d354e16. It fails the bootstrap test as jemalloc_sys is not built --- Cargo.toml | 3 +-- src/bin/cg_clif.rs | 42 ------------------------------------------ 2 files changed, 1 insertion(+), 44 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 79c9b57532d..9861af1f8ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,10 +35,9 @@ smallvec = "1.6.1" #gimli = { path = "../" } [features] -default = ["jit", "inline_asm", "jemalloc"] +default = ["jit", "inline_asm"] jit = ["cranelift-jit", "libloading"] inline_asm = [] -jemalloc = [] [profile.dev] # By compiling dependencies with optimizations, performing tests gets much faster. diff --git a/src/bin/cg_clif.rs b/src/bin/cg_clif.rs index b8d6958b3b2..983839d48d2 100644 --- a/src/bin/cg_clif.rs +++ b/src/bin/cg_clif.rs @@ -1,7 +1,5 @@ #![feature(rustc_private)] -#[cfg(feature = "jemalloc")] -extern crate jemalloc_sys; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_interface; @@ -35,46 +33,6 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks { } fn main() { - // Pull in jemalloc when enabled. - // - // Note that we're pulling in a static copy of jemalloc which means that to - // pull it in we need to actually reference its symbols for it to get - // linked. The two crates we link to here, std and rustc_driver, are both - // dynamic libraries. That means to pull in jemalloc we need to actually - // reference allocation symbols one way or another (as this file is the only - // object code in the rustc executable). - #[cfg(feature = "jemalloc")] - { - use std::os::raw::{c_int, c_void}; - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = - jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - // On OSX, jemalloc doesn't directly override malloc/free, but instead - // registers itself with the allocator's zone APIs in a ctor. However, - // the linker doesn't seem to consider ctors as "used" when statically - // linking, so we need to explicitly depend on the function. - #[cfg(target_os = "macos")] - { - extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; - } - } - let start_time = std::time::Instant::now(); let start_rss = get_resident_set_size(); rustc_driver::init_rustc_env_logger(); From 95e4db3e0338ce88b724b41a19ce0fc9d2ed1395 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 19:22:36 +0100 Subject: [PATCH 030/370] More doc fixes --- Readme.md | 2 +- docs/usage.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 6848ce78090..86e62f74478 100644 --- a/Readme.md +++ b/Readme.md @@ -42,7 +42,7 @@ $ $cg_clif_dir/build/cargo.sh build This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend. -For additional ways to use rustc_codegen_cranelift like the JIT mode see [full_usage.md](docs/full_usage.md). +For additional ways to use rustc_codegen_cranelift like the JIT mode see [usage.md](docs/usage.md). ## Env vars diff --git a/docs/usage.md b/docs/usage.md index defe16ab3af..3eee3b554e3 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -12,7 +12,7 @@ In the directory with your project (where you can do the usual `cargo build`), r $ $cg_clif_dir/build/cargo.sh build ``` -This will build and run your project with rustc_codegen_cranelift instead of the usual LLVM backend. +This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend. ## Rustc From 05339134de9d3977002752b79b5f280f33ab1993 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 19:26:11 +0100 Subject: [PATCH 031/370] Add license section to the readme Just in case --- Readme.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Readme.md b/Readme.md index 86e62f74478..ffe1d9a1e65 100644 --- a/Readme.md +++ b/Readme.md @@ -55,3 +55,20 @@ See [env_vars.md](docs/env_vars.md) for all env vars used by rustc_codegen_crane `llvm_asm!` will remain unimplemented forever. `asm!` doesn't yet support reg classes. You have to specify specific registers instead. * SIMD ([tracked here](https://github.com/bjorn3/rustc_codegen_cranelift/issues/171), some basic things work) + +## License + +Licensed under either of + + * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you shall be dual licensed as above, without any +additional terms or conditions. From 341a4863fabe8c67b1b72c6d3183ee824878f950 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 27 Nov 2020 16:52:17 +0100 Subject: [PATCH 032/370] Use the new component dependency option of the rust-toolchain file (take 2) --- prepare.sh | 1 - rust-toolchain | 4 +++- scripts/cargo.sh | 2 +- scripts/rustup.sh | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/prepare.sh b/prepare.sh index ee995ffcfa9..64c097261c9 100755 --- a/prepare.sh +++ b/prepare.sh @@ -1,7 +1,6 @@ #!/usr/bin/env bash set -e -rustup component add rust-src rustc-dev llvm-tools-preview ./build_sysroot/prepare_sysroot_src.sh cargo install hyperfine || echo "Skipping hyperfine install" diff --git a/rust-toolchain b/rust-toolchain index 908ca52135b..495d8ea7734 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1,3 @@ -nightly-2021-03-05 +[toolchain] +channel = "nightly-2021-03-05" +components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/scripts/cargo.sh b/scripts/cargo.sh index 669d2d45b71..1daa5a78f7b 100755 --- a/scripts/cargo.sh +++ b/scripts/cargo.sh @@ -4,7 +4,7 @@ dir=$(dirname "$0") source "$dir/config.sh" # read nightly compiler from rust-toolchain file -TOOLCHAIN=$(cat "$dir/rust-toolchain") +TOOLCHAIN=$(cat "$dir/rust-toolchain" | grep channel | sed "s/channel = \"\(.*\)\"/\1/") cmd=$1 shift || true diff --git a/scripts/rustup.sh b/scripts/rustup.sh index 694945a87c2..fa7557653d8 100755 --- a/scripts/rustup.sh +++ b/scripts/rustup.sh @@ -8,7 +8,7 @@ case $1 in echo "=> Installing new nightly" rustup toolchain install --profile minimal "nightly-${TOOLCHAIN}" # Sanity check to see if the nightly exists - echo "nightly-${TOOLCHAIN}" > rust-toolchain + sed -i "s/\"nightly-.*\"/\"nightly-${TOOLCHAIN}\"/" rust-toolchain rustup component add rustfmt || true echo "=> Uninstalling all old nighlies" From f8b15d85ded26b45aeed62ea541008a91e922096 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 7 Mar 2021 11:51:43 -0500 Subject: [PATCH 033/370] rustdoc: Don't enter an infer_ctxt in get_blanket_impls for impls that aren't blanket impls --- src/librustdoc/clean/blanket_impl.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 4e4e1e5cbce..ec02b48ad9d 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -32,12 +32,8 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { trait_def_id, impl_def_id ); let trait_ref = self.cx.tcx.impl_trait_ref(impl_def_id).unwrap(); - let may_apply = self.cx.tcx.infer_ctxt().enter(|infcx| { - match trait_ref.self_ty().kind() { - ty::Param(_) => {} - _ => return false, - } - + let is_param = matches!(trait_ref.self_ty().kind(), ty::Param(_)); + let may_apply = is_param && self.cx.tcx.infer_ctxt().enter(|infcx| { let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id); let ty = ty.subst(infcx.tcx, substs); let param_env = param_env.subst(infcx.tcx, substs); From aef1e35edc11b3e0ecf7f77bc70c197062023476 Mon Sep 17 00:00:00 2001 From: est31 Date: Tue, 30 Jun 2020 18:58:15 +0200 Subject: [PATCH 034/370] Emit unused externs --- compiler/rustc_errors/src/emitter.rs | 3 +++ compiler/rustc_errors/src/json.rs | 19 +++++++++++++++++++ compiler/rustc_errors/src/lib.rs | 8 ++++++++ compiler/rustc_metadata/src/creader.rs | 4 ++++ 4 files changed, 34 insertions(+) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 9b6f67166bd..dbb71d52e49 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -195,6 +195,9 @@ pub trait Emitter { fn emit_future_breakage_report(&mut self, _diags: Vec<(FutureBreakage, Diagnostic)>) {} + /// Emit list of unused externs + fn emit_unused_externs(&mut self, _unused_externs: &[&str]) {} + /// Checks if should show explanations about "rustc --explain" fn should_show_explain(&self) -> bool { true diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index c27b39a9d62..a1ab98f766e 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -159,6 +159,19 @@ impl Emitter for JsonEmitter { } } + fn emit_unused_externs(&mut self, unused_externs: &[&str]) { + let data = UnusedExterns { unused_extern_names: unused_externs }; + let result = if self.pretty { + writeln!(&mut self.dst, "{}", as_pretty_json(&data)) + } else { + writeln!(&mut self.dst, "{}", as_json(&data)) + } + .and_then(|_| self.dst.flush()); + if let Err(e) = result { + panic!("failed to print unused externs: {:?}", e); + } + } + fn source_map(&self) -> Option<&Lrc> { Some(&self.sm) } @@ -322,6 +335,12 @@ struct FutureIncompatReport { future_incompat_report: Vec, } +#[derive(Encodable)] +struct UnusedExterns<'a, 'b> { + /// List of unused externs by their names. + unused_extern_names: &'a [&'b str], +} + impl Diagnostic { fn from_errors_diagnostic(diag: &crate::Diagnostic, je: &JsonEmitter) -> Diagnostic { let sugg = diag.suggestions.iter().map(|sugg| Diagnostic { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index a0be7442d59..5720e98abc8 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -767,6 +767,10 @@ impl Handler { self.inner.borrow_mut().emitter.emit_future_breakage_report(diags) } + pub fn emit_unused_externs(&self, unused_externs: &[&str]) { + self.inner.borrow_mut().emit_unused_externs(unused_externs) + } + pub fn delay_as_bug(&self, diagnostic: Diagnostic) { self.inner.borrow_mut().delay_as_bug(diagnostic) } @@ -841,6 +845,10 @@ impl HandlerInner { self.emitter.emit_artifact_notification(path, artifact_type); } + fn emit_unused_externs(&mut self, unused_externs: &[&str]) { + self.emitter.emit_unused_externs(unused_externs); + } + fn treat_err_as_bug(&self) -> bool { self.flags.treat_err_as_bug.map_or(false, |c| self.err_count() >= c.get()) } diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index b5506acf735..3f2d312e61b 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -893,6 +893,7 @@ impl<'a> CrateLoader<'a> { fn report_unused_deps(&mut self, krate: &ast::Crate) { // Make a point span rather than covering the whole file let span = krate.span.shrink_to_lo(); + let mut unused_externs = Vec::new(); // Complain about anything left over for (name, entry) in self.sess.opts.externs.iter() { if let ExternLocation::FoundInLibrarySearchDirectories = entry.location { @@ -917,6 +918,7 @@ impl<'a> CrateLoader<'a> { ) } }; + unused_externs.push(name as &str); self.sess.parse_sess.buffer_lint_with_diagnostic( lint::builtin::UNUSED_CRATE_DEPENDENCIES, span, @@ -929,6 +931,8 @@ impl<'a> CrateLoader<'a> { diag, ); } + // FIXME: add gating + self.sess.parse_sess.span_diagnostic.emit_unused_externs(&unused_externs); } pub fn postprocess(&mut self, krate: &ast::Crate) { From 3f2ca47a79911d422fd47ee2a23dd08a9fa42aa9 Mon Sep 17 00:00:00 2001 From: est31 Date: Tue, 30 Jun 2020 20:17:07 +0200 Subject: [PATCH 035/370] Gate the printing on --json=unused-externs --- compiler/rustc_metadata/src/creader.rs | 5 +++-- compiler/rustc_session/src/config.rs | 18 +++++++++++++++--- compiler/rustc_session/src/options.rs | 3 +++ src/librustdoc/config.rs | 2 +- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 3f2d312e61b..7b34374032c 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -931,8 +931,9 @@ impl<'a> CrateLoader<'a> { diag, ); } - // FIXME: add gating - self.sess.parse_sess.span_diagnostic.emit_unused_externs(&unused_externs); + if self.sess.opts.json_unused_externs { + self.sess.parse_sess.span_diagnostic.emit_unused_externs(&unused_externs); + } } pub fn postprocess(&mut self, krate: &ast::Crate) { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f25828e2161..a66201953d6 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -734,6 +734,7 @@ impl Default for Options { remap_path_prefix: Vec::new(), edition: DEFAULT_EDITION, json_artifact_notifications: false, + json_unused_externs: false, pretty: None, } } @@ -1254,11 +1255,12 @@ pub fn parse_color(matches: &getopts::Matches) -> ColorConfig { /// /// The first value returned is how to render JSON diagnostics, and the second /// is whether or not artifact notifications are enabled. -pub fn parse_json(matches: &getopts::Matches) -> (HumanReadableErrorType, bool) { +pub fn parse_json(matches: &getopts::Matches) -> (HumanReadableErrorType, bool, bool) { let mut json_rendered: fn(ColorConfig) -> HumanReadableErrorType = HumanReadableErrorType::Default; let mut json_color = ColorConfig::Never; let mut json_artifact_notifications = false; + let mut json_unused_externs = false; for option in matches.opt_strs("json") { // For now conservatively forbid `--color` with `--json` since `--json` // won't actually be emitting any colors and anything colorized is @@ -1275,6 +1277,7 @@ pub fn parse_json(matches: &getopts::Matches) -> (HumanReadableErrorType, bool) "diagnostic-short" => json_rendered = HumanReadableErrorType::Short, "diagnostic-rendered-ansi" => json_color = ColorConfig::Always, "artifacts" => json_artifact_notifications = true, + "unused-externs" => json_unused_externs = true, s => early_error( ErrorOutputType::default(), &format!("unknown `--json` option `{}`", s), @@ -1282,7 +1285,7 @@ pub fn parse_json(matches: &getopts::Matches) -> (HumanReadableErrorType, bool) } } } - (json_rendered(json_color), json_artifact_notifications) + (json_rendered(json_color), json_artifact_notifications, json_unused_externs) } /// Parses the `--error-format` flag. @@ -1860,7 +1863,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let edition = parse_crate_edition(matches); - let (json_rendered, json_artifact_notifications) = parse_json(matches); + let (json_rendered, json_artifact_notifications, json_unused_externs) = parse_json(matches); let error_format = parse_error_format(matches, color, json_rendered); @@ -1873,6 +1876,14 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let mut debugging_opts = build_debugging_options(matches, error_format); check_debug_option_stability(&debugging_opts, error_format, json_rendered); + if !debugging_opts.unstable_options && json_unused_externs { + early_error( + error_format, + "the `-Z unstable-options` flag must also be passed to enable \ + the flag `--json=unused-externs`", + ); + } + let output_types = parse_output_types(&debugging_opts, matches, error_format); let mut cg = build_codegen_options(matches, error_format); @@ -2050,6 +2061,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { remap_path_prefix, edition, json_artifact_notifications, + json_unused_externs, pretty, } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 79bbad8307b..cfe29d40b74 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -147,6 +147,9 @@ top_level_options!( // by the compiler. json_artifact_notifications: bool [TRACKED], + // `true` if we're emitting a JSON blob containing the unused externs + json_unused_externs: bool [UNTRACKED], + pretty: Option [UNTRACKED], } ); diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index ecb6378f31f..5d6d5aaec14 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -323,7 +323,7 @@ impl Options { } let color = config::parse_color(&matches); - let (json_rendered, _artifacts) = config::parse_json(&matches); + let (json_rendered, ..) = config::parse_json(&matches); let error_format = config::parse_error_format(&matches, color, json_rendered); let codegen_options = build_codegen_options(matches, error_format); From 2d5200605f18717efcb5483cfd2aece167cab7ce Mon Sep 17 00:00:00 2001 From: est31 Date: Sun, 5 Jul 2020 19:35:46 +0200 Subject: [PATCH 036/370] Make parse_json return JsonConfig --- compiler/rustc_session/src/config.rs | 19 ++++++++++++++++--- src/librustdoc/config.rs | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index a66201953d6..433b87aa3c6 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1251,11 +1251,18 @@ pub fn parse_color(matches: &getopts::Matches) -> ColorConfig { } } +/// Possible json config files +pub struct JsonConfig { + pub json_rendered: HumanReadableErrorType, + pub json_artifact_notifications: bool, + pub json_unused_externs: bool, +} + /// Parse the `--json` flag. /// /// The first value returned is how to render JSON diagnostics, and the second /// is whether or not artifact notifications are enabled. -pub fn parse_json(matches: &getopts::Matches) -> (HumanReadableErrorType, bool, bool) { +pub fn parse_json(matches: &getopts::Matches) -> JsonConfig { let mut json_rendered: fn(ColorConfig) -> HumanReadableErrorType = HumanReadableErrorType::Default; let mut json_color = ColorConfig::Never; @@ -1285,7 +1292,12 @@ pub fn parse_json(matches: &getopts::Matches) -> (HumanReadableErrorType, bool, } } } - (json_rendered(json_color), json_artifact_notifications, json_unused_externs) + + JsonConfig { + json_rendered: json_rendered(json_color), + json_artifact_notifications, + json_unused_externs, + } } /// Parses the `--error-format` flag. @@ -1863,7 +1875,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let edition = parse_crate_edition(matches); - let (json_rendered, json_artifact_notifications, json_unused_externs) = parse_json(matches); + let JsonConfig { json_rendered, json_artifact_notifications, json_unused_externs } = + parse_json(matches); let error_format = parse_error_format(matches, color, json_rendered); diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 5d6d5aaec14..112fe230916 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -323,7 +323,7 @@ impl Options { } let color = config::parse_color(&matches); - let (json_rendered, ..) = config::parse_json(&matches); + let config::JsonConfig { json_rendered, .. } = config::parse_json(&matches); let error_format = config::parse_error_format(&matches, color, json_rendered); let codegen_options = build_codegen_options(matches, error_format); From 13371b59ee918445ede03cebb741539db807e0e7 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 1 Aug 2020 12:57:35 +0200 Subject: [PATCH 037/370] Make doctests collect and emit the unused externs --- compiler/rustc_session/src/config.rs | 4 ++ src/librustdoc/config.rs | 6 +- src/librustdoc/doctest.rs | 85 ++++++++++++++++++++++++++-- 3 files changed, 88 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 433b87aa3c6..2965fe8e1e8 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -485,6 +485,10 @@ impl Externs { pub fn iter(&self) -> BTreeMapIter<'_, String, ExternEntry> { self.0.iter() } + + pub fn len(&self) -> usize { + self.0.len() + } } impl ExternEntry { diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 112fe230916..61035684ef3 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -153,6 +153,8 @@ crate struct Options { /// If this option is set to `true`, rustdoc will only run checks and not generate /// documentation. crate run_check: bool, + /// Whether doctests should emit unused externs + crate json_unused_externs: bool, } impl fmt::Debug for Options { @@ -323,7 +325,8 @@ impl Options { } let color = config::parse_color(&matches); - let config::JsonConfig { json_rendered, .. } = config::parse_json(&matches); + let config::JsonConfig { json_rendered, json_unused_externs, .. } = + config::parse_json(&matches); let error_format = config::parse_error_format(&matches, color, json_rendered); let codegen_options = build_codegen_options(matches, error_format); @@ -644,6 +647,7 @@ impl Options { }, crate_name, output_format, + json_unused_externs, }) } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 27ce064669d..50cdf46ce4f 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1,5 +1,5 @@ use rustc_ast as ast; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_errors::{ColorConfig, ErrorReported}; use rustc_hir as hir; @@ -23,6 +23,8 @@ use std::panic; use std::path::PathBuf; use std::process::{self, Command, Stdio}; use std::str; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::{Arc, Mutex}; use crate::clean::Attributes; use crate::config::Options; @@ -103,8 +105,10 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { let mut test_args = options.test_args.clone(); let display_warnings = options.display_warnings; + let externs = options.externs.clone(); + let json_unused_externs = options.json_unused_externs; - let tests = interface::run_compiler(config, |compiler| { + let res = interface::run_compiler(config, |compiler| { compiler.enter(|queries| { let lower_to_hir = queries.lower_to_hir()?; @@ -147,12 +151,15 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { }); compiler.session().abort_if_errors(); - let ret: Result<_, ErrorReported> = Ok(collector.tests); + let unused_extern_reports = collector.unused_extern_reports.clone(); + let compiling_test_count = collector.compiling_test_count.load(Ordering::SeqCst); + let ret: Result<_, ErrorReported> = + Ok((collector.tests, unused_extern_reports, compiling_test_count)); ret }) }); - let tests = match tests { - Ok(tests) => tests, + let (tests, unused_extern_reports, compiling_test_count) = match res { + Ok(res) => res, Err(ErrorReported) => return Err(ErrorReported), }; @@ -164,6 +171,29 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { Some(testing::Options::new().display_output(display_warnings)), ); + // Collect and warn about unused externs, but only if we've gotten + // reports for each doctest + if json_unused_externs { + let unused_extern_reports: Vec<_> = + std::mem::take(&mut unused_extern_reports.lock().unwrap()); + if unused_extern_reports.len() == compiling_test_count { + let extern_names = externs.iter().map(|(name, _)| name).collect::>(); + let mut unused_extern_names = unused_extern_reports + .iter() + .map(|uexts| uexts.unused_extern_names.iter().collect::>()) + .fold(extern_names, |uextsa, uextsb| { + uextsa.intersection(&uextsb).map(|v| *v).collect::>() + }) + .iter() + .map(|v| (*v).clone()) + .collect::>(); + unused_extern_names.sort(); + let unused_extern_json = + serde_json::to_string(&UnusedExterns { unused_extern_names }).unwrap(); + eprintln!("{}", unused_extern_json); + } + } + Ok(()) } @@ -233,6 +263,12 @@ impl DirState { } } +#[derive(serde::Serialize, serde::Deserialize)] +struct UnusedExterns { + /// List of unused externs by their names. + unused_extern_names: Vec, +} + fn run_test( test: &str, cratename: &str, @@ -251,6 +287,7 @@ fn run_test( outdir: DirState, path: PathBuf, test_id: &str, + report_unused_externs: impl Fn(UnusedExterns), ) -> Result<(), TestFailure> { let (test, line_offset, supports_color) = make_test(test, Some(cratename), as_test_harness, opts, edition, Some(test_id)); @@ -276,6 +313,11 @@ fn run_test( if as_test_harness { compiler.arg("--test"); } + if options.json_unused_externs && !compile_fail { + compiler.arg("--error-format=json"); + compiler.arg("--json").arg("unused-externs"); + compiler.arg("-Z").arg("unstable-options"); + } for lib_str in &options.lib_strs { compiler.arg("-L").arg(&lib_str); } @@ -335,7 +377,26 @@ fn run_test( eprint!("{}", self.0); } } - let out = str::from_utf8(&output.stderr).unwrap(); + let mut out_lines = str::from_utf8(&output.stderr) + .unwrap() + .lines() + .filter(|l| { + if let Ok(uext) = serde_json::from_str::(l) { + report_unused_externs(uext); + false + } else { + true + } + }) + .collect::>(); + + // Add a \n to the end to properly terminate the last line, + // but only if there was output to be printed + if out_lines.len() > 0 { + out_lines.push(""); + } + + let out = out_lines.join("\n"); let _bomb = Bomb(&out); match (output.status.success(), compile_fail) { (true, true) => { @@ -719,6 +780,8 @@ crate struct Collector { source_map: Option>, filename: Option, visited_tests: FxHashMap<(String, usize), usize>, + unused_extern_reports: Arc>>, + compiling_test_count: AtomicUsize, } impl Collector { @@ -743,6 +806,8 @@ impl Collector { source_map, filename, visited_tests: FxHashMap::default(), + unused_extern_reports: Default::default(), + compiling_test_count: AtomicUsize::new(0), } } @@ -789,6 +854,10 @@ impl Tester for Collector { let runtool_args = self.options.runtool_args.clone(); let target = self.options.target.clone(); let target_str = target.to_string(); + let unused_externs = self.unused_extern_reports.clone(); + if !config.compile_fail { + self.compiling_test_count.fetch_add(1, Ordering::SeqCst); + } // FIXME(#44940): if doctests ever support path remapping, then this filename // needs to be the result of `SourceMap::span_to_unmapped_path`. @@ -844,6 +913,9 @@ impl Tester for Collector { test_type: testing::TestType::DocTest, }, testfn: testing::DynTestFn(box move || { + let report_unused_externs = |uext| { + unused_externs.lock().unwrap().push(uext); + }; let res = run_test( &test, &cratename, @@ -862,6 +934,7 @@ impl Tester for Collector { outdir, path, &test_id, + report_unused_externs, ); if let Err(err) = res { From 3a62eb74db63f1b49d5e00c32192498abaf1640f Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 10 Aug 2020 01:57:35 +0200 Subject: [PATCH 038/370] Emit the lint level of the unused-crate-dependencies Also, turn off the lint when the unused dependencies json flag is specified so that cargo doesn't have to supress the lint --- compiler/rustc_errors/src/emitter.rs | 2 +- compiler/rustc_errors/src/json.rs | 10 ++++--- compiler/rustc_errors/src/lib.rs | 8 +++--- compiler/rustc_interface/src/passes.rs | 7 +++++ compiler/rustc_metadata/src/creader.rs | 36 ++++++++++++++++++++------ src/librustdoc/doctest.rs | 22 ++++++++++++++-- 6 files changed, 66 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index dbb71d52e49..2b6dec905f1 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -196,7 +196,7 @@ pub trait Emitter { fn emit_future_breakage_report(&mut self, _diags: Vec<(FutureBreakage, Diagnostic)>) {} /// Emit list of unused externs - fn emit_unused_externs(&mut self, _unused_externs: &[&str]) {} + fn emit_unused_externs(&mut self, _lint_level: &str, _unused_externs: &[&str]) {} /// Checks if should show explanations about "rustc --explain" fn should_show_explain(&self) -> bool { diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index a1ab98f766e..8511b51e3bf 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -159,8 +159,8 @@ impl Emitter for JsonEmitter { } } - fn emit_unused_externs(&mut self, unused_externs: &[&str]) { - let data = UnusedExterns { unused_extern_names: unused_externs }; + fn emit_unused_externs(&mut self, lint_level: &str, unused_externs: &[&str]) { + let data = UnusedExterns { lint_level, unused_extern_names: unused_externs }; let result = if self.pretty { writeln!(&mut self.dst, "{}", as_pretty_json(&data)) } else { @@ -336,9 +336,11 @@ struct FutureIncompatReport { } #[derive(Encodable)] -struct UnusedExterns<'a, 'b> { +struct UnusedExterns<'a, 'b, 'c> { + /// The severity level of the unused dependencies lint + lint_level: &'a str, /// List of unused externs by their names. - unused_extern_names: &'a [&'b str], + unused_extern_names: &'b [&'c str], } impl Diagnostic { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 5720e98abc8..533c32b32c6 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -767,8 +767,8 @@ impl Handler { self.inner.borrow_mut().emitter.emit_future_breakage_report(diags) } - pub fn emit_unused_externs(&self, unused_externs: &[&str]) { - self.inner.borrow_mut().emit_unused_externs(unused_externs) + pub fn emit_unused_externs(&self, lint_level: &str, unused_externs: &[&str]) { + self.inner.borrow_mut().emit_unused_externs(lint_level, unused_externs) } pub fn delay_as_bug(&self, diagnostic: Diagnostic) { @@ -845,8 +845,8 @@ impl HandlerInner { self.emitter.emit_artifact_notification(path, artifact_type); } - fn emit_unused_externs(&mut self, unused_externs: &[&str]) { - self.emitter.emit_unused_externs(unused_externs); + fn emit_unused_externs(&mut self, lint_level: &str, unused_externs: &[&str]) { + self.emitter.emit_unused_externs(lint_level, unused_externs); } fn treat_err_as_bug(&self) -> bool { diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 5217066bbef..717f4d5a3ba 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -17,6 +17,7 @@ use rustc_hir::definitions::Definitions; use rustc_hir::Crate; use rustc_index::vec::IndexVec; use rustc_lint::LintStore; +use rustc_metadata::creader::CStore; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; use rustc_middle::middle; @@ -836,6 +837,12 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { }); sess.time("looking_for_derive_registrar", || proc_macro_decls::find(tcx)); + + let cstore = tcx + .cstore_as_any() + .downcast_ref::() + .expect("`tcx.cstore` is not a `CStore`"); + cstore.report_unused_deps(tcx); }, { par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 7b34374032c..9e3f121378c 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -46,6 +46,9 @@ pub struct CStore { /// This map is used to verify we get no hash conflicts between /// `StableCrateId` values. stable_crate_ids: FxHashMap, + + /// Unused externs of the crate + unused_externs: Vec, } pub struct CrateLoader<'a> { @@ -190,6 +193,21 @@ impl CStore { crate fn has_global_allocator(&self) -> bool { self.has_global_allocator } + + pub fn report_unused_deps(&self, tcx: TyCtxt<'_>) { + let level = tcx + .lint_level_at_node(lint::builtin::UNUSED_CRATE_DEPENDENCIES, rustc_hir::CRATE_HIR_ID) + .0; + if level != lint::Level::Allow && tcx.sess.opts.json_unused_externs { + let unused_externs = + self.unused_externs.iter().map(|ident| ident.to_ident_string()).collect::>(); + let unused_externs = unused_externs.iter().map(String::as_str).collect::>(); + tcx.sess + .parse_sess + .span_diagnostic + .emit_unused_externs(level.as_str(), &unused_externs); + } + } } impl<'a> CrateLoader<'a> { @@ -217,6 +235,7 @@ impl<'a> CrateLoader<'a> { allocator_kind: None, has_global_allocator: false, stable_crate_ids, + unused_externs: Vec::new(), }, used_extern_options: Default::default(), } @@ -893,18 +912,23 @@ impl<'a> CrateLoader<'a> { fn report_unused_deps(&mut self, krate: &ast::Crate) { // Make a point span rather than covering the whole file let span = krate.span.shrink_to_lo(); - let mut unused_externs = Vec::new(); // Complain about anything left over for (name, entry) in self.sess.opts.externs.iter() { if let ExternLocation::FoundInLibrarySearchDirectories = entry.location { // Don't worry about pathless `--extern foo` sysroot references continue; } - if self.used_extern_options.contains(&Symbol::intern(name)) { + let name_interned = Symbol::intern(name); + if self.used_extern_options.contains(&name_interned) { continue; } // Got a real unused --extern + if self.sess.opts.json_unused_externs { + self.cstore.unused_externs.push(name_interned); + continue; + } + let diag = match self.sess.opts.extern_dep_specs.get(name) { Some(loc) => BuiltinLintDiagnostics::ExternDepSpec(name.clone(), loc.into()), None => { @@ -918,7 +942,6 @@ impl<'a> CrateLoader<'a> { ) } }; - unused_externs.push(name as &str); self.sess.parse_sess.buffer_lint_with_diagnostic( lint::builtin::UNUSED_CRATE_DEPENDENCIES, span, @@ -931,9 +954,6 @@ impl<'a> CrateLoader<'a> { diag, ); } - if self.sess.opts.json_unused_externs { - self.sess.parse_sess.span_diagnostic.emit_unused_externs(&unused_externs); - } } pub fn postprocess(&mut self, krate: &ast::Crate) { @@ -941,9 +961,9 @@ impl<'a> CrateLoader<'a> { self.inject_allocator_crate(krate); self.inject_panic_runtime(krate); - info!("{:?}", CrateDump(&self.cstore)); - self.report_unused_deps(krate); + + info!("{:?}", CrateDump(&self.cstore)); } pub fn process_extern_crate( diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 50cdf46ce4f..116b3aad61e 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -188,8 +188,23 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { .map(|v| (*v).clone()) .collect::>(); unused_extern_names.sort(); - let unused_extern_json = - serde_json::to_string(&UnusedExterns { unused_extern_names }).unwrap(); + // Take the most severe lint level + let lint_level = unused_extern_reports + .iter() + .map(|uexts| uexts.lint_level.as_str()) + .max_by_key(|v| match *v { + "warn" => 1, + "deny" => 2, + "forbid" => 3, + // The allow lint level is not expected, + // as if allow is specified, no message + // is to be emitted. + v => unreachable!("Invalid lint level '{}'", v), + }) + .unwrap_or("warn") + .to_string(); + let uext = UnusedExterns { lint_level, unused_extern_names }; + let unused_extern_json = serde_json::to_string(&uext).unwrap(); eprintln!("{}", unused_extern_json); } } @@ -265,6 +280,8 @@ impl DirState { #[derive(serde::Serialize, serde::Deserialize)] struct UnusedExterns { + /// Lint level of the unused_crate_dependencies lint + lint_level: String, /// List of unused externs by their names. unused_extern_names: Vec, } @@ -317,6 +334,7 @@ fn run_test( compiler.arg("--error-format=json"); compiler.arg("--json").arg("unused-externs"); compiler.arg("-Z").arg("unstable-options"); + compiler.arg("-W").arg("unused_crate_dependencies"); } for lib_str in &options.lib_strs { compiler.arg("-L").arg(&lib_str); From d8c9a287036f72bf078f868f8fe635b7a7fde32c Mon Sep 17 00:00:00 2001 From: est31 Date: Wed, 12 Aug 2020 03:45:16 +0200 Subject: [PATCH 039/370] Fix the tests --- compiler/rustc_metadata/src/creader.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 9e3f121378c..5634467eeb7 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -195,10 +195,16 @@ impl CStore { } pub fn report_unused_deps(&self, tcx: TyCtxt<'_>) { + // We put the check for the option before the lint_level_at_node call + // because the call mutates internal state and introducing it + // leads to some ui tests failing. + if !tcx.sess.opts.json_unused_externs { + return; + } let level = tcx .lint_level_at_node(lint::builtin::UNUSED_CRATE_DEPENDENCIES, rustc_hir::CRATE_HIR_ID) .0; - if level != lint::Level::Allow && tcx.sess.opts.json_unused_externs { + if level != lint::Level::Allow { let unused_externs = self.unused_externs.iter().map(|ident| ident.to_ident_string()).collect::>(); let unused_externs = unused_externs.iter().map(String::as_str).collect::>(); From d018ef180d9bc4e852457fd83fda0bec8452baf6 Mon Sep 17 00:00:00 2001 From: est31 Date: Tue, 2 Mar 2021 03:07:13 +0100 Subject: [PATCH 040/370] Add notes to keep the UnusedExterns structs synced up --- compiler/rustc_errors/src/json.rs | 4 ++++ src/librustdoc/doctest.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 8511b51e3bf..3753ca580e7 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -335,6 +335,10 @@ struct FutureIncompatReport { future_incompat_report: Vec, } +// NOTE: Keep this in sync with the equivalent structs in rustdoc's +// doctest component (as well as cargo). +// We could unify this struct the one in rustdoc but they have different +// ownership semantics, so doing so would create wasteful allocations. #[derive(Encodable)] struct UnusedExterns<'a, 'b, 'c> { /// The severity level of the unused dependencies lint diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 116b3aad61e..f7a6ccfc7d1 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -278,6 +278,10 @@ impl DirState { } } +// NOTE: Keep this in sync with the equivalent structs in rustc +// and cargo. +// We could unify this struct the one in rustc but they have different +// ownership semantics, so doing so would create wasteful allocations. #[derive(serde::Serialize, serde::Deserialize)] struct UnusedExterns { /// Lint level of the unused_crate_dependencies lint From 8f62149d071ad1a42deef3bd67c9a414d73559f8 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 9 Mar 2021 10:16:43 +0100 Subject: [PATCH 041/370] Rustup to rustc 1.52.0-nightly (8f349be27 2021-03-08) --- build_sysroot/Cargo.lock | 12 ++++++------ rust-toolchain | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index a7650ab995b..cd0526b0129 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -16,9 +16,9 @@ dependencies = [ [[package]] name = "adler" -version = "0.2.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -132,18 +132,18 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.86" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" +checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" dependencies = [ "rustc-std-workspace-core", ] [[package]] name = "miniz_oxide" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" dependencies = [ "adler", "autocfg", diff --git a/rust-toolchain b/rust-toolchain index 495d8ea7734..d00e2bee746 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-03-05" +channel = "nightly-2021-03-09" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 826189ef51c4f0ad5f6e10d44cf8e9e7a229891e Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 9 Mar 2021 12:37:39 +0100 Subject: [PATCH 042/370] Some clippy fixes --- src/abi/pass_mode.rs | 2 +- src/abi/returning.rs | 2 +- src/debuginfo/line_info.rs | 4 ++-- src/intrinsics/simd.rs | 2 +- src/lib.rs | 8 +++----- src/num.rs | 6 +++--- src/pretty_clif.rs | 4 ++-- 7 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs index 06b52168e65..7c275965199 100644 --- a/src/abi/pass_mode.rs +++ b/src/abi/pass_mode.rs @@ -208,7 +208,7 @@ pub(super) fn from_casted_value<'tcx>( }); let ptr = Pointer::new(fx.bcx.ins().stack_addr(pointer_ty(fx.tcx), stack_slot, 0)); let mut offset = 0; - let mut block_params_iter = block_params.into_iter().copied(); + let mut block_params_iter = block_params.iter().copied(); for param in abi_params { let val = ptr.offset_i64(fx, offset).store( fx, diff --git a/src/abi/returning.rs b/src/abi/returning.rs index b68c3a053b3..e1c53224b4f 100644 --- a/src/abi/returning.rs +++ b/src/abi/returning.rs @@ -142,7 +142,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx, T>( let results = fx .bcx .inst_results(call_inst) - .into_iter() + .iter() .copied() .collect::>(); let result = diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index 30ed356c762..8578ab33ced 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -39,11 +39,11 @@ fn osstr_as_utf8_bytes(path: &OsStr) -> &[u8] { #[cfg(unix)] { use std::os::unix::ffi::OsStrExt; - return path.as_bytes(); + path.as_bytes() } #[cfg(not(unix))] { - return path.to_str().unwrap().as_bytes(); + path.to_str().unwrap().as_bytes() } } diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 1f8eeb1e714..337f4d6766a 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -88,7 +88,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let idx_bytes = match idx_const.val { ty::ConstKind::Value(ConstValue::ByRef { alloc, offset }) => { let ptr = Pointer::new(AllocId(0 /* dummy */), offset); - let size = Size::from_bytes(4 * u64::from(ret_lane_count) /* size_of([u32; ret_lane_count]) */); + let size = Size::from_bytes(4 * ret_lane_count /* size_of([u32; ret_lane_count]) */); alloc.get_bytes(fx, ptr, size).unwrap() } _ => unreachable!("{:?}", idx_const), diff --git a/src/lib.rs b/src/lib.rs index c07b33cc83c..650e5e04bdb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -240,9 +240,9 @@ impl CodegenBackend for CraneliftCodegenBackend { vec![] } - fn codegen_crate<'tcx>( + fn codegen_crate( &self, - tcx: TyCtxt<'tcx>, + tcx: TyCtxt<'_>, metadata: EncodedMetadata, need_metadata_module: bool, ) -> Box { @@ -252,9 +252,7 @@ impl CodegenBackend for CraneliftCodegenBackend { BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args) .unwrap_or_else(|err| tcx.sess.fatal(&err)) }; - let res = driver::codegen_crate(tcx, metadata, need_metadata_module, config); - - res + driver::codegen_crate(tcx, metadata, need_metadata_module, config) } fn join_codegen( diff --git a/src/num.rs b/src/num.rs index da49e1c6c91..9ee564a9a54 100644 --- a/src/num.rs +++ b/src/num.rs @@ -387,7 +387,7 @@ pub(crate) fn codegen_ptr_binop<'tcx>( let lhs = in_lhs.load_scalar(fx); let rhs = in_rhs.load_scalar(fx); - return codegen_compare_bin_op(fx, bin_op, false, lhs, rhs); + codegen_compare_bin_op(fx, bin_op, false, lhs, rhs) } BinOp::Offset => { let pointee_ty = in_lhs.layout().ty.builtin_deref(true).unwrap().ty; @@ -396,10 +396,10 @@ pub(crate) fn codegen_ptr_binop<'tcx>( let ptr_diff = fx.bcx.ins().imul_imm(offset, pointee_size as i64); let base_val = base.load_scalar(fx); let res = fx.bcx.ins().iadd(base_val, ptr_diff); - return CValue::by_val(res, base.layout()); + CValue::by_val(res, base.layout()) } _ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs, in_rhs), - }; + } } else { let (lhs_ptr, lhs_extra) = in_lhs.load_scalar_pair(fx); let (rhs_ptr, rhs_extra) = in_rhs.load_scalar_pair(fx); diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index 87f0e0c3738..855a0cc8e4a 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -205,8 +205,8 @@ pub(crate) fn should_write_ir(tcx: TyCtxt<'_>) -> bool { tcx.sess.opts.output_types.contains_key(&OutputType::LlvmAssembly) } -pub(crate) fn write_ir_file<'tcx>( - tcx: TyCtxt<'tcx>, +pub(crate) fn write_ir_file( + tcx: TyCtxt<'_>, name: &str, write: impl FnOnce(&mut dyn Write) -> std::io::Result<()>, ) { From 9adb1393563f4bfa1a035e7de4018a3cec249f50 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 9 Mar 2021 12:46:04 +0100 Subject: [PATCH 043/370] Add rustc_private=true to the package metadata for rust-analyzer --- Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 9861af1f8ea..e51714b56d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,3 +75,6 @@ debug = false [profile.release.package.syn] opt-level = 0 debug = false + +[package.metadata.rust-analyzer] +rustc_private = true From eefe1ede8222867558e115dfeceee44104806f29 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 9 Mar 2021 12:52:43 +0100 Subject: [PATCH 044/370] Update config name for latest rust-analyzer --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index a13d5931ffa..0cd576e160f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,7 @@ // source for rustc_* is not included in the rust-src component; disable the errors about this "rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "macro-error"], "rust-analyzer.assist.importMergeBehavior": "last", - "rust-analyzer.cargo.loadOutDirsFromCheck": true, + "rust-analyzer.cargo.runBuildScripts": true, "rust-analyzer.linkedProjects": [ "./Cargo.toml", //"./build_sysroot/sysroot_src/src/libstd/Cargo.toml", From 1ec905766d0c8b76ecef22d1948fe87a490da3fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 24 Feb 2021 00:00:00 +0000 Subject: [PATCH 045/370] Use FromStr trait for number option parsing Replace `parse_uint` with generic `parse_number` based on `FromStr`. Use it for parsing inlining threshold to avoid casting later. --- compiler/rustc_codegen_llvm/src/back/write.rs | 2 +- compiler/rustc_codegen_ssa/src/back/write.rs | 2 +- compiler/rustc_session/src/config.rs | 1 + compiler/rustc_session/src/options.rs | 28 +++++++++---------- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index c224da7885b..36e22f260a7 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -1044,7 +1044,7 @@ pub unsafe fn with_llvm_pmb( // thresholds copied from clang. match (opt_level, opt_size, inline_threshold) { (.., Some(t)) => { - llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, t as u32); + llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, t); } (llvm::CodeGenOptLevel::Aggressive, ..) => { llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 275); diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 7b8ce157fc2..9afb0ccd706 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -106,7 +106,7 @@ pub struct ModuleConfig { pub vectorize_loop: bool, pub vectorize_slp: bool, pub merge_functions: bool, - pub inline_threshold: Option, + pub inline_threshold: Option, pub new_llvm_pass_manager: bool, pub emit_lifetime_markers: bool, } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f25828e2161..12ada53c2fa 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2367,6 +2367,7 @@ crate mod dep_tracking { impl_dep_tracking_hash_via_hash!(PathBuf); impl_dep_tracking_hash_via_hash!(lint::Level); impl_dep_tracking_hash_via_hash!(Option); + impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 79bbad8307b..67af17bafcc 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -248,9 +248,9 @@ macro_rules! options { pub const parse_list: &str = "a space-separated list of strings"; pub const parse_opt_list: &str = parse_list; pub const parse_opt_comma_list: &str = "a comma-separated list of strings"; - pub const parse_uint: &str = "a number"; - pub const parse_opt_uint: &str = parse_uint; - pub const parse_threads: &str = parse_uint; + pub const parse_number: &str = "a number"; + pub const parse_opt_number: &str = parse_number; + pub const parse_threads: &str = parse_number; pub const parse_passes: &str = "a space-separated list of passes, or `all`"; pub const parse_panic_strategy: &str = "either `unwind` or `abort`"; pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; @@ -413,16 +413,16 @@ macro_rules! options { } } - /// Use this for any uint option that has a static default. - fn parse_uint(slot: &mut usize, v: Option<&str>) -> bool { + /// Use this for any numeric option that has a static default. + fn parse_number(slot: &mut T, v: Option<&str>) -> bool { match v.and_then(|s| s.parse().ok()) { Some(i) => { *slot = i; true }, None => false } } - /// Use this for any uint option that lacks a static default. - fn parse_opt_uint(slot: &mut Option, v: Option<&str>) -> bool { + /// Use this for any numeric option that lacks a static default. + fn parse_opt_number(slot: &mut Option, v: Option<&str>) -> bool { match v { Some(s) => { *slot = s.parse().ok(); slot.is_some() } None => false @@ -748,13 +748,13 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, "this option is deprecated and does nothing"), code_model: Option = (None, parse_code_model, [TRACKED], "choose the code model to use (`rustc --print code-models` for details)"), - codegen_units: Option = (None, parse_opt_uint, [UNTRACKED], + codegen_units: Option = (None, parse_opt_number, [UNTRACKED], "divide crate into N units to optimize in parallel"), control_flow_guard: CFGuard = (CFGuard::Disabled, parse_cfguard, [TRACKED], "use Windows Control Flow Guard (default: no)"), debug_assertions: Option = (None, parse_opt_bool, [TRACKED], "explicitly enable the `cfg(debug_assertions)` directive"), - debuginfo: usize = (0, parse_uint, [TRACKED], + debuginfo: usize = (0, parse_number, [TRACKED], "debug info emission level (0 = no debug info, 1 = line tables only, \ 2 = full debug info with variable and type information; default: 0)"), default_linker_libraries: bool = (false, parse_bool, [UNTRACKED], @@ -769,7 +769,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, "force use of unwind tables"), incremental: Option = (None, parse_opt_string, [UNTRACKED], "enable incremental compilation"), - inline_threshold: Option = (None, parse_opt_uint, [TRACKED], + inline_threshold: Option = (None, parse_opt_number, [TRACKED], "set the threshold for inlining a function"), link_arg: (/* redirected to link_args */) = ((), parse_string_push, [UNTRACKED], "a single extra argument to append to the linker invocation (can be used several times)"), @@ -959,9 +959,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "verify incr. comp. hashes of green query instances (default: no)"), inline_mir: Option = (None, parse_opt_bool, [TRACKED], "enable MIR inlining (default: no)"), - inline_mir_threshold: Option = (None, parse_opt_uint, [TRACKED], + inline_mir_threshold: Option = (None, parse_opt_number, [TRACKED], "a default MIR inlining threshold (default: 50)"), - inline_mir_hint_threshold: Option = (None, parse_opt_uint, [TRACKED], + inline_mir_hint_threshold: Option = (None, parse_opt_number, [TRACKED], "inlining threshold for functions with inline hint (default: 100)"), inline_in_all_cgus: Option = (None, parse_opt_bool, [TRACKED], "control whether `#[inline]` functions are in all CGUs"), @@ -999,7 +999,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, mir_emit_retag: bool = (false, parse_bool, [TRACKED], "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ (default: no)"), - mir_opt_level: Option = (None, parse_opt_uint, [TRACKED], + mir_opt_level: Option = (None, parse_opt_number, [TRACKED], "MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"), mutable_noalias: bool = (false, parse_bool, [TRACKED], "emit noalias metadata for mutable references (default: no)"), @@ -1120,7 +1120,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "which mangling version to use for symbol names ('legacy' (default) or 'v0')"), teach: bool = (false, parse_bool, [TRACKED], "show extended diagnostic help (default: no)"), - terminal_width: Option = (None, parse_opt_uint, [UNTRACKED], + terminal_width: Option = (None, parse_opt_number, [UNTRACKED], "set the current terminal width"), tune_cpu: Option = (None, parse_opt_string, [TRACKED], "select processor to schedule for (`rustc --print target-cpus` for details)"), From 871874817b06bc066ff14fadcbec80fd85bfb2ed Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 9 Mar 2021 16:30:31 +0100 Subject: [PATCH 046/370] Lower GHA timeout to 60 min --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3b29225f601..2ac516381cf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,6 +7,7 @@ on: jobs: build: runs-on: ${{ matrix.os }} + timeout-minutes: 60 strategy: fail-fast: false From 6b58ed225ec0d5048ab188ef68e47c07bc8547e9 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 9 Mar 2021 16:45:55 +0100 Subject: [PATCH 047/370] Adjust for changed -Zmir-opt-level numbering --- build_sysroot/build_sysroot.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_sysroot/build_sysroot.sh b/build_sysroot/build_sysroot.sh index 636aa5f3f3d..0354304e55b 100755 --- a/build_sysroot/build_sysroot.sh +++ b/build_sysroot/build_sysroot.sh @@ -28,7 +28,7 @@ export __CARGO_DEFAULT_LIB_METADATA="cg_clif" if [[ "$1" != "--debug" ]]; then sysroot_channel='release' # FIXME Enable incremental again once rust-lang/rust#74946 is fixed - CARGO_INCREMENTAL=0 RUSTFLAGS="$RUSTFLAGS -Zmir-opt-level=2" cargo build --target "$TARGET_TRIPLE" --release + CARGO_INCREMENTAL=0 RUSTFLAGS="$RUSTFLAGS -Zmir-opt-level=3" cargo build --target "$TARGET_TRIPLE" --release else sysroot_channel='debug' cargo build --target "$TARGET_TRIPLE" From 83e6251f21984764cac52d5d50408437dc000e57 Mon Sep 17 00:00:00 2001 From: kadmin Date: Tue, 29 Dec 2020 02:00:04 +0000 Subject: [PATCH 048/370] Update cranelift --- src/base.rs | 10 ++++++++++ src/lib.rs | 1 + 2 files changed, 11 insertions(+) diff --git a/src/base.rs b/src/base.rs index f2c61c95f4f..ba7c82d24c5 100644 --- a/src/base.rs +++ b/src/base.rs @@ -832,6 +832,16 @@ fn codegen_stmt<'tcx>( } } StatementKind::Coverage { .. } => fx.tcx.sess.fatal("-Zcoverage is unimplemented"), + StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { + src, + dst, + count, + }) => { + let dst = codegen_operand(fx, dst).load_scalar(fx); + let src = codegen_operand(fx, src).load_scalar(fx); + let count = codegen_operand(fx, count).load_scalar(fx); + fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, count); + } } } diff --git a/src/lib.rs b/src/lib.rs index 8edb883ccb5..fae71fef9e6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,7 @@ #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] #![warn(unreachable_pub)] +#![feature(box_patterns)] extern crate snap; #[macro_use] From d30c497de6dc625012293efd29fa2f98a479947b Mon Sep 17 00:00:00 2001 From: kadmin Date: Sat, 23 Jan 2021 03:55:41 +0000 Subject: [PATCH 049/370] Build StKind::CopyOverlapping This replaces where it was previously being constructed in intrinsics, with direct construction of the Statement. --- src/base.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/base.rs b/src/base.rs index ba7c82d24c5..8b5ae9e0541 100644 --- a/src/base.rs +++ b/src/base.rs @@ -837,10 +837,21 @@ fn codegen_stmt<'tcx>( dst, count, }) => { - let dst = codegen_operand(fx, dst).load_scalar(fx); + let dst = codegen_operand(fx, dst); + let pointee = dst + .layout() + .pointee_info_at(fx, rustc_target::abi::Size::ZERO) + .expect("Expected pointer"); + let dst = dst.load_scalar(fx); let src = codegen_operand(fx, src).load_scalar(fx); let count = codegen_operand(fx, count).load_scalar(fx); - fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, count); + let elem_size: u64 = pointee.size.bytes(); + let bytes = if elem_size != 1 { + fx.bcx.ins().imul_imm(count, elem_size as i64) + } else { + count + }; + fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, bytes); } } } From d674d3dad89a4906e0473ed2717db391625732fa Mon Sep 17 00:00:00 2001 From: kadmin Date: Fri, 26 Feb 2021 16:42:51 +0000 Subject: [PATCH 050/370] Clean up todos Also add some span_bugs where it is unreachable --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index fae71fef9e6..8edb883ccb5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,6 @@ #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] #![warn(unreachable_pub)] -#![feature(box_patterns)] extern crate snap; #[macro_use] From 95182bb2ccff3ba7cd4fe1e09488ab1fd6411244 Mon Sep 17 00:00:00 2001 From: "katelyn a. martin" Date: Thu, 27 Aug 2020 11:49:18 -0400 Subject: [PATCH 051/370] rustc_target: add "unwind" payloads to `Abi` ### Overview This commit begins the implementation work for RFC 2945. For more information, see the rendered RFC [1] and tracking issue [2]. A boolean `unwind` payload is added to the `C`, `System`, `Stdcall`, and `Thiscall` variants, marking whether unwinding across FFI boundaries is acceptable. The cases where each of these variants' `unwind` member is true correspond with the `C-unwind`, `system-unwind`, `stdcall-unwind`, and `thiscall-unwind` ABI strings introduced in RFC 2945 [3]. ### Feature Gate and Unstable Book This commit adds a `c_unwind` feature gate for the new ABI strings. Tests for this feature gate are included in `src/test/ui/c-unwind/`, which ensure that this feature gate works correctly for each of the new ABIs. A new language features entry in the unstable book is added as well. ### Further Work To Be Done This commit does not proceed to implement the new unwinding ABIs, and is intentionally scoped specifically to *defining* the ABIs and their feature flag. ### One Note on Test Churn This will lead to some test churn, in re-blessing hash tests, as the deleted comment in `src/librustc_target/spec/abi.rs` mentioned, because we can no longer guarantee the ordering of the `Abi` variants. While this is a downside, this decision was made bearing in mind that RFC 2945 states the following, in the "Other `unwind` Strings" section [3]: > More unwind variants of existing ABI strings may be introduced, > with the same semantics, without an additional RFC. Adding a new variant for each of these cases, rather than specifying a payload for a given ABI, would quickly become untenable, and make working with the `Abi` enum prone to mistakes. This approach encodes the unwinding information *into* a given ABI, to account for the future possibility of other `-unwind` ABI strings. ### Ignore Directives `ignore-*` directives are used in two of our `*-unwind` ABI test cases. Specifically, the `stdcall-unwind` and `thiscall-unwind` test cases ignore architectures that do not support `stdcall` and `thiscall`, respectively. These directives are cribbed from `src/test/ui/c-variadic/variadic-ffi-1.rs` for `stdcall`, and `src/test/ui/extern/extern-thiscall.rs` for `thiscall`. This would otherwise fail on some targets, see: https://github.com/rust-lang-ci/rust/commit/fcf697f90206e9c87b39d494f94ab35d976bfc60 ### Footnotes [1]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md [2]: https://github.com/rust-lang/rust/issues/74990 [3]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md#other-unwind-abi-strings --- src/abi/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index c79889f8ca1..b158d73f3a1 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -476,8 +476,11 @@ pub(crate) fn codegen_terminator_call<'tcx>( // FIXME find a cleaner way to support varargs if fn_sig.c_variadic { - if fn_sig.abi != Abi::C { - fx.tcx.sess.span_fatal(span, &format!("Variadic call for non-C abi {:?}", fn_sig.abi)); + if !matches!(fn_sig.abi, Abi::C { .. }) { + fx.tcx.sess.span_fatal( + span, + &format!("Variadic call for non-C abi {:?}", fn_sig.abi), + ); } let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap(); let abi_params = call_args From 88f2a702c7c46274331f5be08f4dde692dbf1913 Mon Sep 17 00:00:00 2001 From: hyd-dev Date: Thu, 11 Mar 2021 19:39:26 +0800 Subject: [PATCH 052/370] Add regression test for https://github.com/rust-lang/rust/issues/81555 --- src/test/ui/proc-macro/issue-81555.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/ui/proc-macro/issue-81555.rs diff --git a/src/test/ui/proc-macro/issue-81555.rs b/src/test/ui/proc-macro/issue-81555.rs new file mode 100644 index 00000000000..693f1f7dc39 --- /dev/null +++ b/src/test/ui/proc-macro/issue-81555.rs @@ -0,0 +1,15 @@ +// check-pass +// aux-build:test-macros.rs +#![feature(stmt_expr_attributes, proc_macro_hygiene)] + +extern crate test_macros; + +use test_macros::identity_attr; + +#[identity_attr] +fn main() { + let _x; + let y = (); + #[identity_attr] + _x = y; +} From c8b2c86b2eaa2d98add7c13e6c9c5df11ca34549 Mon Sep 17 00:00:00 2001 From: hyd-dev Date: Thu, 11 Mar 2021 20:19:27 +0800 Subject: [PATCH 053/370] Add regression test for https://github.com/rust-lang/rust/issues/79825 --- src/test/ui/proc-macro/auxiliary/issue-79825.rs | 14 ++++++++++++++ src/test/ui/proc-macro/issue-79825.rs | 10 ++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/test/ui/proc-macro/auxiliary/issue-79825.rs create mode 100644 src/test/ui/proc-macro/issue-79825.rs diff --git a/src/test/ui/proc-macro/auxiliary/issue-79825.rs b/src/test/ui/proc-macro/auxiliary/issue-79825.rs new file mode 100644 index 00000000000..930891b1d43 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/issue-79825.rs @@ -0,0 +1,14 @@ +// force-host +// no-prefer-dynamic +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn assert_input(args: TokenStream, input: TokenStream) -> TokenStream { + assert_eq!(input.to_string(), "trait Alias = Sized ;"); + assert!(args.is_empty()); + TokenStream::new() +} diff --git a/src/test/ui/proc-macro/issue-79825.rs b/src/test/ui/proc-macro/issue-79825.rs new file mode 100644 index 00000000000..f628469ce3a --- /dev/null +++ b/src/test/ui/proc-macro/issue-79825.rs @@ -0,0 +1,10 @@ +// check-pass +// aux-build:issue-79825.rs +#![feature(trait_alias)] + +extern crate issue_79825; + +#[issue_79825::assert_input] +trait Alias = Sized; + +fn main() {} From 6b1dd82162d62fef5fee258b050c96686b5ccbf0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 8 Mar 2021 16:18:03 +0000 Subject: [PATCH 054/370] Prepare mir::Constant for ty::Const only supporting valtrees --- src/constant.rs | 30 +++++++++++++++++------------- src/intrinsics/llvm.rs | 6 +++--- src/intrinsics/simd.rs | 8 ++++---- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index b0639cf9e15..23ad5267c56 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -8,7 +8,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{ read_target_uint, AllocId, Allocation, ConstValue, ErrorHandled, GlobalAlloc, Pointer, Scalar, }; -use rustc_middle::ty::{Const, ConstKind}; +use rustc_middle::ty::ConstKind; use cranelift_codegen::ir::GlobalValueData; use cranelift_module::*; @@ -39,7 +39,10 @@ impl ConstantCx { pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { let mut all_constants_ok = true; for constant in &fx.mir.required_consts { - let const_ = fx.monomorphize(constant.literal); + let const_ = match fx.monomorphize(constant.literal) { + ConstantSource::Ty(ct) => ct, + ConstantSource::Val(..) => continue, + }; match const_.val { ConstKind::Value(_) => {} ConstKind::Unevaluated(def, ref substs, promoted) => { @@ -113,19 +116,17 @@ pub(crate) fn codegen_constant<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, constant: &Constant<'tcx>, ) -> CValue<'tcx> { - let const_ = fx.monomorphize(constant.literal); + let const_ = match fx.monomorphize(constant.literal) { + ConstantSource::Ty(ct) => ct, + ConstantSource::Val(val, ty) => return codegen_const_value(fx, val, ty), + }; let const_val = match const_.val { ConstKind::Value(const_val) => const_val, ConstKind::Unevaluated(def, ref substs, promoted) if fx.tcx.is_static(def.did) => { assert!(substs.is_empty()); assert!(promoted.is_none()); - return codegen_static_ref( - fx, - def.did, - fx.layout_of(fx.monomorphize(&constant.literal.ty)), - ) - .to_cvalue(fx); + return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty)).to_cvalue(fx); } ConstKind::Unevaluated(def, ref substs, promoted) => { match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) { @@ -422,11 +423,14 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant pub(crate) fn mir_operand_get_const_val<'tcx>( fx: &FunctionCx<'_, '_, 'tcx>, operand: &Operand<'tcx>, -) -> Option<&'tcx Const<'tcx>> { +) -> Option> { match operand { Operand::Copy(_) | Operand::Move(_) => None, - Operand::Constant(const_) => { - Some(fx.monomorphize(const_.literal).eval(fx.tcx, ParamEnv::reveal_all())) - } + Operand::Constant(const_) => match const_.literal { + ConstantSource::Ty(const_) => { + fx.monomorphize(const_).eval(fx.tcx, ParamEnv::reveal_all()).val.try_to_value() + } + ConstantSource::Val(val, _) => Some(val), + }, } } diff --git a/src/intrinsics/llvm.rs b/src/intrinsics/llvm.rs index 0692da397eb..83c91f789cd 100644 --- a/src/intrinsics/llvm.rs +++ b/src/intrinsics/llvm.rs @@ -53,7 +53,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( }; llvm.x86.sse2.cmp.ps | llvm.x86.sse2.cmp.pd, (c x, c y, o kind) { let kind_const = crate::constant::mir_operand_get_const_val(fx, kind).expect("llvm.x86.sse2.cmp.* kind not const"); - let flt_cc = match kind_const.val.try_to_bits(Size::from_bytes(1)).unwrap_or_else(|| panic!("kind not scalar: {:?}", kind_const)) { + let flt_cc = match kind_const.try_to_bits(Size::from_bytes(1)).unwrap_or_else(|| panic!("kind not scalar: {:?}", kind_const)) { 0 => FloatCC::Equal, 1 => FloatCC::LessThan, 2 => FloatCC::LessThanOrEqual, @@ -84,7 +84,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( llvm.x86.sse2.psrli.d, (c a, o imm8) { let imm8 = crate::constant::mir_operand_get_const_val(fx, imm8).expect("llvm.x86.sse2.psrli.d imm8 not const"); simd_for_each_lane(fx, a, ret, |fx, _lane_layout, res_lane_layout, lane| { - let res_lane = match imm8.val.try_to_bits(Size::from_bytes(4)).unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8)) { + let res_lane = match imm8.try_to_bits(Size::from_bytes(4)).unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8)) { imm8 if imm8 < 32 => fx.bcx.ins().ushr_imm(lane, i64::from(imm8 as u8)), _ => fx.bcx.ins().iconst(types::I32, 0), }; @@ -94,7 +94,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( llvm.x86.sse2.pslli.d, (c a, o imm8) { let imm8 = crate::constant::mir_operand_get_const_val(fx, imm8).expect("llvm.x86.sse2.psrli.d imm8 not const"); simd_for_each_lane(fx, a, ret, |fx, _lane_layout, res_lane_layout, lane| { - let res_lane = match imm8.val.try_to_bits(Size::from_bytes(4)).unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8)) { + let res_lane = match imm8.try_to_bits(Size::from_bytes(4)).unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8)) { imm8 if imm8 < 32 => fx.bcx.ins().ishl_imm(lane, i64::from(imm8 as u8)), _ => fx.bcx.ins().iconst(types::I32, 0), }; diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 1f8eeb1e714..d17136080fe 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -85,8 +85,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( use rustc_middle::mir::interpret::*; let idx_const = crate::constant::mir_operand_get_const_val(fx, idx).expect("simd_shuffle* idx not const"); - let idx_bytes = match idx_const.val { - ty::ConstKind::Value(ConstValue::ByRef { alloc, offset }) => { + let idx_bytes = match idx_const { + ConstValue::ByRef { alloc, offset } => { let ptr = Pointer::new(AllocId(0 /* dummy */), offset); let size = Size::from_bytes(4 * u64::from(ret_lane_count) /* size_of([u32; ret_lane_count]) */); alloc.get_bytes(fx, ptr, size).unwrap() @@ -130,7 +130,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( ); }; - let idx = idx_const.val.try_to_bits(Size::from_bytes(4 /* u32*/)).unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const)); + let idx = idx_const.try_to_bits(Size::from_bytes(4 /* u32*/)).unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const)); let (lane_count, _lane_ty) = base.layout().ty.simd_size_and_type(fx.tcx); if idx >= lane_count.into() { fx.tcx.sess.span_fatal(fx.mir.span, &format!("[simd_insert] idx {} >= lane_count {}", idx, lane_count)); @@ -159,7 +159,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( return; }; - let idx = idx_const.val.try_to_bits(Size::from_bytes(4 /* u32*/)).unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const)); + let idx = idx_const.try_to_bits(Size::from_bytes(4 /* u32*/)).unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const)); let (lane_count, _lane_ty) = v.layout().ty.simd_size_and_type(fx.tcx); if idx >= lane_count.into() { fx.tcx.sess.span_fatal(fx.mir.span, &format!("[simd_extract] idx {} >= lane_count {}", idx, lane_count)); From dd2b8a0444a957b9d1d6481abd38b025c855d79d Mon Sep 17 00:00:00 2001 From: Vlad Frolov Date: Sat, 13 Mar 2021 17:21:56 +0200 Subject: [PATCH 055/370] provide a more realistic example for BinaryHeap::as_slice --- library/alloc/src/collections/binary_heap.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 7a43a3a868b..ed32ff496c6 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -899,13 +899,11 @@ impl BinaryHeap { /// ``` /// #![feature(binary_heap_as_slice)] /// use std::collections::BinaryHeap; - /// let heap = BinaryHeap::from(vec![1, 2, 3, 4, 5, 6, 7]); - /// let slice = heap.as_slice(); + /// use std::io::{self, Write}; /// - /// // Will print in some order - /// for x in slice { - /// println!("{}", x); - /// } + /// let heap = BinaryHeap::from(vec![1, 2, 3, 4, 5, 6, 7]); + /// + /// io::sink().write(heap.as_slice()).unwrap(); /// ``` #[unstable(feature = "binary_heap_as_slice", issue = "82331")] pub fn as_slice(&self) -> &[T] { From 578fcdef5fbd02bd3ae7d30349f62aa9143a0bf2 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 10:22:21 +0100 Subject: [PATCH 056/370] Special case ZST's in Rvalue::Repeat Fixes #1146 by preventing a hang for [(); usize::MAX], which is used in a test of libcore. --- src/base.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/base.rs b/src/base.rs index 362ba7e1c2c..5a28656add2 100644 --- a/src/base.rs +++ b/src/base.rs @@ -660,7 +660,9 @@ fn codegen_stmt<'tcx>( .val .try_to_bits(fx.tcx.data_layout.pointer_size) .unwrap(); - if fx.clif_type(operand.layout().ty) == Some(types::I8) { + if operand.layout().size.bytes() == 0 { + // Do nothing for ZST's + } else if fx.clif_type(operand.layout().ty) == Some(types::I8) { let times = fx.bcx.ins().iconst(fx.pointer_type, times as i64); // FIXME use emit_small_memset where possible let addr = lval.to_ptr().get_addr(fx); From b1d14ca05d6b34423c31fd237fdf2d6cd6f70333 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 11:59:06 +0100 Subject: [PATCH 057/370] Use mmap for metadata loading This can have a significant improvement on compilation times. In addition it reduces the memory consumption. Fixes #927 --- Cargo.lock | 10 +++++++ Cargo.toml | 3 ++- src/metadata.rs | 72 ++++++++++++++++++++++++++++++------------------- 3 files changed, 57 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ed186032ff..a033912364e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -240,6 +240,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memmap2" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e3e85b970d650e2ae6d70592474087051c11c54da7f7b4949725c5735fbcc6" +dependencies = [ + "libc", +] + [[package]] name = "object" version = "0.23.0" @@ -310,6 +319,7 @@ dependencies = [ "gimli", "indexmap", "libloading", + "memmap2", "object", "smallvec", "target-lexicon", diff --git a/Cargo.toml b/Cargo.toml index e51714b56d7..59542c414fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,12 +16,13 @@ cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime/", branch cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" } target-lexicon = "0.11.0" gimli = { version = "0.23.0", default-features = false, features = ["write"]} -object = { version = "0.23.0", default-features = false, features = ["std", "read_core", "write", "coff", "elf", "macho", "pe"] } +object = { version = "0.23.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" } indexmap = "1.0.2" libloading = { version = "0.6.0", optional = true } smallvec = "1.6.1" +memmap2 = "0.2.1" # Uncomment to use local checkout of cranelift #[patch."https://github.com/bytecodealliance/wasmtime/"] diff --git a/src/metadata.rs b/src/metadata.rs index 190c4f45cca..dda9285a38a 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -1,11 +1,11 @@ //! Reading and writing of the rustc metadata for rlibs and dylibs -use std::convert::TryFrom; use std::fs::File; +use std::ops::Deref; use std::path::Path; use rustc_codegen_ssa::METADATA_FILENAME; -use rustc_data_structures::owning_ref::OwningRef; +use rustc_data_structures::owning_ref::{OwningRef, StableAddress}; use rustc_data_structures::rustc_erase_owner; use rustc_data_structures::sync::MetadataRef; use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader}; @@ -17,38 +17,56 @@ use crate::backend::WriteMetadata; pub(crate) struct CraneliftMetadataLoader; +struct StableMmap(memmap2::Mmap); + +impl Deref for StableMmap { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + &*self.0 + } +} + +unsafe impl StableAddress for StableMmap {} + +fn load_metadata_with( + path: &Path, + f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>, +) -> Result { + let file = File::open(path).map_err(|e| format!("{:?}", e))?; + let data = unsafe { memmap2::MmapOptions::new().map_copy_read_only(&file) } + .map_err(|e| format!("{:?}", e))?; + let metadata = OwningRef::new(StableMmap(data)).try_map(f)?; + return Ok(rustc_erase_owner!(metadata.map_owner_box())); +} + impl MetadataLoader for CraneliftMetadataLoader { fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result { - let mut archive = ar::Archive::new(File::open(path).map_err(|e| format!("{:?}", e))?); - // Iterate over all entries in the archive: - while let Some(entry_result) = archive.next_entry() { - let mut entry = entry_result.map_err(|e| format!("{:?}", e))?; - if entry.header().identifier() == METADATA_FILENAME.as_bytes() { - let mut buf = Vec::with_capacity( - usize::try_from(entry.header().size()) - .expect("Rlib metadata file too big to load into memory."), - ); - ::std::io::copy(&mut entry, &mut buf).map_err(|e| format!("{:?}", e))?; - let buf: OwningRef, [u8]> = OwningRef::new(buf); - return Ok(rustc_erase_owner!(buf.map_owner_box())); - } - } + load_metadata_with(path, |data| { + let archive = object::read::archive::ArchiveFile::parse(&*data) + .map_err(|e| format!("{:?}", e))?; - Err("couldn't find metadata entry".to_string()) + for entry_result in archive.members() { + let entry = entry_result.map_err(|e| format!("{:?}", e))?; + if entry.name() == METADATA_FILENAME.as_bytes() { + return Ok(entry.data()); + } + } + + Err("couldn't find metadata entry".to_string()) + }) } fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result { use object::{Object, ObjectSection}; - let file = std::fs::read(path).map_err(|e| format!("read:{:?}", e))?; - let file = object::File::parse(&file).map_err(|e| format!("parse: {:?}", e))?; - let buf = file - .section_by_name(".rustc") - .ok_or("no .rustc section")? - .data() - .map_err(|e| format!("failed to read .rustc section: {:?}", e))? - .to_owned(); - let buf: OwningRef, [u8]> = OwningRef::new(buf); - Ok(rustc_erase_owner!(buf.map_owner_box())) + + load_metadata_with(path, |data| { + let file = object::File::parse(&data).map_err(|e| format!("parse: {:?}", e))?; + file.section_by_name(".rustc") + .ok_or("no .rustc section")? + .data() + .map_err(|e| format!("failed to read .rustc section: {:?}", e)) + }) } } From 21a0c8e9e47942dcbc47f1680d076daeb5629451 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 15 Mar 2021 11:23:44 +0000 Subject: [PATCH 058/370] s/ConstantSource/ConstantKind/ --- src/constant.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index 23ad5267c56..9d93370b7d0 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -40,8 +40,8 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { let mut all_constants_ok = true; for constant in &fx.mir.required_consts { let const_ = match fx.monomorphize(constant.literal) { - ConstantSource::Ty(ct) => ct, - ConstantSource::Val(..) => continue, + ConstantKind::Ty(ct) => ct, + ConstantKind::Val(..) => continue, }; match const_.val { ConstKind::Value(_) => {} @@ -117,8 +117,8 @@ pub(crate) fn codegen_constant<'tcx>( constant: &Constant<'tcx>, ) -> CValue<'tcx> { let const_ = match fx.monomorphize(constant.literal) { - ConstantSource::Ty(ct) => ct, - ConstantSource::Val(val, ty) => return codegen_const_value(fx, val, ty), + ConstantKind::Ty(ct) => ct, + ConstantKind::Val(val, ty) => return codegen_const_value(fx, val, ty), }; let const_val = match const_.val { ConstKind::Value(const_val) => const_val, @@ -427,10 +427,10 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( match operand { Operand::Copy(_) | Operand::Move(_) => None, Operand::Constant(const_) => match const_.literal { - ConstantSource::Ty(const_) => { + ConstantKind::Ty(const_) => { fx.monomorphize(const_).eval(fx.tcx, ParamEnv::reveal_all()).val.try_to_value() } - ConstantSource::Val(val, _) => Some(val), + ConstantKind::Val(val, _) => Some(val), }, } } From 3d85f05dfd85be2ea8c61fd2e6a5b6816c0abfdc Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 13:55:54 +0100 Subject: [PATCH 059/370] Remove no longer necessary intcasts --- src/num.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/num.rs b/src/num.rs index 9ee564a9a54..2ebf30da2d8 100644 --- a/src/num.rs +++ b/src/num.rs @@ -166,13 +166,11 @@ pub(crate) fn codegen_int_binop<'tcx>( BinOp::Shl => { let lhs_ty = fx.bcx.func.dfg.value_type(lhs); let actual_shift = fx.bcx.ins().band_imm(rhs, i64::from(lhs_ty.bits() - 1)); - let actual_shift = clif_intcast(fx, actual_shift, types::I8, false); fx.bcx.ins().ishl(lhs, actual_shift) } BinOp::Shr => { let lhs_ty = fx.bcx.func.dfg.value_type(lhs); let actual_shift = fx.bcx.ins().band_imm(rhs, i64::from(lhs_ty.bits() - 1)); - let actual_shift = clif_intcast(fx, actual_shift, types::I8, false); if signed { fx.bcx.ins().sshr(lhs, actual_shift) } else { From 78d0b7765107bcad95a5279b6a78fd0753159e1b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 14:04:22 +0100 Subject: [PATCH 060/370] Update Cranelift --- Cargo.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a033912364e..9184074e92f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,7 +40,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "cranelift-entity", ] @@ -48,7 +48,7 @@ dependencies = [ [[package]] name = "cranelift-codegen" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "byteorder", "cranelift-bforest", @@ -66,7 +66,7 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -75,17 +75,17 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" [[package]] name = "cranelift-entity" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" [[package]] name = "cranelift-frontend" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "cranelift-codegen", "log", @@ -96,7 +96,7 @@ dependencies = [ [[package]] name = "cranelift-jit" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "anyhow", "cranelift-codegen", @@ -114,7 +114,7 @@ dependencies = [ [[package]] name = "cranelift-module" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "anyhow", "cranelift-codegen", @@ -126,7 +126,7 @@ dependencies = [ [[package]] name = "cranelift-native" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "cranelift-codegen", "target-lexicon", @@ -135,7 +135,7 @@ dependencies = [ [[package]] name = "cranelift-object" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "anyhow", "cranelift-codegen", From f545a21fbe9f32b6f489b064488647997f3af70e Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 14:21:15 +0100 Subject: [PATCH 061/370] Split rust fork setup out of test_bootstrap.sh --- scripts/setup_rust_fork.sh | 68 ++++++++++++++++++++++++++++++++++++++ scripts/test_bootstrap.sh | 62 +--------------------------------- 2 files changed, 69 insertions(+), 61 deletions(-) create mode 100644 scripts/setup_rust_fork.sh diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh new file mode 100644 index 00000000000..e8bedf625f7 --- /dev/null +++ b/scripts/setup_rust_fork.sh @@ -0,0 +1,68 @@ +#!/bin/bash +set -e + +./build.sh +source build/config.sh + +echo "[SETUP] Rust fork" +git clone https://github.com/rust-lang/rust.git || true +pushd rust +git fetch +git checkout -- . +git checkout "$(rustc -V | cut -d' ' -f3 | tr -d '(')" + +git apply - < config.toml < config.toml < Date: Mon, 15 Mar 2021 14:22:11 +0100 Subject: [PATCH 062/370] Fix assert_assignable adt checking --- src/value_and_place.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 1a6a301a45b..b97d3900984 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -705,6 +705,19 @@ pub(crate) fn assert_assignable<'tcx>( } // dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed } + (&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b)) + if adt_def_a.did == adt_def_b.did => + { + let mut types_a = substs_a.types(); + let mut types_b = substs_b.types(); + loop { + match (types_a.next(), types_b.next()) { + (Some(a), Some(b)) => assert_assignable(fx, a, b), + (None, None) => return, + (Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty), + } + } + } _ => { assert_eq!( from_ty, to_ty, From 154668bd02a6bf29632ee500ec1778b7fb820c5d Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 14:48:58 +0100 Subject: [PATCH 063/370] Suppress an unnecessary warning and fix an incorrect warning --- src/lib.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 650e5e04bdb..158f5d4b9d2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -224,8 +224,10 @@ pub struct CraneliftCodegenBackend { impl CodegenBackend for CraneliftCodegenBackend { fn init(&self, sess: &Session) { - if sess.lto() != rustc_session::config::Lto::No && sess.opts.cg.embed_bitcode { - sess.warn("LTO is not supported. You may get a linker error."); + use rustc_session::config::Lto; + match sess.lto() { + Lto::No | Lto::ThinLocal => {} + Lto::Thin | Lto::Fat => sess.warn("LTO is not supported. You may get a linker error."), } } @@ -320,12 +322,9 @@ fn build_isa(sess: &Session) -> Box { flags_builder.set("opt_level", "none").unwrap(); } OptLevel::Less | OptLevel::Default => {} - OptLevel::Aggressive => { + OptLevel::Size | OptLevel::SizeMin | OptLevel::Aggressive => { flags_builder.set("opt_level", "speed_and_size").unwrap(); } - OptLevel::Size | OptLevel::SizeMin => { - sess.warn("Optimizing for size is not supported. Just ignoring the request"); - } } let flags = settings::Flags::new(flags_builder); From 80b2feae1a808aeed5ff4df7eee5d33c211081f6 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 14:49:57 +0100 Subject: [PATCH 064/370] Run the rustc test suite on CI --- .github/workflows/bootstrap_rustc.yml | 44 -------------- .github/workflows/rustc.yml | 82 +++++++++++++++++++++++++ scripts/test_rustc_tests.sh | 86 +++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 44 deletions(-) delete mode 100644 .github/workflows/bootstrap_rustc.yml create mode 100644 .github/workflows/rustc.yml create mode 100755 scripts/test_rustc_tests.sh diff --git a/.github/workflows/bootstrap_rustc.yml b/.github/workflows/bootstrap_rustc.yml deleted file mode 100644 index 8c94a0aa5e6..00000000000 --- a/.github/workflows/bootstrap_rustc.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Bootstrap rustc using cg_clif - -on: - - push - -jobs: - bootstrap_rustc: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Cache cargo installed crates - uses: actions/cache@v2 - with: - path: ~/.cargo/bin - key: ${{ runner.os }}-cargo-installed-crates - - - name: Cache cargo registry and index - uses: actions/cache@v2 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo target dir - uses: actions/cache@v2 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} - - - name: Prepare dependencies - run: | - git config --global user.email "user@example.com" - git config --global user.name "User" - ./prepare.sh - - - name: Test - run: | - # Enable backtraces for easier debugging - export RUST_BACKTRACE=1 - - ./scripts/test_bootstrap.sh diff --git a/.github/workflows/rustc.yml b/.github/workflows/rustc.yml new file mode 100644 index 00000000000..e01a92598ba --- /dev/null +++ b/.github/workflows/rustc.yml @@ -0,0 +1,82 @@ +name: Various rustc tests + +on: + - push + +jobs: + bootstrap_rustc: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Cache cargo installed crates + uses: actions/cache@v2 + with: + path: ~/.cargo/bin + key: ${{ runner.os }}-cargo-installed-crates + + - name: Cache cargo registry and index + uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }} + + - name: Cache cargo target dir + uses: actions/cache@v2 + with: + path: target + key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + + - name: Prepare dependencies + run: | + git config --global user.email "user@example.com" + git config --global user.name "User" + ./prepare.sh + + - name: Test + run: | + # Enable backtraces for easier debugging + export RUST_BACKTRACE=1 + + ./scripts/test_bootstrap.sh + rustc_test_suite: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Cache cargo installed crates + uses: actions/cache@v2 + with: + path: ~/.cargo/bin + key: ${{ runner.os }}-cargo-installed-crates + + - name: Cache cargo registry and index + uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }} + + - name: Cache cargo target dir + uses: actions/cache@v2 + with: + path: target + key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + + - name: Prepare dependencies + run: | + git config --global user.email "user@example.com" + git config --global user.name "User" + ./prepare.sh + + - name: Test + run: | + # Enable backtraces for easier debugging + export RUST_BACKTRACE=1 + + ./scripts/test_rustc_tests.sh diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh new file mode 100755 index 00000000000..1c3318d53de --- /dev/null +++ b/scripts/test_rustc_tests.sh @@ -0,0 +1,86 @@ +#!/bin/bash +set -e + +cd $(dirname "$0")/../ + +source ./scripts/setup_rust_fork.sh + +echo "[TEST] Test suite of rustc" +pushd rust + +cargo install ripgrep + +rm -r src/test/ui/{extern/,panics/,unsized-locals/,thinlto/,simd*,*lto*.rs,linkage*,unwind-*.rs} || true +for test in $(rg --files-with-matches "asm!|catch_unwind|should_panic|lto" src/test/ui); do + rm $test +done + +for test in $(rg -i --files-with-matches "//(\[\w+\])?~|// error-pattern:|// build-fail|// run-fail|-Cllvm-args" src/test/ui); do + rm $test +done + +git checkout -- src/test/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed + +# these all depend on unwinding support +rm src/test/ui/backtrace.rs +rm src/test/ui/array-slice-vec/box-of-array-of-drop-*.rs +rm src/test/ui/array-slice-vec/slice-panic-*.rs +rm src/test/ui/array-slice-vec/nested-vec-3.rs +rm src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs +rm src/test/ui/issues/issue-26655.rs +rm src/test/ui/issues/issue-29485.rs +rm src/test/ui/issues/issue-30018-panic.rs +rm src/test/ui/multi-panic.rs +rm src/test/ui/sepcomp/sepcomp-unwind.rs +rm src/test/ui/structs-enums/unit-like-struct-drop-run.rs +rm src/test/ui/terminate-in-initializer.rs +rm src/test/ui/threads-sendsync/task-stderr.rs +rm src/test/ui/numbers-arithmetic/int-abs-overflow.rs +rm src/test/ui/drop/drop-trait-enum.rs +rm src/test/ui/numbers-arithmetic/issue-8460.rs + +rm src/test/ui/issues/issue-28950.rs # depends on stack size optimizations +rm src/test/ui/init-large-type.rs # same +rm src/test/ui/sse2.rs # cpuid not supported, so sse2 not detected +rm src/test/ui/issues/issue-33992.rs # unsupported linkages +rm src/test/ui/issues/issue-51947.rs # same +rm src/test/ui/numbers-arithmetic/saturating-float-casts.rs # intrinsic gives different but valid result +rm src/test/ui/mir/mir_misc_casts.rs # depends on deduplication of constants +rm src/test/ui/mir/mir_raw_fat_ptr.rs # same +rm src/test/ui/async-await/async-fn-size-moved-locals.rs # -Cpanic=abort shrinks some generator by one byte +rm src/test/ui/async-await/async-fn-size-uninit-locals.rs # same +rm src/test/ui/generator/size-moved-locals.rs # same +rm src/test/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment +rm src/test/ui/test-attrs/test-fn-signature-verification-for-explicit-return-type.rs # "Cannot run dynamic test fn out-of-process" +rm src/test/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and nearbyintf64 intrinsics + +rm src/test/incremental/hashes/inline_asm.rs # inline asm +rm src/test/incremental/issue-72386.rs # same +rm src/test/incremental/change_crate_dep_kind.rs # requires -Cpanic=unwind +rm src/test/incremental/issue-49482.rs # same +rm src/test/incremental/issue-54059.rs # same +rm src/test/incremental/lto.rs # requires lto + +rm src/test/pretty/asm.rs # inline asm +rm src/test/pretty/raw-str-nonexpr.rs # same + +rm -r src/test/run-pass-valgrind/unsized-locals + +rm src/test/ui/json-bom-plus-crlf-multifile.rs # differing warning +rm src/test/ui/json-bom-plus-crlf.rs # same + +rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition +rm src/test/ui/cfg/cfg-panic.rs +rm src/test/ui/default-alloc-error-hook.rs +rm -r src/test/ui/hygiene/ + +rm -r src/test/ui/polymorphization/ # polymorphization not yet supported +rm src/test/codegen-units/polymorphization/unused_type_parameters.rs # same + +rm -r src/test/run-make/fmt-write-bloat/ # tests an optimization +rm src/test/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs +rm src/test/ui/abi/variadic-ffi.rs # requires callee side vararg support + +echo "[TEST] rustc test suite" +RUST_TEST_NOCAPTURE=1 COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 src/test/{codegen-units,run-make,run-pass-valgrind,ui} +popd From 53235d2abb881876dd4ec8119c6a31da53d328a4 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 18:01:48 +0100 Subject: [PATCH 065/370] Enable thread test in std_example Turns out libstd doesn't use #[thread_local] on Windows at all --- example/std_example.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/example/std_example.rs b/example/std_example.rs index 221b512e3bd..015bbdfed46 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -16,8 +16,7 @@ fn main() { let mut stderr = stderr.lock(); // FIXME support lazy jit when multi threading - // FIXME support TLS on windows - #[cfg(not(any(lazy_jit, windows)))] + #[cfg(not(lazy_jit))] std::thread::spawn(move || { println!("Hello from another thread!"); }); From 34c6cee397183974b34a6e04c94b38202eb40caf Mon Sep 17 00:00:00 2001 From: Camelid Date: Mon, 8 Mar 2021 19:35:53 -0800 Subject: [PATCH 066/370] Rename `#[doc(spotlight)]` to `#[doc(notable_trait)]` "spotlight" is not a very specific or self-explaining name. Additionally, the dialog that it triggers is called "Notable traits". So, "notable trait" is a better name. * Rename `#[doc(spotlight)]` to `#[doc(notable_trait)]` * Rename `#![feature(doc_spotlight)]` to `#![feature(doc_notable_trait)]` * Update documentation * Improve documentation --- compiler/rustc_ast_passes/src/feature_gate.rs | 2 +- compiler/rustc_feature/src/active.rs | 7 ++-- compiler/rustc_feature/src/removed.rs | 5 +++ compiler/rustc_passes/src/check_attr.rs | 22 +++++++++--- compiler/rustc_span/src/symbol.rs | 2 ++ library/core/src/future/future.rs | 3 +- library/core/src/iter/traits/iterator.rs | 3 +- library/core/src/lib.rs | 3 +- library/std/src/io/mod.rs | 6 ++-- library/std/src/lib.rs | 3 +- src/doc/rustdoc/src/unstable-features.md | 34 ++++++++++--------- .../language-features/doc-notable-trait.md | 33 ++++++++++++++++++ .../src/language-features/doc-spotlight.md | 30 ---------------- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/formats/cache.rs | 2 +- src/test/rustdoc-ui/doc-spotlight.fixed | 10 ++++++ src/test/rustdoc-ui/doc-spotlight.rs | 10 ++++++ src/test/rustdoc-ui/doc-spotlight.stderr | 14 ++++++++ ...{doc-spotlight.rs => doc-notable_trait.rs} | 10 +++--- .../feature-gate-doc_notable_trait.rs | 4 +++ .../feature-gate-doc_notable_trait.stderr | 12 +++++++ .../feature-gate-doc_spotlight.rs | 4 --- .../feature-gate-doc_spotlight.stderr | 12 ------- 23 files changed, 149 insertions(+), 84 deletions(-) create mode 100644 src/doc/unstable-book/src/language-features/doc-notable-trait.md delete mode 100644 src/doc/unstable-book/src/language-features/doc-spotlight.md create mode 100644 src/test/rustdoc-ui/doc-spotlight.fixed create mode 100644 src/test/rustdoc-ui/doc-spotlight.rs create mode 100644 src/test/rustdoc-ui/doc-spotlight.stderr rename src/test/rustdoc/{doc-spotlight.rs => doc-notable_trait.rs} (78%) create mode 100644 src/test/ui/feature-gates/feature-gate-doc_notable_trait.rs create mode 100644 src/test/ui/feature-gates/feature-gate-doc_notable_trait.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-doc_spotlight.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 8a17ac90a02..3a294faa13f 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -313,7 +313,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { include => external_doc cfg => doc_cfg masked => doc_masked - spotlight => doc_spotlight + notable_trait => doc_notable_trait keyword => doc_keyword ); } diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index ee2fce34b0b..126c85740fa 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -216,6 +216,10 @@ declare_features! ( /// Renamed from `optin_builtin_traits`. (active, auto_traits, "1.50.0", Some(13231), None), + /// Allows `#[doc(notable_trait)]`. + /// Renamed from `doc_spotlight`. + (active, doc_notable_trait, "1.52.0", Some(45040), None), + // no-tracking-issue-end // ------------------------------------------------------------------------- @@ -374,9 +378,6 @@ declare_features! ( /// Allows `#[doc(masked)]`. (active, doc_masked, "1.21.0", Some(44027), None), - /// Allows `#[doc(spotlight)]`. - (active, doc_spotlight, "1.22.0", Some(45040), None), - /// Allows `#[doc(include = "some-file")]`. (active, external_doc, "1.22.0", Some(44732), None), diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 38a3a4e3d44..ca58bc9584d 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -80,6 +80,11 @@ declare_features! ( Some("subsumed by `#![feature(allocator_internals)]`")), /// Allows identifying crates that contain sanitizer runtimes. (removed, sanitizer_runtime, "1.17.0", None, None, None), + /// Allows `#[doc(spotlight)]`. + /// The attribute was renamed to `#[doc(notable_trait)]` + /// and the feature to `doc_notable_trait`. + (removed, doc_spotlight, "1.22.0", Some(45040), None, + Some("renamed to `doc_notable_trait`")), (removed, proc_macro_mod, "1.27.0", Some(54727), None, Some("subsumed by `#![feature(proc_macro_hygiene)]`")), (removed, proc_macro_expr, "1.27.0", Some(54727), None, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 9c606f3e4d4..972d8500c18 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -9,7 +9,7 @@ use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_ast::{Attribute, Lit, LitKind, NestedMetaItem}; -use rustc_errors::{pluralize, struct_span_err}; +use rustc_errors::{pluralize, struct_span_err, Applicability}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; @@ -589,10 +589,10 @@ impl CheckAttrVisitor<'tcx> { | sym::masked | sym::no_default_passes | sym::no_inline + | sym::notable_trait | sym::passes | sym::plugins | sym::primitive - | sym::spotlight | sym::test => {} _ => { @@ -601,11 +601,23 @@ impl CheckAttrVisitor<'tcx> { hir_id, i_meta.span, |lint| { - let msg = format!( + let mut diag = lint.build(&format!( "unknown `doc` attribute `{}`", rustc_ast_pretty::pprust::path_to_string(&i_meta.path), - ); - lint.build(&msg).emit(); + )); + if i_meta.has_name(sym::spotlight) { + diag.note( + "`doc(spotlight)` was renamed to `doc(notable_trait)`", + ); + diag.span_suggestion_short( + i_meta.span, + "use `notable_trait` instead", + String::from("notable_trait"), + Applicability::MachineApplicable, + ); + diag.note("`doc(spotlight)` is now a no-op"); + } + diag.emit(); }, ); is_valid = false; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4fcb8b6c1b7..ca9ddce7223 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -476,6 +476,7 @@ symbols! { doc_cfg, doc_keyword, doc_masked, + doc_notable_trait, doc_spotlight, doctest, document_private_items, @@ -799,6 +800,7 @@ symbols! { noreturn, nostack, not, + notable_trait, note, object_safe_for_dispatch, of, diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs index e9a99ddb6b1..cc4cf54a2f7 100644 --- a/library/core/src/future/future.rs +++ b/library/core/src/future/future.rs @@ -24,7 +24,8 @@ use crate::task::{Context, Poll}; /// `.await` the value. /// /// [`Waker`]: crate::task::Waker -#[doc(spotlight)] +#[cfg_attr(bootstrap, doc(spotlight))] +#[cfg_attr(not(bootstrap), doc(notable_trait))] #[must_use = "futures do nothing unless you `.await` or poll them"] #[stable(feature = "futures_api", since = "1.36.0")] #[lang = "future_trait"] diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index f8504e842ee..efb0c183821 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -92,7 +92,8 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} label = "`{Self}` is not an iterator", message = "`{Self}` is not an iterator" )] -#[doc(spotlight)] +#[cfg_attr(bootstrap, doc(spotlight))] +#[cfg_attr(not(bootstrap), doc(notable_trait))] #[rustc_diagnostic_item = "Iterator"] #[must_use = "iterators are lazy and do nothing unless consumed"] pub trait Iterator { diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index e10e1738de5..01b22cd90cb 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -108,7 +108,8 @@ #![feature(custom_inner_attributes)] #![feature(decl_macro)] #![feature(doc_cfg)] -#![feature(doc_spotlight)] +#![cfg_attr(bootstrap, feature(doc_spotlight))] +#![cfg_attr(not(bootstrap), feature(doc_notable_trait))] #![feature(duration_consts_2)] #![feature(duration_saturating_ops)] #![feature(extended_key_value_attributes)] diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 17002e3b860..37bba56177a 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -505,7 +505,8 @@ pub(crate) fn default_read_exact(this: &mut R, mut buf: &mut [ /// [`std::io`]: self /// [`File`]: crate::fs::File #[stable(feature = "rust1", since = "1.0.0")] -#[doc(spotlight)] +#[cfg_attr(bootstrap, doc(spotlight))] +#[cfg_attr(not(bootstrap), doc(notable_trait))] pub trait Read { /// Pull some bytes from this source into the specified buffer, returning /// how many bytes were read. @@ -1291,7 +1292,8 @@ impl Initializer { /// /// [`write_all`]: Write::write_all #[stable(feature = "rust1", since = "1.0.0")] -#[doc(spotlight)] +#[cfg_attr(bootstrap, doc(spotlight))] +#[cfg_attr(not(bootstrap), doc(notable_trait))] pub trait Write { /// Write a buffer into this writer, returning how many bytes were written. /// diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 8149858e103..33034b833ba 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -257,7 +257,8 @@ #![feature(doc_cfg)] #![feature(doc_keyword)] #![feature(doc_masked)] -#![feature(doc_spotlight)] +#![cfg_attr(bootstrap, feature(doc_spotlight))] +#![cfg_attr(not(bootstrap), feature(doc_notable_trait))] #![feature(dropck_eyepatch)] #![feature(duration_constants)] #![feature(duration_zero)] diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 7d1845dc957..28b81a40265 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -88,26 +88,28 @@ Book][unstable-doc-cfg] and [its tracking issue][issue-doc-cfg]. [unstable-doc-cfg]: ../unstable-book/language-features/doc-cfg.html [issue-doc-cfg]: https://github.com/rust-lang/rust/issues/43781 -### Adding your trait to the "Important Traits" dialog +### Adding your trait to the "Notable traits" dialog -Rustdoc keeps a list of a few traits that are believed to be "fundamental" to a given type when -implemented on it. These traits are intended to be the primary interface for their types, and are -often the only thing available to be documented on their types. For this reason, Rustdoc will track -when a given type implements one of these traits and call special attention to it when a function -returns one of these types. This is the "Important Traits" dialog, visible as a circle-i button next -to the function, which, when clicked, shows the dialog. +Rustdoc keeps a list of a few traits that are believed to be "fundamental" to +types that implement them. These traits are intended to be the primary interface +for their implementers, and are often most of the API available to be documented +on their types. For this reason, Rustdoc will track when a given type implements +one of these traits and call special attention to it when a function returns one +of these types. This is the "Notable traits" dialog, accessible as a circled `i` +button next to the function, which, when clicked, shows the dialog. -In the standard library, the traits that qualify for inclusion are `Iterator`, `io::Read`, and -`io::Write`. However, rather than being implemented as a hard-coded list, these traits have a -special marker attribute on them: `#[doc(spotlight)]`. This means that you could apply this -attribute to your own trait to include it in the "Important Traits" dialog in documentation. +In the standard library, some of the traits that are part of this list are +`Iterator`, `Future`, `io::Read`, and `io::Write`. However, rather than being +implemented as a hard-coded list, these traits have a special marker attribute +on them: `#[doc(notable_trait)]`. This means that you can apply this attribute +to your own trait to include it in the "Notable traits" dialog in documentation. -The `#[doc(spotlight)]` attribute currently requires the `#![feature(doc_spotlight)]` feature gate. -For more information, see [its chapter in the Unstable Book][unstable-spotlight] and [its tracking -issue][issue-spotlight]. +The `#[doc(notable_trait)]` attribute currently requires the `#![feature(doc_notable_trait)]` +feature gate. For more information, see [its chapter in the Unstable Book][unstable-notable_trait] +and [its tracking issue][issue-notable_trait]. -[unstable-spotlight]: ../unstable-book/language-features/doc-spotlight.html -[issue-spotlight]: https://github.com/rust-lang/rust/issues/45040 +[unstable-notable_trait]: ../unstable-book/language-features/doc-notable-trait.html +[issue-notable_trait]: https://github.com/rust-lang/rust/issues/45040 ### Exclude certain dependencies from documentation diff --git a/src/doc/unstable-book/src/language-features/doc-notable-trait.md b/src/doc/unstable-book/src/language-features/doc-notable-trait.md new file mode 100644 index 00000000000..dc402ed4253 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/doc-notable-trait.md @@ -0,0 +1,33 @@ +# `doc_notable_trait` + +The tracking issue for this feature is: [#45040] + +The `doc_notable_trait` feature allows the use of the `#[doc(notable_trait)]` +attribute, which will display the trait in a "Notable traits" dialog for +functions returning types that implement the trait. For example, this attribute +is applied to the `Iterator`, `Future`, `io::Read`, and `io::Write` traits in +the standard library. + +You can do this on your own traits like so: + +``` +#![feature(doc_notable_trait)] + +#[doc(notable_trait)] +pub trait MyTrait {} + +pub struct MyStruct; +impl MyTrait for MyStruct {} + +/// The docs for this function will have a button that displays a dialog about +/// `MyStruct` implementing `MyTrait`. +pub fn my_fn() -> MyStruct { MyStruct } +``` + +This feature was originally implemented in PR [#45039]. + +See also its documentation in [the rustdoc book][rustdoc-book-notable_trait]. + +[#45040]: https://github.com/rust-lang/rust/issues/45040 +[#45039]: https://github.com/rust-lang/rust/pull/45039 +[rustdoc-book-notable_trait]: ../../rustdoc/unstable-features.html#adding-your-trait-to-the-notable-traits-dialog diff --git a/src/doc/unstable-book/src/language-features/doc-spotlight.md b/src/doc/unstable-book/src/language-features/doc-spotlight.md deleted file mode 100644 index 75eff163318..00000000000 --- a/src/doc/unstable-book/src/language-features/doc-spotlight.md +++ /dev/null @@ -1,30 +0,0 @@ -# `doc_spotlight` - -The tracking issue for this feature is: [#45040] - -The `doc_spotlight` feature allows the use of the `spotlight` parameter to the `#[doc]` attribute, -to "spotlight" a specific trait on the return values of functions. Adding a `#[doc(spotlight)]` -attribute to a trait definition will make rustdoc print extra information for functions which return -a type that implements that trait. For example, this attribute is applied to the `Iterator`, -`io::Read`, `io::Write`, and `Future` traits in the standard library. - -You can do this on your own traits, like this: - -``` -#![feature(doc_spotlight)] - -#[doc(spotlight)] -pub trait MyTrait {} - -pub struct MyStruct; -impl MyTrait for MyStruct {} - -/// The docs for this function will have an extra line about `MyStruct` implementing `MyTrait`, -/// without having to write that yourself! -pub fn my_fn() -> MyStruct { MyStruct } -``` - -This feature was originally implemented in PR [#45039]. - -[#45040]: https://github.com/rust-lang/rust/issues/45040 -[#45039]: https://github.com/rust-lang/rust/pull/45039 diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 47a74238a7a..1bbbb71c6cc 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -628,7 +628,7 @@ crate fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) { let trait_ = clean::TraitWithExtraInfo { trait_, - is_spotlight: clean::utils::has_doc_flag(cx.tcx.get_attrs(did), sym::spotlight), + is_spotlight: clean::utils::has_doc_flag(cx.tcx.get_attrs(did), sym::notable_trait), }; cx.external_traits.borrow_mut().insert(did, trait_); cx.active_extern_traits.remove(&did); diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 9415caf8b6f..407f7b809ff 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -229,7 +229,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { if let clean::TraitItem(ref t) = *item.kind { self.cache.traits.entry(item.def_id).or_insert_with(|| clean::TraitWithExtraInfo { trait_: t.clone(), - is_spotlight: item.attrs.has_doc_flag(sym::spotlight), + is_spotlight: item.attrs.has_doc_flag(sym::notable_trait), }); } diff --git a/src/test/rustdoc-ui/doc-spotlight.fixed b/src/test/rustdoc-ui/doc-spotlight.fixed new file mode 100644 index 00000000000..6c90aace689 --- /dev/null +++ b/src/test/rustdoc-ui/doc-spotlight.fixed @@ -0,0 +1,10 @@ +// ignore-tidy-linelength +// check-pass +// run-rustfix + +#![feature(doc_notable_trait)] + +#[doc(notable_trait)] +//~^ WARN unknown `doc` attribute `spotlight` +//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +trait MyTrait {} diff --git a/src/test/rustdoc-ui/doc-spotlight.rs b/src/test/rustdoc-ui/doc-spotlight.rs new file mode 100644 index 00000000000..7cea553c4b0 --- /dev/null +++ b/src/test/rustdoc-ui/doc-spotlight.rs @@ -0,0 +1,10 @@ +// ignore-tidy-linelength +// check-pass +// run-rustfix + +#![feature(doc_notable_trait)] + +#[doc(spotlight)] +//~^ WARN unknown `doc` attribute `spotlight` +//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +trait MyTrait {} diff --git a/src/test/rustdoc-ui/doc-spotlight.stderr b/src/test/rustdoc-ui/doc-spotlight.stderr new file mode 100644 index 00000000000..e79cdc3d77a --- /dev/null +++ b/src/test/rustdoc-ui/doc-spotlight.stderr @@ -0,0 +1,14 @@ +warning: unknown `doc` attribute `spotlight` + --> $DIR/doc-spotlight.rs:7:7 + | +LL | #[doc(spotlight)] + | ^^^^^^^^^ help: use `notable_trait` instead + | + = note: `#[warn(invalid_doc_attributes)]` on by default + = 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 + = note: `doc(spotlight)` was renamed to `doc(notable_trait)` + = note: `doc(spotlight)` is now a no-op + +warning: 1 warning emitted + diff --git a/src/test/rustdoc/doc-spotlight.rs b/src/test/rustdoc/doc-notable_trait.rs similarity index 78% rename from src/test/rustdoc/doc-spotlight.rs rename to src/test/rustdoc/doc-notable_trait.rs index ddd46c3c215..58a24b855d6 100644 --- a/src/test/rustdoc/doc-spotlight.rs +++ b/src/test/rustdoc/doc-notable_trait.rs @@ -1,4 +1,4 @@ -#![feature(doc_spotlight)] +#![feature(doc_notable_trait)] pub struct Wrapper { inner: T, @@ -6,9 +6,9 @@ pub struct Wrapper { impl SomeTrait for Wrapper {} -#[doc(spotlight)] +#[doc(notable_trait)] pub trait SomeTrait { - // @has doc_spotlight/trait.SomeTrait.html + // @has doc_notable_trait/trait.SomeTrait.html // @has - '//code[@class="content"]' 'impl SomeTrait for Wrapper' fn wrap_me(self) -> Wrapper where Self: Sized { Wrapper { @@ -21,7 +21,7 @@ pub struct SomeStruct; impl SomeTrait for SomeStruct {} impl SomeStruct { - // @has doc_spotlight/struct.SomeStruct.html + // @has doc_notable_trait/struct.SomeStruct.html // @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct' // @has - '//code[@class="content"]' 'impl SomeTrait for Wrapper' pub fn new() -> SomeStruct { @@ -29,7 +29,7 @@ impl SomeStruct { } } -// @has doc_spotlight/fn.bare_fn.html +// @has doc_notable_trait/fn.bare_fn.html // @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct' pub fn bare_fn() -> SomeStruct { SomeStruct diff --git a/src/test/ui/feature-gates/feature-gate-doc_notable_trait.rs b/src/test/ui/feature-gates/feature-gate-doc_notable_trait.rs new file mode 100644 index 00000000000..7f3392eadad --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-doc_notable_trait.rs @@ -0,0 +1,4 @@ +#[doc(notable_trait)] //~ ERROR: `#[doc(notable_trait)]` is experimental +trait SomeTrait {} + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-doc_notable_trait.stderr b/src/test/ui/feature-gates/feature-gate-doc_notable_trait.stderr new file mode 100644 index 00000000000..1f9bef40c4e --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-doc_notable_trait.stderr @@ -0,0 +1,12 @@ +error[E0658]: `#[doc(notable_trait)]` is experimental + --> $DIR/feature-gate-doc_notable_trait.rs:1:1 + | +LL | #[doc(notable_trait)] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #45040 for more information + = help: add `#![feature(doc_notable_trait)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-doc_spotlight.rs b/src/test/ui/feature-gates/feature-gate-doc_spotlight.rs deleted file mode 100644 index 452b45b3445..00000000000 --- a/src/test/ui/feature-gates/feature-gate-doc_spotlight.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[doc(spotlight)] //~ ERROR: `#[doc(spotlight)]` is experimental -trait SomeTrait {} - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr b/src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr deleted file mode 100644 index 010d74054a4..00000000000 --- a/src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: `#[doc(spotlight)]` is experimental - --> $DIR/feature-gate-doc_spotlight.rs:1:1 - | -LL | #[doc(spotlight)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #45040 for more information - = help: add `#![feature(doc_spotlight)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. From 770a9cf780b6560e2c9224ae4588c6f7baa5add6 Mon Sep 17 00:00:00 2001 From: SNCPlay42 Date: Fri, 8 Jan 2021 22:07:49 +0000 Subject: [PATCH 067/370] fix expected/found order on impl trait projection mismatch --- compiler/rustc_middle/src/traits/mod.rs | 3 ++ compiler/rustc_middle/src/ty/error.rs | 48 ++++++++++++------- .../rustc_trait_selection/src/opaque_types.rs | 2 +- .../src/traits/error_reporting/mod.rs | 1 + .../src/traits/error_reporting/suggestions.rs | 1 + ...mpl-trait-return-missing-constraint.stderr | 8 ++-- .../type-mismatch-signature-deduction.stderr | 6 +-- .../bound-normalization-fail.stderr | 12 ++--- src/test/ui/impl-trait/equality2.stderr | 6 ++- .../issues/issue-70877.full_tait.stderr | 8 ++-- .../issues/issue-70877.min_tait.stderr | 8 ++-- .../issue-63279.full_tait.stderr | 6 +-- .../issue-63279.min_tait.stderr | 6 +-- 13 files changed, 69 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 0bd0a701fb2..3650866c007 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -323,6 +323,9 @@ pub enum ObligationCauseCode<'tcx> { /// #[feature(trivial_bounds)] is not enabled TrivialBound, + + /// If `X` is the concrete type of an opaque type `impl Y`, then `X` must implement `Y` + OpaqueType, } impl ObligationCauseCode<'_> { diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index f19cc998449..8ff84b0e743 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -509,13 +509,18 @@ impl Trait for X { "consider constraining the associated type `{}` to `{}`", values.found, values.expected, ); - if !self.suggest_constraint( + if !(self.suggest_constraining_opaque_associated_type( + db, + &msg, + proj_ty, + values.expected, + ) || self.suggest_constraint( db, &msg, body_owner_def_id, proj_ty, values.expected, - ) { + )) { db.help(&msg); db.note( "for more information, visit \ @@ -699,20 +704,7 @@ impl Trait for X { } } - if let ty::Opaque(def_id, _) = *proj_ty.self_ty().kind() { - // When the expected `impl Trait` is not defined in the current item, it will come from - // a return type. This can occur when dealing with `TryStream` (#71035). - if self.constrain_associated_type_structured_suggestion( - db, - self.def_span(def_id), - &assoc, - proj_ty.trait_ref_and_own_substs(self).1, - values.found, - &msg, - ) { - return; - } - } + self.suggest_constraining_opaque_associated_type(db, &msg, proj_ty, values.found); if self.point_at_associated_type(db, body_owner_def_id, values.found) { return; @@ -750,6 +742,30 @@ fn foo(&self) -> Self::T { String::new() } } } + /// When the expected `impl Trait` is not defined in the current item, it will come from + /// a return type. This can occur when dealing with `TryStream` (#71035). + fn suggest_constraining_opaque_associated_type( + self, + db: &mut DiagnosticBuilder<'_>, + msg: &str, + proj_ty: &ty::ProjectionTy<'tcx>, + ty: Ty<'tcx>, + ) -> bool { + let assoc = self.associated_item(proj_ty.item_def_id); + if let ty::Opaque(def_id, _) = *proj_ty.self_ty().kind() { + self.constrain_associated_type_structured_suggestion( + db, + self.def_span(def_id), + &assoc, + proj_ty.trait_ref_and_own_substs(self).1, + ty, + &msg, + ) + } else { + false + } + } + fn point_at_methods_that_satisfy_associated_type( self, db: &mut DiagnosticBuilder<'_>, diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index d6a585e626c..186256101e4 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -1171,7 +1171,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { // This also instantiates nested instances of `impl Trait`. let predicate = self.instantiate_opaque_types_in_map(predicate); - let cause = traits::ObligationCause::new(span, self.body_id, traits::MiscObligation); + let cause = traits::ObligationCause::new(span, self.body_id, traits::OpaqueType); // Require that the predicate holds for the concrete type. debug!("instantiate_opaque_types: predicate={:?}", predicate); 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 a3faf4cb7d4..5de4fb1ce8c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1194,6 +1194,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { ObligationCauseCode::ItemObligation(_) | ObligationCauseCode::BindingObligation(_, _) | ObligationCauseCode::ObjectCastObligation(_) + | ObligationCauseCode::OpaqueType ); if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp( 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 c1b105f1d84..6292413d7bd 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1840,6 +1840,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { | ObligationCauseCode::MethodReceiver | ObligationCauseCode::ReturnNoExpression | ObligationCauseCode::UnifyReceiver(..) + | ObligationCauseCode::OpaqueType | ObligationCauseCode::MiscObligation => {} ObligationCauseCode::SliceOrArrayElem => { err.note("slice and array elements must have `Sized` type"); diff --git a/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr index b0e9e33a6c3..89e05b61fc9 100644 --- a/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr +++ b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr @@ -2,13 +2,13 @@ error[E0271]: type mismatch resolving `::Item == i32` --> $DIR/impl-trait-return-missing-constraint.rs:25:13 | LL | fn bar() -> impl Bar { - | -------- the expected opaque type + | -------- the found opaque type ... LL | fn baz() -> impl Bar { - | ^^^^^^^^^^^^^^^^^^^^ expected associated type, found `i32` + | ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found associated type | - = note: expected associated type `::Item` - found type `i32` + = note: expected type `i32` + found associated type `::Item` help: consider constraining the associated type `::Item` to `i32` | LL | fn bar() -> impl Bar { diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.stderr b/src/test/ui/generator/type-mismatch-signature-deduction.stderr index 30e23ea8f65..3f1f33a3b12 100644 --- a/src/test/ui/generator/type-mismatch-signature-deduction.stderr +++ b/src/test/ui/generator/type-mismatch-signature-deduction.stderr @@ -16,10 +16,10 @@ error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature- --> $DIR/type-mismatch-signature-deduction.rs:5:13 | LL | fn foo() -> impl Generator { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `i32` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found enum `Result` | - = note: expected enum `Result<{integer}, _>` - found type `i32` + = note: expected type `i32` + found enum `Result<{integer}, _>` error: aborting due to 2 previous errors diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr index a7d06c71663..6958cd97a4a 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.stderr +++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr @@ -11,10 +11,10 @@ error[E0271]: type mismatch resolving ` as FooLike>::Output == $DIR/bound-normalization-fail.rs:27:32 | LL | fn foo_fail() -> impl FooLike { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()` | - = note: expected type `()` - found associated type `::Assoc` + = note: expected associated type `::Assoc` + found type `()` help: consider constraining the associated type `::Assoc` to `()` | LL | fn foo_fail>() -> impl FooLike { @@ -30,10 +30,10 @@ error[E0271]: type mismatch resolving ` as FooLike>::Output == $DIR/bound-normalization-fail.rs:43:41 | LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()` | - = note: expected type `()` - found associated type `>::Assoc` + = note: expected associated type `>::Assoc` + found type `()` help: consider constraining the associated type `>::Assoc` to `()` | LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike { diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr index 1443b76048b..3318866c52c 100644 --- a/src/test/ui/impl-trait/equality2.stderr +++ b/src/test/ui/impl-trait/equality2.stderr @@ -35,8 +35,10 @@ LL | let _: i32 = Leak::leak(hide(0_i32)); | = note: expected type `i32` found associated type `::T` - = help: consider constraining the associated type `::T` to `i32` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html +help: consider constraining the associated type `::T` to `i32` + | +LL | fn hide(x: T) -> impl Foo { + | ^^^^^^^^^ error[E0308]: mismatched types --> $DIR/equality2.rs:38:10 diff --git a/src/test/ui/impl-trait/issues/issue-70877.full_tait.stderr b/src/test/ui/impl-trait/issues/issue-70877.full_tait.stderr index bd4d4fdf2a6..8e42b9d46db 100644 --- a/src/test/ui/impl-trait/issues/issue-70877.full_tait.stderr +++ b/src/test/ui/impl-trait/issues/issue-70877.full_tait.stderr @@ -2,13 +2,13 @@ error[E0271]: type mismatch resolving `::Item == Box<(dyn for<' --> $DIR/issue-70877.rs:11:12 | LL | type FooRet = impl std::fmt::Debug; - | -------------------- the expected opaque type + | -------------------- the found opaque type ... LL | type Foo = impl Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found enum `Option` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Option`, found opaque type | - = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>` - found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option + 'static)>` + = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option + 'static)>` + found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>` error: aborting due to previous error diff --git a/src/test/ui/impl-trait/issues/issue-70877.min_tait.stderr b/src/test/ui/impl-trait/issues/issue-70877.min_tait.stderr index bd4d4fdf2a6..8e42b9d46db 100644 --- a/src/test/ui/impl-trait/issues/issue-70877.min_tait.stderr +++ b/src/test/ui/impl-trait/issues/issue-70877.min_tait.stderr @@ -2,13 +2,13 @@ error[E0271]: type mismatch resolving `::Item == Box<(dyn for<' --> $DIR/issue-70877.rs:11:12 | LL | type FooRet = impl std::fmt::Debug; - | -------------------- the expected opaque type + | -------------------- the found opaque type ... LL | type Foo = impl Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found enum `Option` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Option`, found opaque type | - = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>` - found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option + 'static)>` + = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option + 'static)>` + found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>` error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.full_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-63279.full_tait.stderr index f544f61df97..53a0016c08e 100644 --- a/src/test/ui/type-alias-impl-trait/issue-63279.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-63279.full_tait.stderr @@ -11,10 +11,10 @@ error[E0271]: type mismatch resolving `<[closure@$DIR/issue-63279.rs:11:5: 11:28 --> $DIR/issue-63279.rs:8:16 | LL | type Closure = impl FnOnce(); - | ^^^^^^^^^^^^^ expected opaque type, found `()` + | ^^^^^^^^^^^^^ expected `()`, found opaque type | - = note: expected opaque type `impl FnOnce<()>` - found unit type `()` + = note: expected unit type `()` + found opaque type `impl FnOnce<()>` error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.min_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-63279.min_tait.stderr index bdf414d0bad..be386ab90ea 100644 --- a/src/test/ui/type-alias-impl-trait/issue-63279.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-63279.min_tait.stderr @@ -11,10 +11,10 @@ error[E0271]: type mismatch resolving `<[closure@$DIR/issue-63279.rs:11:5: 11:28 --> $DIR/issue-63279.rs:8:16 | LL | type Closure = impl FnOnce(); - | ^^^^^^^^^^^^^ expected opaque type, found `()` + | ^^^^^^^^^^^^^ expected `()`, found opaque type | - = note: expected opaque type `impl FnOnce<()>` - found unit type `()` + = note: expected unit type `()` + found opaque type `impl FnOnce<()>` error: aborting due to 2 previous errors From 525e23adafc06aec29338cbe46794c63920608a7 Mon Sep 17 00:00:00 2001 From: SNCPlay42 Date: Fri, 8 Jan 2021 22:16:24 +0000 Subject: [PATCH 068/370] peel derives when checking normalized is expected --- .../src/traits/error_reporting/mod.rs | 2 +- .../ui/associated-types/issue-44153.stderr | 2 +- ...rojection-mismatch-in-impl-where-clause.rs | 20 +++++++++++++++++++ ...ction-mismatch-in-impl-where-clause.stderr | 11 ++++++++++ src/test/ui/issues/issue-33941.stderr | 12 +++++------ src/test/ui/issues/issue-39970.stderr | 2 +- 6 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs create mode 100644 src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr 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 5de4fb1ce8c..9dc3a143884 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1190,7 +1190,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { ); let is_normalized_ty_expected = !matches!( - obligation.cause.code, + obligation.cause.code.peel_derives(), ObligationCauseCode::ItemObligation(_) | ObligationCauseCode::BindingObligation(_, _) | ObligationCauseCode::ObjectCastObligation(_) diff --git a/src/test/ui/associated-types/issue-44153.stderr b/src/test/ui/associated-types/issue-44153.stderr index 8ef71087958..cafc8ec52ca 100644 --- a/src/test/ui/associated-types/issue-44153.stderr +++ b/src/test/ui/associated-types/issue-44153.stderr @@ -5,7 +5,7 @@ LL | fn visit() {} | ---------- required by `Visit::visit` ... LL | <() as Visit>::visit(); - | ^^^^^^^^^^^^^^^^^^^^ expected `()`, found `&()` + | ^^^^^^^^^^^^^^^^^^^^ expected `&()`, found `()` | = note: required because of the requirements on the impl of `Visit` for `()` diff --git a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs new file mode 100644 index 00000000000..b4fd6b3e743 --- /dev/null +++ b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs @@ -0,0 +1,20 @@ +pub trait Super { + type Assoc; +} + +impl Super for () { + type Assoc = u8; +} + +pub trait Test {} + +impl Test for T where T: Super {} + +fn test() -> impl Test { + //~^ERROR type mismatch resolving `<() as Super>::Assoc == ()` + () +} + +fn main() { + let a = test(); +} diff --git a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr new file mode 100644 index 00000000000..d1956a9afb8 --- /dev/null +++ b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr @@ -0,0 +1,11 @@ +error[E0271]: type mismatch resolving `<() as Super>::Assoc == ()` + --> $DIR/projection-mismatch-in-impl-where-clause.rs:13:14 + | +LL | fn test() -> impl Test { + | ^^^^^^^^^ expected `()`, found `u8` + | + = note: required because of the requirements on the impl of `Test` for `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/issues/issue-33941.stderr b/src/test/ui/issues/issue-33941.stderr index e91dae08b3a..043658c9508 100644 --- a/src/test/ui/issues/issue-33941.stderr +++ b/src/test/ui/issues/issue-33941.stderr @@ -11,10 +11,10 @@ error[E0271]: type mismatch resolving ` $DIR/issue-33941.rs:4:14 | LL | for _ in HashMap::new().iter().cloned() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found tuple | - = note: expected tuple `(&_, &_)` - found reference `&_` + = note: expected reference `&_` + found tuple `(&_, &_)` = note: required because of the requirements on the impl of `Iterator` for `Cloned>` = note: required because of the requirements on the impl of `IntoIterator` for `Cloned>` = note: required by `into_iter` @@ -23,10 +23,10 @@ error[E0271]: type mismatch resolving ` $DIR/issue-33941.rs:4:14 | LL | for _ in HashMap::new().iter().cloned() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found tuple | - = note: expected tuple `(&_, &_)` - found reference `&_` + = note: expected reference `&_` + found tuple `(&_, &_)` = note: required because of the requirements on the impl of `Iterator` for `Cloned>` = note: required by `std::iter::Iterator::next` diff --git a/src/test/ui/issues/issue-39970.stderr b/src/test/ui/issues/issue-39970.stderr index 6f342b459c0..8ecde9d1e68 100644 --- a/src/test/ui/issues/issue-39970.stderr +++ b/src/test/ui/issues/issue-39970.stderr @@ -5,7 +5,7 @@ LL | fn visit() {} | ---------- required by `Visit::visit` ... LL | <() as Visit>::visit(); - | ^^^^^^^^^^^^^^^^^^^^ expected `&()`, found `()` + | ^^^^^^^^^^^^^^^^^^^^ expected `()`, found `&()` | = note: required because of the requirements on the impl of `Visit` for `()` From 218b383f8f00808a08c08e131470e1ab5c2e6749 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 17 Mar 2021 13:54:40 +0100 Subject: [PATCH 069/370] Rustfmt --- src/metadata.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/metadata.rs b/src/metadata.rs index dda9285a38a..c5189c972cd 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -46,7 +46,7 @@ impl MetadataLoader for CraneliftMetadataLoader { let archive = object::read::archive::ArchiveFile::parse(&*data) .map_err(|e| format!("{:?}", e))?; - for entry_result in archive.members() { + for entry_result in archive.members() { let entry = entry_result.map_err(|e| format!("{:?}", e))?; if entry.name() == METADATA_FILENAME.as_bytes() { return Ok(entry.data()); From e86b95480fac70673bd837e7fcfa45458bd52eb7 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 17 Mar 2021 13:56:54 +0100 Subject: [PATCH 070/370] Directly invoke the main function in JIT mode Fixes #1151 --- src/driver/jit.rs | 74 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 245df03ffb8..dec95d65714 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -7,6 +7,7 @@ use std::os::raw::{c_char, c_int}; use rustc_codegen_ssa::CrateInfo; use rustc_middle::mir::mono::MonoItem; +use rustc_session::config::EntryFnType; use cranelift_jit::{JITBuilder, JITModule}; @@ -32,16 +33,6 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { let mut jit_module = JITModule::new(jit_builder); assert_eq!(pointer_ty(tcx), jit_module.target_config().pointer_type()); - let sig = Signature { - params: vec![ - AbiParam::new(jit_module.target_config().pointer_type()), - AbiParam::new(jit_module.target_config().pointer_type()), - ], - returns: vec![AbiParam::new(jit_module.target_config().pointer_type() /*isize*/)], - call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)), - }; - let main_func_id = jit_module.declare_function("main", Linkage::Import, &sig).unwrap(); - let (_, cgus) = tcx.collect_and_partition_mono_items(LOCAL_CRATE); let mono_items = cgus .iter() @@ -86,24 +77,17 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { tcx.sess.fatal("Inline asm is not supported in JIT mode"); } - crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, &mut unwind_context); crate::allocator::codegen(tcx, &mut jit_module, &mut unwind_context); tcx.sess.abort_if_errors(); jit_module.finalize_definitions(); - let _unwind_register_guard = unsafe { unwind_context.register_jit(&jit_module) }; - let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id); - println!( "Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed" ); - let f: extern "C" fn(c_int, *const *const c_char) -> c_int = - unsafe { ::std::mem::transmute(finalized_main) }; - let args = ::std::env::var("CG_CLIF_JIT_ARGS").unwrap_or_else(|_| String::new()); let args = std::iter::once(&*tcx.crate_name(LOCAL_CRATE).as_str().to_string()) .chain(args.split(' ')) @@ -118,12 +102,58 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { BACKEND_CONFIG.with(|tls_backend_config| { assert!(tls_backend_config.borrow_mut().replace(backend_config).is_none()) }); - CURRENT_MODULE - .with(|current_module| assert!(current_module.borrow_mut().replace(jit_module).is_none())); - let ret = f(args.len() as c_int, argv.as_ptr()); + let (main_def_id, entry_ty) = tcx.entry_fn(LOCAL_CRATE).unwrap(); + let instance = Instance::mono(tcx, main_def_id.to_def_id()).polymorphize(tcx); - std::process::exit(ret); + match entry_ty { + EntryFnType::Main => { + // FIXME set program arguments somehow + + let main_sig = Signature { + params: vec![], + returns: vec![], + call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)), + }; + let main_func_id = jit_module + .declare_function(tcx.symbol_name(instance).name, Linkage::Import, &main_sig) + .unwrap(); + let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id); + + CURRENT_MODULE.with(|current_module| { + assert!(current_module.borrow_mut().replace(jit_module).is_none()) + }); + + let f: extern "C" fn() = unsafe { ::std::mem::transmute(finalized_main) }; + f(); + std::process::exit(0); + } + EntryFnType::Start => { + let start_sig = Signature { + params: vec![ + AbiParam::new(jit_module.target_config().pointer_type()), + AbiParam::new(jit_module.target_config().pointer_type()), + ], + returns: vec![AbiParam::new( + jit_module.target_config().pointer_type(), /*isize*/ + )], + call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)), + }; + let start_func_id = jit_module + .declare_function(tcx.symbol_name(instance).name, Linkage::Import, &start_sig) + .unwrap(); + let finalized_start: *const u8 = jit_module.get_finalized_function(start_func_id); + + CURRENT_MODULE.with(|current_module| { + assert!(current_module.borrow_mut().replace(jit_module).is_none()) + }); + + let f: extern "C" fn(c_int, *const *const c_char) -> c_int = + unsafe { ::std::mem::transmute(finalized_start) }; + let ret = f(args.len() as c_int, argv.as_ptr()); + std::process::exit(ret); + } + } } #[no_mangle] @@ -220,7 +250,7 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> { imported_symbols } -pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'_, 'tcx>, inst: Instance<'tcx>) { +fn codegen_shim<'tcx>(cx: &mut CodegenCx<'_, 'tcx>, inst: Instance<'tcx>) { let tcx = cx.tcx; let pointer_type = cx.module.target_config().pointer_type(); From 33d22f84000eca68397ba50d5481cfb11ce35145 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Mon, 15 Mar 2021 15:34:22 +0100 Subject: [PATCH 071/370] BTree: clarify order sanity enforced by range searches --- library/alloc/src/collections/btree/map.rs | 6 ++++++ library/alloc/src/collections/btree/navigate.rs | 15 +++++++++++---- library/alloc/src/collections/btree/search.rs | 15 ++++++++++++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 622983996aa..40f3d5510cd 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -1018,6 +1018,9 @@ impl BTreeMap { /// /// Panics if range `start > end`. /// Panics if range `start == end` and both bounds are `Excluded`. + /// May panic if the [`Ord`] implementation of type `T` is ill-defined, + /// either because it does not form a total order or because it does not + /// correspond to the [`Ord`] implementation of type `K`. /// /// # Examples /// @@ -1061,6 +1064,9 @@ impl BTreeMap { /// /// Panics if range `start > end`. /// Panics if range `start == end` and both bounds are `Excluded`. + /// May panic if the [`Ord`] implementation of type `T` is ill-defined, + /// either because it does not form a total order or because it does not + /// correspond to the [`Ord`] implementation of type `K`. /// /// # Examples /// diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs index c2c99a9360c..4399feaccc9 100644 --- a/library/alloc/src/collections/btree/navigate.rs +++ b/library/alloc/src/collections/btree/navigate.rs @@ -29,11 +29,18 @@ impl LeafRange { impl NodeRef { /// Finds the distinct leaf edges delimiting a specified range in a tree. - /// Returns either a pair of different handles into the same tree or a pair - /// of empty options. + /// + /// If such distinct edges exist, returns them in ascending order, meaning + /// that a non-zero number of calls to `next_unchecked` on the `front` of + /// the result and/or calls to `next_back_unchecked` on the `back` of the + /// result will eventually reach the same edge. + /// + /// If there are no such edges, i.e., if the tree contains no key within + /// the range, returns a pair of empty options. + /// /// # Safety - /// Unless `BorrowType` is `Immut`, do not use the duplicate handles to - /// visit the same KV twice. + /// Unless `BorrowType` is `Immut`, do not use the handles to visit the same + /// KV twice. unsafe fn find_leaf_edges_spanning_range( self, range: R, diff --git a/library/alloc/src/collections/btree/search.rs b/library/alloc/src/collections/btree/search.rs index f376b3cde02..7443db95203 100644 --- a/library/alloc/src/collections/btree/search.rs +++ b/library/alloc/src/collections/btree/search.rs @@ -68,13 +68,18 @@ impl NodeRef( mut self, @@ -115,6 +120,10 @@ impl NodeRef upper_edge_idx { + // Since we already checked the range bounds, this can only + // happen if `Q: Ord` does not implement a total order or does + // not correspond to the `K: Ord` implementation that is used + // while populating the tree. panic!("Ord is ill-defined in BTreeMap range") } if lower_edge_idx < upper_edge_idx { From 79348f49792cb4831a57ca817792ab72308d9325 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 18 Mar 2021 05:25:47 +0900 Subject: [PATCH 072/370] `cargo update -p parking_lot -p parking_lot_core` Changelog: https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md#parking_lot_core-083-2021-02-12 The full log: ``` Removing cloudabi v0.1.0 Updating parking_lot v0.11.0 -> v0.11.1 Updating parking_lot_core v0.8.0 -> v0.8.3 ``` --- Cargo.lock | 22 ++++++---------------- src/tools/tidy/src/deps.rs | 2 -- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 203d8acb5b4..757cd29ac80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -613,15 +613,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "cloudabi" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" -dependencies = [ - "bitflags", -] - [[package]] name = "cmake" version = "0.1.44" @@ -2492,9 +2483,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733" +checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" dependencies = [ "instant", "lock_api", @@ -2503,15 +2494,14 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" +checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" dependencies = [ - "cfg-if 0.1.10", - "cloudabi", + "cfg-if 1.0.0", "instant", "libc", - "redox_syscall 0.1.57", + "redox_syscall 0.2.5", "smallvec 1.6.1", "winapi 0.3.9", ] diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 06dc16f7676..5ec2fb6ca79 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -32,7 +32,6 @@ const EXCEPTIONS: &[(&str, &str)] = &[ ("fuchsia-zircon", "BSD-3-Clause"), // rustdoc, rustc, cargo (jobserver & tempdir) ("colored", "MPL-2.0"), // rustfmt ("ordslice", "Apache-2.0"), // rls - ("cloudabi", "BSD-2-Clause"), // (rls -> crossbeam-channel 0.2 -> rand 0.5) ("ryu", "Apache-2.0 OR BSL-1.0"), // rls/cargo/... (because of serde) ("bytesize", "Apache-2.0"), // cargo ("im-rc", "MPL-2.0+"), // cargo @@ -76,7 +75,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "cfg-if", "chalk-derive", "chalk-ir", - "cloudabi", "cmake", "compiler_builtins", "cpuid-bool", From 2b0e27e2423bfa4e878390afaafd47e72ae0c30b Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 18 Mar 2021 05:34:05 +0900 Subject: [PATCH 073/370] `cargo update -p bytecount` Commit range: https://github.com/llogiq/bytecount/compare/b0f5fba8069b993b251a95473910853eff0b888b...8dcd43753cde591fc10dab6e54be3e2fc6e938ce The full log: ``` Updating bytecount v0.6.0 -> v0.6.2 Adding libm v0.1.4 Removing packed_simd v0.3.3 Adding packed_simd_2 v0.3.4 ``` --- Cargo.lock | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 757cd29ac80..4a4335ba498 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,11 +252,11 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "bytecount" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0017894339f586ccb943b01b9555de56770c11cda818e7e3d8bd93f4ed7f46e" +checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e" dependencies = [ - "packed_simd", + "packed_simd_2", ] [[package]] @@ -1901,6 +1901,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" + [[package]] name = "libnghttp2-sys" version = "0.1.4+1.41.0" @@ -2435,12 +2441,13 @@ dependencies = [ ] [[package]] -name = "packed_simd" -version = "0.3.3" +name = "packed_simd_2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a85ea9fc0d4ac0deb6fe7911d38786b32fc11119afd9e9d38b84ff691ce64220" +checksum = "3278e0492f961fd4ae70909f56b2723a7e8d01a228427294e19cdfdebda89a17" dependencies = [ "cfg-if 0.1.10", + "libm", ] [[package]] From dd166da8f83c0792e2652cf64a2a2fd5f635d11c Mon Sep 17 00:00:00 2001 From: The8472 Date: Wed, 17 Mar 2021 23:45:03 +0100 Subject: [PATCH 074/370] generalize slice::fill specialization for byte-sized items This should also improve cross-crate inlining since the method is generic --- library/core/src/slice/specialize.rs | 49 ++++++++-------------------- 1 file changed, 13 insertions(+), 36 deletions(-) diff --git a/library/core/src/slice/specialize.rs b/library/core/src/slice/specialize.rs index 16a9588989c..425cf71626f 100644 --- a/library/core/src/slice/specialize.rs +++ b/library/core/src/slice/specialize.rs @@ -1,3 +1,4 @@ +use crate::mem::{size_of, transmute_copy}; use crate::ptr::write_bytes; pub(super) trait SpecFill { @@ -17,42 +18,18 @@ impl SpecFill for [T] { } impl SpecFill for [T] { - default fn spec_fill(&mut self, value: T) { - for item in self.iter_mut() { - *item = value; - } - } -} - -impl SpecFill for [u8] { - fn spec_fill(&mut self, value: u8) { - // SAFETY: this is slice of u8 - unsafe { - let ptr = self.as_mut_ptr(); - let len = self.len(); - write_bytes(ptr, value, len); - } - } -} - -impl SpecFill for [i8] { - fn spec_fill(&mut self, value: i8) { - // SAFETY: this is slice of i8 - unsafe { - let ptr = self.as_mut_ptr(); - let len = self.len(); - write_bytes(ptr, value as u8, len); - } - } -} - -impl SpecFill for [bool] { - fn spec_fill(&mut self, value: bool) { - // SAFETY: this is slice of bool - unsafe { - let ptr = self.as_mut_ptr(); - let len = self.len(); - write_bytes(ptr, value as u8, len); + fn spec_fill(&mut self, value: T) { + if size_of::() == 1 { + // SAFETY: The size_of check above ensures that values are 1 byte wide, as required + // for the transmute and write_bytes + unsafe { + let value: u8 = transmute_copy(&value); + write_bytes(self.as_mut_ptr(), value, self.len()); + } + } else { + for item in self.iter_mut() { + *item = value; + } } } } From d7fdd9065544bc6819ec34b61c93fd9674d8db8f Mon Sep 17 00:00:00 2001 From: The8472 Date: Thu, 18 Mar 2021 00:02:39 +0100 Subject: [PATCH 075/370] add bench --- library/core/benches/slice.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/library/core/benches/slice.rs b/library/core/benches/slice.rs index dbab0085686..04efa520787 100644 --- a/library/core/benches/slice.rs +++ b/library/core/benches/slice.rs @@ -114,3 +114,16 @@ rotate!(rotate_16_usize_4, 16, |i| [i; 4]); rotate!(rotate_16_usize_5, 16, |i| [i; 5]); rotate!(rotate_64_usize_4, 64, |i| [i; 4]); rotate!(rotate_64_usize_5, 64, |i| [i; 5]); + +#[bench] +fn fill_byte_sized(b: &mut Bencher) { + #[derive(Copy, Clone)] + struct NewType(u8); + + let mut ary = [NewType(0); 1024]; + + b.iter(|| { + let slice = &mut ary[..]; + black_box(slice.fill(black_box(NewType(42)))); + }); +} From 664b25ea38f9a7e826048df1490a101adbc7d6d5 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 18 Mar 2021 12:19:31 +0100 Subject: [PATCH 076/370] Rustup to rustc 1.52.0-nightly (36f1f04f1 2021-03-17) --- build_sysroot/Cargo.lock | 4 ++-- rust-toolchain | 2 +- src/driver/aot.rs | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index cd0526b0129..22557726889 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" +checksum = "538c092e5586f4cdd7dd8078c4a79220e3e168880218124dcbce860f0ea938c6" dependencies = [ "rustc-std-workspace-core", ] diff --git a/rust-toolchain b/rust-toolchain index d00e2bee746..a0b828e39a4 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-03-09" +channel = "nightly-2021-03-18" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 0f1da66170a..3f3cdab058b 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -165,9 +165,8 @@ pub(super) fn run_aot( ) -> Box<(CodegenResults, FxHashMap)> { use rustc_span::symbol::sym; - let subsystem = tcx - .sess - .first_attr_value_str_by_name(&tcx.hir().krate().item.attrs, sym::windows_subsystem); + let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); + let subsystem = tcx.sess.first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem); let windows_subsystem = subsystem.map(|subsystem| { if subsystem != sym::windows && subsystem != sym::console { tcx.sess.fatal(&format!( From 0069007d5b17b19bf6a7686dec7dee7be46dcd47 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 18 Mar 2021 12:20:24 +0100 Subject: [PATCH 077/370] Avoid nightly feature usage where easily possible --- example/mini_core_hello_world.rs | 5 +---- src/base.rs | 24 ++++++++++-------------- src/lib.rs | 4 ---- src/pretty_clif.rs | 5 +---- 4 files changed, 12 insertions(+), 26 deletions(-) diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 08ceaeb6544..ea37ca98b59 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -1,7 +1,4 @@ -#![feature( - no_core, start, lang_items, box_syntax, never_type, linkage, - extern_types, thread_local -)] +#![feature(no_core, lang_items, box_syntax, never_type, linkage, extern_types, thread_local)] #![no_core] #![allow(dead_code, non_camel_case_types)] diff --git a/src/base.rs b/src/base.rs index ee0244b1ad0..33a28ac733e 100644 --- a/src/base.rs +++ b/src/base.rs @@ -465,16 +465,16 @@ fn codegen_stmt<'tcx>( let val = crate::constant::codegen_tls_ref(fx, def_id, lval.layout()); lval.write_cvalue(fx, val); } - Rvalue::BinaryOp(bin_op, box (ref lhs, ref rhs)) => { - let lhs = codegen_operand(fx, lhs); - let rhs = codegen_operand(fx, rhs); + Rvalue::BinaryOp(bin_op, ref lhs_rhs) => { + let lhs = codegen_operand(fx, &lhs_rhs.0); + let rhs = codegen_operand(fx, &lhs_rhs.1); let res = crate::num::codegen_binop(fx, bin_op, lhs, rhs); lval.write_cvalue(fx, res); } - Rvalue::CheckedBinaryOp(bin_op, box (ref lhs, ref rhs)) => { - let lhs = codegen_operand(fx, lhs); - let rhs = codegen_operand(fx, rhs); + Rvalue::CheckedBinaryOp(bin_op, ref lhs_rhs) => { + let lhs = codegen_operand(fx, &lhs_rhs.0); + let rhs = codegen_operand(fx, &lhs_rhs.1); let res = if !fx.tcx.sess.overflow_checks() { let val = @@ -835,19 +835,15 @@ fn codegen_stmt<'tcx>( } } StatementKind::Coverage { .. } => fx.tcx.sess.fatal("-Zcoverage is unimplemented"), - StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { - src, - dst, - count, - }) => { - let dst = codegen_operand(fx, dst); + StatementKind::CopyNonOverlapping(inner) => { + let dst = codegen_operand(fx, &inner.dst); let pointee = dst .layout() .pointee_info_at(fx, rustc_target::abi::Size::ZERO) .expect("Expected pointer"); let dst = dst.load_scalar(fx); - let src = codegen_operand(fx, src).load_scalar(fx); - let count = codegen_operand(fx, count).load_scalar(fx); + let src = codegen_operand(fx, &inner.src).load_scalar(fx); + let count = codegen_operand(fx, &inner.count).load_scalar(fx); let elem_size: u64 = pointee.size.bytes(); let bytes = if elem_size != 1 { fx.bcx.ins().imul_imm(count, elem_size as i64) diff --git a/src/lib.rs b/src/lib.rs index 158f5d4b9d2..63fb1c40844 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,7 @@ #![feature( rustc_private, decl_macro, - type_alias_impl_trait, - associated_type_bounds, never_type, - try_blocks, - box_patterns, hash_drain_filter )] #![warn(rust_2018_idioms)] diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index 855a0cc8e4a..d22ea3772ee 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -224,10 +224,7 @@ pub(crate) fn write_ir_file( let clif_file_name = clif_output_dir.join(name); - let res: std::io::Result<()> = try { - let mut file = std::fs::File::create(clif_file_name)?; - write(&mut file)?; - }; + let res = std::fs::File::create(clif_file_name).and_then(|mut file| write(&mut file)); if let Err(err) = res { tcx.sess.warn(&format!("error writing ir file: {}", err)); } From 7bd3950831bde1f8d4910e9435cf0c423e1a6772 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 18 Mar 2021 12:51:58 +0100 Subject: [PATCH 078/370] Fix rustc test suite --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 1c3318d53de..fbc3feceec7 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -68,6 +68,7 @@ rm -r src/test/run-pass-valgrind/unsized-locals rm src/test/ui/json-bom-plus-crlf-multifile.rs # differing warning rm src/test/ui/json-bom-plus-crlf.rs # same +rm src/test/ui/type-alias-impl-trait/cross_crate_ice*.rs # requires removed aux dep rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition rm src/test/ui/cfg/cfg-panic.rs From fd6e4e41b7608c6fcdd34aedfc2d88b27b1ada05 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Thu, 18 Mar 2021 08:22:04 +0100 Subject: [PATCH 079/370] BTree: no longer search arrays twice to check Ord --- library/alloc/src/collections/btree/map.rs | 6 --- .../alloc/src/collections/btree/map/tests.rs | 2 - library/alloc/src/collections/btree/search.rs | 52 ++++++++++--------- 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 40f3d5510cd..622983996aa 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -1018,9 +1018,6 @@ impl BTreeMap { /// /// Panics if range `start > end`. /// Panics if range `start == end` and both bounds are `Excluded`. - /// May panic if the [`Ord`] implementation of type `T` is ill-defined, - /// either because it does not form a total order or because it does not - /// correspond to the [`Ord`] implementation of type `K`. /// /// # Examples /// @@ -1064,9 +1061,6 @@ impl BTreeMap { /// /// Panics if range `start > end`. /// Panics if range `start == end` and both bounds are `Excluded`. - /// May panic if the [`Ord`] implementation of type `T` is ill-defined, - /// either because it does not form a total order or because it does not - /// correspond to the [`Ord`] implementation of type `K`. /// /// # Examples /// diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index e636e490e1b..3a74b6a6fa8 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -776,7 +776,6 @@ fn test_range_backwards_4() { } #[test] -#[should_panic] fn test_range_finding_ill_order_in_map() { let mut map = BTreeMap::new(); map.insert(Cyclic3::B, ()); @@ -789,7 +788,6 @@ fn test_range_finding_ill_order_in_map() { } #[test] -#[should_panic] fn test_range_finding_ill_order_in_range_ord() { // Has proper order the first time asked, then flips around. struct EvilTwin(i32); diff --git a/library/alloc/src/collections/btree/search.rs b/library/alloc/src/collections/btree/search.rs index 7443db95203..62a048e61c6 100644 --- a/library/alloc/src/collections/btree/search.rs +++ b/library/alloc/src/collections/btree/search.rs @@ -76,9 +76,7 @@ impl NodeRef( @@ -118,14 +116,8 @@ impl NodeRef upper_edge_idx { - // Since we already checked the range bounds, this can only - // happen if `Q: Ord` does not implement a total order or does - // not correspond to the `K: Ord` implementation that is used - // while populating the tree. - panic!("Ord is ill-defined in BTreeMap range") - } + let (upper_edge_idx, upper_child_bound) = + unsafe { self.find_upper_bound_index(upper_bound, lower_edge_idx) }; if lower_edge_idx < upper_edge_idx { return Ok(( self, @@ -135,6 +127,7 @@ impl NodeRef return Err(common_edge), @@ -174,7 +167,7 @@ impl NodeRef, { - let (edge_idx, bound) = self.find_upper_bound_index(bound); + let (edge_idx, bound) = unsafe { self.find_upper_bound_index(bound, 0) }; let edge = unsafe { Handle::new_edge(self, edge_idx) }; (edge, bound) } @@ -193,29 +186,33 @@ impl NodeRef { Q: Ord, K: Borrow, { - match self.find_key_index(key) { + match unsafe { self.find_key_index(key, 0) } { IndexResult::KV(idx) => Found(unsafe { Handle::new_kv(self, idx) }), IndexResult::Edge(idx) => GoDown(unsafe { Handle::new_edge(self, idx) }), } } /// Returns either the KV index in the node at which the key (or an equivalent) - /// exists, or the edge index where the key belongs. + /// exists, or the edge index where the key belongs, starting from a particular index. /// /// The result is meaningful only if the tree is ordered by key, like the tree /// in a `BTreeMap` is. - fn find_key_index(&self, key: &Q) -> IndexResult + /// + /// # Safety + /// `start_index` must be a valid edge index for the node. + unsafe fn find_key_index(&self, key: &Q, start_index: usize) -> IndexResult where Q: Ord, K: Borrow, { let node = self.reborrow(); let keys = node.keys(); - for (i, k) in keys.iter().enumerate() { + debug_assert!(start_index <= keys.len()); + for (offset, k) in unsafe { keys.get_unchecked(start_index..) }.iter().enumerate() { match key.cmp(k.borrow()) { Ordering::Greater => {} - Ordering::Equal => return IndexResult::KV(i), - Ordering::Less => return IndexResult::Edge(i), + Ordering::Equal => return IndexResult::KV(start_index + offset), + Ordering::Less => return IndexResult::Edge(start_index + offset), } } IndexResult::Edge(keys.len()) @@ -235,11 +232,11 @@ impl NodeRef { K: Borrow, { match bound { - Included(key) => match self.find_key_index(key) { + Included(key) => match unsafe { self.find_key_index(key, 0) } { IndexResult::KV(idx) => (idx, AllExcluded), IndexResult::Edge(idx) => (idx, bound), }, - Excluded(key) => match self.find_key_index(key) { + Excluded(key) => match unsafe { self.find_key_index(key, 0) } { IndexResult::KV(idx) => (idx + 1, AllIncluded), IndexResult::Edge(idx) => (idx, bound), }, @@ -248,26 +245,31 @@ impl NodeRef { } } - /// Clone of `find_lower_bound_index` for the upper bound. - fn find_upper_bound_index<'r, Q>( + /// Mirror image of `find_lower_bound_index` for the upper bound, + /// with an additional parameter to skip part of the key array. + /// + /// # Safety + /// `start_index` must be a valid edge index for the node. + unsafe fn find_upper_bound_index<'r, Q>( &self, bound: SearchBound<&'r Q>, + start_index: usize, ) -> (usize, SearchBound<&'r Q>) where Q: ?Sized + Ord, K: Borrow, { match bound { - Included(key) => match self.find_key_index(key) { + Included(key) => match unsafe { self.find_key_index(key, start_index) } { IndexResult::KV(idx) => (idx + 1, AllExcluded), IndexResult::Edge(idx) => (idx, bound), }, - Excluded(key) => match self.find_key_index(key) { + Excluded(key) => match unsafe { self.find_key_index(key, start_index) } { IndexResult::KV(idx) => (idx, AllIncluded), IndexResult::Edge(idx) => (idx, bound), }, AllIncluded => (self.len(), AllIncluded), - AllExcluded => (0, AllExcluded), + AllExcluded => (start_index, AllExcluded), } } } From e4a1092b9f21a7dd966d7198846132f3dd17513a Mon Sep 17 00:00:00 2001 From: SparrowLii Date: Fri, 19 Mar 2021 02:16:21 +0800 Subject: [PATCH 080/370] Add simd_neg platform intrinsic --- src/intrinsics/simd.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index d17136080fe..86df71a0dfc 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -276,5 +276,6 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( // simd_bitmask // simd_select // simd_rem + // simd_neg } } From 500bcfcdb3122d68cabdfc2eb9034d88b708e0bc Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 13 Mar 2021 16:31:38 +0100 Subject: [PATCH 081/370] update `const_eval_resolve` --- src/constant.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index 9d93370b7d0..f4cbfb6967f 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -45,9 +45,9 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { }; match const_.val { ConstKind::Value(_) => {} - ConstKind::Unevaluated(def, ref substs, promoted) => { + ConstKind::Unevaluated(unevaluated) => { if let Err(err) = - fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) + fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) { all_constants_ok = false; match err { @@ -122,14 +122,14 @@ pub(crate) fn codegen_constant<'tcx>( }; let const_val = match const_.val { ConstKind::Value(const_val) => const_val, - ConstKind::Unevaluated(def, ref substs, promoted) if fx.tcx.is_static(def.did) => { + ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) if fx.tcx.is_static(def.did) => { assert!(substs.is_empty()); assert!(promoted.is_none()); return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty)).to_cvalue(fx); } - ConstKind::Unevaluated(def, ref substs, promoted) => { - match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) { + ConstKind::Unevaluated(unevaluated) => { + match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) { Ok(const_val) => const_val, Err(_) => { span_bug!(constant.span, "erroneous constant not captured by required_consts"); From 26a62701e42d10c03ce5f2f911e7d5edeefa2f0f Mon Sep 17 00:00:00 2001 From: Yechan Bae Date: Sat, 20 Mar 2021 13:42:54 -0400 Subject: [PATCH 082/370] Update the comment --- library/alloc/src/str.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index a7584c6b651..4d1e876457b 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -163,7 +163,7 @@ where }) .expect("attempt to join into collection with len > usize::MAX"); - // crucial for safety + // prepare an uninitialized buffer let mut result = Vec::with_capacity(reserved_len); debug_assert!(result.capacity() >= reserved_len); @@ -178,9 +178,9 @@ where // massive improvements possible (~ x2) let remain = specialize_for_lengths!(sep, target, iter; 0, 1, 2, 3, 4); - // issue #80335: A weird borrow implementation can return different - // slices for the length calculation and the actual copy, so - // `remain.len()` might be non-zero. + // A weird borrow implementation may return different + // slices for the length calculation and the actual copy. + // Make sure we don't expose uninitialized bytes to the caller. let result_len = reserved_len - remain.len(); result.set_len(result_len); } From addf680cbd9167eccbf8518039e53a10b3b68dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 20 Mar 2021 00:00:00 +0000 Subject: [PATCH 083/370] Use a single codegen unit to reduce non-determinism in srcloc.rs test When building with multiple codegen units the test case can fail with only a subset of all errors. Use a single codegen unit as a workaround. --- src/test/ui/asm/srcloc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/asm/srcloc.rs b/src/test/ui/asm/srcloc.rs index 1477e3dd566..7262064e7bb 100644 --- a/src/test/ui/asm/srcloc.rs +++ b/src/test/ui/asm/srcloc.rs @@ -1,7 +1,7 @@ // no-system-llvm // only-x86_64 // build-fail - +// compile-flags: -Ccodegen-units=1 #![feature(asm)] // Checks that inline asm errors are mapped to the correct line in the source code. From 3d64f8d475d701a36971cb416e49b80449988f6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Mon, 8 Mar 2021 00:00:00 +0000 Subject: [PATCH 084/370] Join test thread to make assertion effective in sym.rs test case --- src/test/ui/asm/sym.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/asm/sym.rs b/src/test/ui/asm/sym.rs index 9931697e412..d5c03a7d567 100644 --- a/src/test/ui/asm/sym.rs +++ b/src/test/ui/asm/sym.rs @@ -76,5 +76,5 @@ fn main() { std::thread::spawn(|| { assert_eq!(static_addr!(S1), &S1 as *const u32); assert_eq!(static_tls_addr!(S2), &S2 as *const u32); - }); + }).join().unwrap(); } From 56fe51cb36eadcd360a7cf119d930c841dc6ea38 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 21 Mar 2021 10:05:22 +0100 Subject: [PATCH 085/370] Update Cranelift --- Cargo.lock | 40 ++++++++++++++++++++-------------------- src/allocator.rs | 5 +++-- src/base.rs | 3 ++- src/driver/jit.rs | 4 +++- src/main_shim.rs | 9 +++------ 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9184074e92f..3cb67032aaa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,16 +39,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "byteorder", "cranelift-bforest", @@ -65,8 +65,8 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -74,18 +74,18 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" [[package]] name = "cranelift-entity" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" [[package]] name = "cranelift-frontend" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "cranelift-codegen", "log", @@ -95,8 +95,8 @@ dependencies = [ [[package]] name = "cranelift-jit" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "anyhow", "cranelift-codegen", @@ -113,8 +113,8 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "anyhow", "cranelift-codegen", @@ -125,8 +125,8 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "cranelift-codegen", "target-lexicon", @@ -134,8 +134,8 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "anyhow", "cranelift-codegen", diff --git a/src/allocator.rs b/src/allocator.rs index efb64233ef2..f60645a9f97 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -3,6 +3,7 @@ use crate::prelude::*; +use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink}; use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS}; use rustc_span::symbol::sym; @@ -92,7 +93,7 @@ fn codegen_inner( bcx.finalize(); } module - .define_function(func_id, &mut ctx, &mut cranelift_codegen::binemit::NullTrapSink {}) + .define_function(func_id, &mut ctx, &mut NullTrapSink {}, &mut NullStackMapSink {}) .unwrap(); unwind_context.add_function(func_id, &ctx, module.isa()); } @@ -132,7 +133,7 @@ fn codegen_inner( bcx.finalize(); } module - .define_function(func_id, &mut ctx, &mut cranelift_codegen::binemit::NullTrapSink {}) + .define_function(func_id, &mut ctx, &mut NullTrapSink {}, &mut NullStackMapSink {}) .unwrap(); unwind_context.add_function(func_id, &ctx, module.isa()); } diff --git a/src/base.rs b/src/base.rs index 33a28ac733e..8c14e04eeeb 100644 --- a/src/base.rs +++ b/src/base.rs @@ -1,5 +1,6 @@ //! Codegen of a single function +use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink}; use rustc_index::vec::IndexVec; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::layout::FnAbiExt; @@ -131,7 +132,7 @@ pub(crate) fn codegen_fn<'tcx>( let module = &mut cx.module; tcx.sess.time("define function", || { module - .define_function(func_id, context, &mut cranelift_codegen::binemit::NullTrapSink {}) + .define_function(func_id, context, &mut NullTrapSink {}, &mut NullStackMapSink {}) .unwrap() }); diff --git a/src/driver/jit.rs b/src/driver/jit.rs index dec95d65714..1b08b416913 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -5,6 +5,7 @@ use std::cell::RefCell; use std::ffi::CString; use std::os::raw::{c_char, c_int}; +use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink}; use rustc_codegen_ssa::CrateInfo; use rustc_middle::mir::mono::MonoItem; use rustc_session::config::EntryFnType; @@ -297,7 +298,8 @@ fn codegen_shim<'tcx>(cx: &mut CodegenCx<'_, 'tcx>, inst: Instance<'tcx>) { .define_function( func_id, &mut Context::for_function(trampoline), - &mut cranelift_codegen::binemit::NullTrapSink {}, + &mut NullTrapSink {}, + &mut NullStackMapSink {}, ) .unwrap(); } diff --git a/src/main_shim.rs b/src/main_shim.rs index 62e551b186f..a6266f50776 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -1,3 +1,4 @@ +use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink}; use rustc_hir::LangItem; use rustc_session::config::EntryFnType; @@ -100,12 +101,8 @@ pub(crate) fn maybe_create_entry_wrapper( bcx.seal_all_blocks(); bcx.finalize(); } - m.define_function( - cmain_func_id, - &mut ctx, - &mut cranelift_codegen::binemit::NullTrapSink {}, - ) - .unwrap(); + m.define_function(cmain_func_id, &mut ctx, &mut NullTrapSink {}, &mut NullStackMapSink {}) + .unwrap(); unwind_context.add_function(cmain_func_id, &ctx, m.isa()); } } From 73626efb26f61c68c8c9d4bec0a35928130a2010 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 21 Mar 2021 10:05:48 +0100 Subject: [PATCH 086/370] Rustfmt --- src/abi/mod.rs | 5 +---- src/base.rs | 13 +++++-------- src/lib.rs | 7 +------ 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index b37a5f308c8..0e7829eaa26 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -470,10 +470,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( // FIXME find a cleaner way to support varargs if fn_sig.c_variadic { if !matches!(fn_sig.abi, Abi::C { .. }) { - fx.tcx.sess.span_fatal( - span, - &format!("Variadic call for non-C abi {:?}", fn_sig.abi), - ); + fx.tcx.sess.span_fatal(span, &format!("Variadic call for non-C abi {:?}", fn_sig.abi)); } let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap(); let abi_params = call_args diff --git a/src/base.rs b/src/base.rs index 8c14e04eeeb..7cd7bb1de41 100644 --- a/src/base.rs +++ b/src/base.rs @@ -839,18 +839,15 @@ fn codegen_stmt<'tcx>( StatementKind::CopyNonOverlapping(inner) => { let dst = codegen_operand(fx, &inner.dst); let pointee = dst - .layout() - .pointee_info_at(fx, rustc_target::abi::Size::ZERO) - .expect("Expected pointer"); + .layout() + .pointee_info_at(fx, rustc_target::abi::Size::ZERO) + .expect("Expected pointer"); let dst = dst.load_scalar(fx); let src = codegen_operand(fx, &inner.src).load_scalar(fx); let count = codegen_operand(fx, &inner.count).load_scalar(fx); let elem_size: u64 = pointee.size.bytes(); - let bytes = if elem_size != 1 { - fx.bcx.ins().imul_imm(count, elem_size as i64) - } else { - count - }; + let bytes = + if elem_size != 1 { fx.bcx.ins().imul_imm(count, elem_size as i64) } else { count }; fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, bytes); } } diff --git a/src/lib.rs b/src/lib.rs index 63fb1c40844..2d18f585dc8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,4 @@ -#![feature( - rustc_private, - decl_macro, - never_type, - hash_drain_filter -)] +#![feature(rustc_private, decl_macro, never_type, hash_drain_filter)] #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] #![warn(unreachable_pub)] From ae8ef70a499907c929f5d7ad6539cd1187da336b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Sun, 21 Mar 2021 14:27:22 +0300 Subject: [PATCH 087/370] Simplify and fix byte skipping in format! string parser Fixes '\\' handling in format strings. Fixes #83340 --- compiler/rustc_parse_format/src/lib.rs | 23 +++++++++-------------- src/test/ui/macros/issue-83340.rs | 8 ++++++++ src/test/ui/macros/issue-83340.stderr | 8 ++++++++ 3 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 src/test/ui/macros/issue-83340.rs create mode 100644 src/test/ui/macros/issue-83340.stderr diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 92d974690b5..e20fc28e794 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -735,25 +735,24 @@ fn find_skips_from_snippet( }; fn find_skips(snippet: &str, is_raw: bool) -> Vec { - let mut eat_ws = false; let mut s = snippet.char_indices().peekable(); let mut skips = vec![]; while let Some((pos, c)) = s.next() { match (c, s.peek()) { // skip whitespace and empty lines ending in '\\' ('\\', Some((next_pos, '\n'))) if !is_raw => { - eat_ws = true; skips.push(pos); skips.push(*next_pos); let _ = s.next(); - } - ('\\', Some((next_pos, '\n' | 'n' | 't'))) if eat_ws => { - skips.push(pos); - skips.push(*next_pos); - let _ = s.next(); - } - (' ' | '\n' | '\t', _) if eat_ws => { - skips.push(pos); + + while let Some((pos, c)) = s.peek() { + if matches!(c, ' ' | '\n' | '\t') { + skips.push(*pos); + let _ = s.next(); + } else { + break; + } + } } ('\\', Some((next_pos, 'n' | 't' | 'r' | '0' | '\\' | '\'' | '\"'))) => { skips.push(*next_pos); @@ -804,10 +803,6 @@ fn find_skips_from_snippet( } } } - _ if eat_ws => { - // `take_while(|c| c.is_whitespace())` - eat_ws = false; - } _ => {} } } diff --git a/src/test/ui/macros/issue-83340.rs b/src/test/ui/macros/issue-83340.rs new file mode 100644 index 00000000000..d26200295cd --- /dev/null +++ b/src/test/ui/macros/issue-83340.rs @@ -0,0 +1,8 @@ +// check-fail + +fn main() { + println!( + "\ +\n {} │", //~ ERROR: 1 positional argument in format string, but no arguments were given + ); +} diff --git a/src/test/ui/macros/issue-83340.stderr b/src/test/ui/macros/issue-83340.stderr new file mode 100644 index 00000000000..1935de02b57 --- /dev/null +++ b/src/test/ui/macros/issue-83340.stderr @@ -0,0 +1,8 @@ +error: 1 positional argument in format string, but no arguments were given + --> $DIR/issue-83340.rs:6:4 + | +LL | \n {} │", + | ^^ + +error: aborting due to previous error + From f5e37100d9c115ab327bafd42d0c4dad539d318f Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 21 Mar 2021 17:47:57 -0400 Subject: [PATCH 088/370] Mark RawVec::reserve as inline and outline the resizing logic --- library/alloc/src/raw_vec.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 56f4ebe57f8..ff7bff7584a 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -315,8 +315,20 @@ impl RawVec { /// # vector.push_all(&[1, 3, 5, 7, 9]); /// # } /// ``` + #[inline] pub fn reserve(&mut self, len: usize, additional: usize) { - handle_reserve(self.try_reserve(len, additional)); + // Callers expect this function to be very cheap when there is already sufficient capacity. + // Therefore, we move all the resizing and error-handling logic from grow_amortized and + // handle_reserve behind a call, while making sure that the this function is likely to be + // inlined as just a comparison and a call if the comparison fails. + #[inline(never)] + fn do_reserve_and_handle(slf: &mut RawVec, len: usize, additional: usize) { + handle_reserve(slf.grow_amortized(len, additional)); + } + + if self.needs_to_grow(len, additional) { + do_reserve_and_handle(self, len, additional); + } } /// The same as `reserve`, but returns on errors instead of panicking or aborting. From 73d773482afcceb8475dd773c4e2e70ed4835242 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 21 Mar 2021 19:17:07 -0400 Subject: [PATCH 089/370] fmt, change to cold --- library/alloc/src/raw_vec.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index ff7bff7584a..dc02c9c883e 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -321,8 +321,12 @@ impl RawVec { // Therefore, we move all the resizing and error-handling logic from grow_amortized and // handle_reserve behind a call, while making sure that the this function is likely to be // inlined as just a comparison and a call if the comparison fails. - #[inline(never)] - fn do_reserve_and_handle(slf: &mut RawVec, len: usize, additional: usize) { + #[cold] + fn do_reserve_and_handle( + slf: &mut RawVec, + len: usize, + additional: usize, + ) { handle_reserve(slf.grow_amortized(len, additional)); } From 18748c9121f5910075ca4317a78ef11adb639263 Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Mon, 22 Mar 2021 15:14:24 -0400 Subject: [PATCH 090/370] Make # format easier to discover --- library/alloc/src/fmt.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index f9424b1d747..8453f694e1e 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -19,6 +19,10 @@ //! format!("{value}", value=4); // => "4" //! format!("{} {}", 1, 2); // => "1 2" //! format!("{:04}", 42); // => "0042" with leading zeros +//! format!("{:#?}", (100, 200)); // => "( +//! // 100, +//! // 200, +//! // )" //! ``` //! //! From these, you can see that the first argument is a format string. It is @@ -163,7 +167,7 @@ //! * `-` - Currently not used //! * `#` - This flag indicates that the "alternate" form of printing should //! be used. The alternate forms are: -//! * `#?` - pretty-print the [`Debug`] formatting +//! * `#?` - pretty-print the [`Debug`] formatting (newline and indent) //! * `#x` - precedes the argument with a `0x` //! * `#X` - precedes the argument with a `0x` //! * `#b` - precedes the argument with a `0b` From 93737dc634f42d07441db2acf26a88ae2e888d9f Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Mon, 22 Mar 2021 17:09:11 -0400 Subject: [PATCH 091/370] Update library/alloc/src/fmt.rs --- library/alloc/src/fmt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index 8453f694e1e..e765fa9d14c 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -167,7 +167,7 @@ //! * `-` - Currently not used //! * `#` - This flag indicates that the "alternate" form of printing should //! be used. The alternate forms are: -//! * `#?` - pretty-print the [`Debug`] formatting (newline and indent) +//! * `#?` - pretty-print the [`Debug`] formatting (adds linebreaks and indentation) //! * `#x` - precedes the argument with a `0x` //! * `#X` - precedes the argument with a `0x` //! * `#b` - precedes the argument with a `0b` From fc9b234928c1d64cc45686d9e61bb5993d8747fa Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 31 Oct 2020 11:50:34 -0700 Subject: [PATCH 092/370] Add IEEE754 tests --- library/core/tests/num/ieee754.rs | 158 ++++++++++++++++++++++++++++++ library/core/tests/num/mod.rs | 1 + 2 files changed, 159 insertions(+) create mode 100644 library/core/tests/num/ieee754.rs diff --git a/library/core/tests/num/ieee754.rs b/library/core/tests/num/ieee754.rs new file mode 100644 index 00000000000..f6e5dfc98c7 --- /dev/null +++ b/library/core/tests/num/ieee754.rs @@ -0,0 +1,158 @@ +//! IEEE 754 floating point compliance tests +//! +//! To understand IEEE 754's requirements on a programming language, one must understand that the +//! requirements of IEEE 754 rest on the total programming environment, and not entirely on any +//! one component. That means the hardware, language, and even libraries are considered part of +//! conforming floating point support in a programming environment. +//! +//! A programming language's duty, accordingly, is: +//! 1. offer access to the hardware where the hardware offers support +//! 2. provide operations that fulfill the remaining requirements of the standard +//! 3. provide the ability to write additional software that can fulfill those requirements +//! +//! This may be fulfilled in any combination that the language sees fit. However, to claim that +//! a language supports IEEE 754 is to suggest that it has fulfilled requirements 1 and 2, without +//! deferring minimum requirements to libraries. This is because support for IEEE 754 is defined +//! as complete support for at least one specified floating point type as an "arithmetic" and +//! "interchange" format, plus specified type conversions to "external character sequences" and +//! integer types. +//! +//! For our purposes, +//! "interchange format" => f32, f64 +//! "arithmetic format" => f32, f64, and any "soft floats" +//! "external character sequence" => str from any float +//! "integer format" => {i,u}{8,16,32,64,128} +//! +//! None of these tests are against Rust's own implementation. They are only tests against the +//! standard. That is why they accept wildly diverse inputs or may seem to duplicate other tests. +//! Please consider this carefully when adding, removing, or reorganizing these tests. They are +//! here so that it is clear what tests are required by the standard and what can be changed. +use ::core::str::FromStr; + +// IEEE 754 for many tests is applied to specific bit patterns. +// These generally are not applicable to NaN, however. +macro_rules! assert_biteq { + ($lhs:expr, $rhs:expr) => { + assert_eq!($lhs.to_bits(), $rhs.to_bits()) + }; +} + +// ToString uses the default fmt::Display impl without special concerns, and bypasses other parts +// of the formatting infrastructure, which makes it ideal for testing here. +#[allow(unused_macros)] +macro_rules! roundtrip { + ($f:expr => $t:ty) => { + ($f).to_string().parse::<$t>().unwrap() + }; +} + +macro_rules! assert_floats_roundtrip { + ($f:ident) => { + assert_biteq!(f32::$f, roundtrip!(f32::$f => f32)); + assert_biteq!(f64::$f, roundtrip!(f64::$f => f64)); + }; + ($f:expr) => { + assert_biteq!($f as f32, roundtrip!($f => f32)); + assert_biteq!($f as f64, roundtrip!($f => f64)); + } +} + +macro_rules! assert_floats_bitne { + ($lhs:ident, $rhs:ident) => { + assert_ne!(f32::$lhs.to_bits(), f32::$rhs.to_bits()); + assert_ne!(f64::$lhs.to_bits(), f64::$rhs.to_bits()); + }; + ($lhs:expr, $rhs:expr) => { + assert_ne!(f32::to_bits($lhs), f32::to_bits($rhs)); + assert_ne!(f64::to_bits($lhs), f64::to_bits($rhs)); + }; +} + +// We must preserve signs on all numbers. That includes zero. +// -0 and 0 are == normally, so test bit equality. +#[test] +fn preserve_signed_zero() { + assert_floats_roundtrip!(-0.0); + assert_floats_roundtrip!(0.0); + assert_floats_bitne!(0.0, -0.0); +} + +#[test] +fn preserve_signed_infinity() { + assert_floats_roundtrip!(INFINITY); + assert_floats_roundtrip!(NEG_INFINITY); + assert_floats_bitne!(INFINITY, NEG_INFINITY); +} + +#[test] +fn infinity_to_str() { + assert!(match f32::INFINITY.to_string().to_lowercase().as_str() { + "+infinity" | "infinity" => true, + "+inf" | "inf" => true, + _ => false, + }); + assert!( + match f64::INFINITY.to_string().to_lowercase().as_str() { + "+infinity" | "infinity" => true, + "+inf" | "inf" => true, + _ => false, + }, + "Infinity must write to a string as some casing of inf or infinity, with an optional +." + ); +} + +#[test] +fn neg_infinity_to_str() { + assert!(match f32::NEG_INFINITY.to_string().to_lowercase().as_str() { + "-infinity" | "-inf" => true, + _ => false, + }); + assert!( + match f64::NEG_INFINITY.to_string().to_lowercase().as_str() { + "-infinity" | "-inf" => true, + _ => false, + }, + "Negative Infinity must write to a string as some casing of -inf or -infinity" + ) +} + +#[test] +fn nan_to_str() { + assert!( + match f32::NAN.to_string().to_lowercase().as_str() { + "nan" | "+nan" | "-nan" => true, + _ => false, + }, + "NaNs must write to a string as some casing of nan." + ) +} + +// "+"?("inf"|"infinity") in any case => Infinity +#[test] +fn infinity_from_str() { + assert_biteq!(f32::INFINITY, f32::from_str("infinity").unwrap()); + assert_biteq!(f32::INFINITY, f32::from_str("inf").unwrap()); + assert_biteq!(f32::INFINITY, f32::from_str("+infinity").unwrap()); + assert_biteq!(f32::INFINITY, f32::from_str("+inf").unwrap()); + // yes! this means you are weLcOmE tO mY iNfInItElY tWiStEd MiNd + assert_biteq!(f32::INFINITY, f32::from_str("+iNfInItY").unwrap()); +} + +// "-inf"|"-infinity" in any case => Negative Infinity +#[test] +fn neg_infinity_from_str() { + assert_biteq!(f32::NEG_INFINITY, f32::from_str("-infinity").unwrap()); + assert_biteq!(f32::NEG_INFINITY, f32::from_str("-inf").unwrap()); + assert_biteq!(f32::NEG_INFINITY, f32::from_str("-INF").unwrap()); + assert_biteq!(f32::NEG_INFINITY, f32::from_str("-INFinity").unwrap()); +} + +// ("+"|"-"")?"s"?"nan" in any case => qNaN +#[test] +fn qnan_from_str() { + assert!("nan".parse::().unwrap().is_nan()); + assert!("-nan".parse::().unwrap().is_nan()); + assert!("+nan".parse::().unwrap().is_nan()); + assert!("+NAN".parse::().unwrap().is_nan()); + assert!("-NaN".parse::().unwrap().is_nan()); +} diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs index e66a73ac128..bbb67667dfc 100644 --- a/library/core/tests/num/mod.rs +++ b/library/core/tests/num/mod.rs @@ -32,6 +32,7 @@ mod flt2dec; mod ops; mod wrapping; +mod ieee754; mod nan; /// Adds the attribute to all items in the block. From 588cc644ad6d6d6419dcd48651ae451557cdc100 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 31 Oct 2020 12:30:22 -0700 Subject: [PATCH 093/370] Add ability to read NaN/Infinity --- library/core/src/num/dec2flt/mod.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index 20ac165c6c7..f008a64ffe6 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -239,13 +239,15 @@ fn dec2flt(s: &str) -> Result { ParseResult::Valid(decimal) => convert(decimal)?, ParseResult::ShortcutToInf => T::INFINITY, ParseResult::ShortcutToZero => T::ZERO, - ParseResult::Invalid => match s { - "inf" => T::INFINITY, - "NaN" => T::NAN, - _ => { + ParseResult::Invalid => { + if s.eq_ignore_ascii_case("nan") { + T::NAN + } else if s.eq_ignore_ascii_case("inf") || s.eq_ignore_ascii_case("infinity") { + T::INFINITY + } else { return Err(pfe_invalid()); } - }, + } }; match sign { From 74db93ed2d0677bbca8ba85617f05eae745363d8 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 31 Oct 2020 13:16:14 -0700 Subject: [PATCH 094/370] Preserve signed zero on roundtrip This commit removes the previous mechanism of differentiating between "Debug" and "Display" formattings for the sign of -0 so as to comply with the IEEE 754 standard's requirements on external character sequences preserving various attributes of a floating point representation. In addition, numerous tests are fixed. --- library/alloc/tests/fmt.rs | 3 +- library/core/src/fmt/float.rs | 19 +- library/core/src/num/flt2dec/mod.rs | 32 +-- library/core/tests/num/flt2dec/mod.rs | 246 +++++++----------- ...float_to_exponential_common.ConstProp.diff | 2 +- 5 files changed, 102 insertions(+), 200 deletions(-) diff --git a/library/alloc/tests/fmt.rs b/library/alloc/tests/fmt.rs index 757fddd2418..ade3bc2d334 100644 --- a/library/alloc/tests/fmt.rs +++ b/library/alloc/tests/fmt.rs @@ -154,8 +154,7 @@ fn test_format_macro_interface() { t!(format!("{:+10.3e}", -1.2345e6f64), " -1.234e6"); // Float edge cases - t!(format!("{}", -0.0), "0"); - t!(format!("{:?}", -0.0), "-0.0"); + t!(format!("{}", -0.0), "-0"); t!(format!("{:?}", 0.0), "0.0"); // sign aware zero padding diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs index 5908da477e1..ece3cde0015 100644 --- a/library/core/src/fmt/float.rs +++ b/library/core/src/fmt/float.rs @@ -54,21 +54,14 @@ where } // Common code of floating point Debug and Display. -fn float_to_decimal_common( - fmt: &mut Formatter<'_>, - num: &T, - negative_zero: bool, - min_precision: usize, -) -> Result +fn float_to_decimal_common(fmt: &mut Formatter<'_>, num: &T, min_precision: usize) -> Result where T: flt2dec::DecodableFloat, { let force_sign = fmt.sign_plus(); - let sign = match (force_sign, negative_zero) { - (false, false) => flt2dec::Sign::Minus, - (false, true) => flt2dec::Sign::MinusRaw, - (true, false) => flt2dec::Sign::MinusPlus, - (true, true) => flt2dec::Sign::MinusPlusRaw, + let sign = match force_sign { + false => flt2dec::Sign::Minus, + true => flt2dec::Sign::MinusPlus, }; if let Some(precision) = fmt.precision { @@ -156,14 +149,14 @@ macro_rules! floating { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for $ty { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { - float_to_decimal_common(fmt, self, true, 1) + float_to_decimal_common(fmt, self, 1) } } #[stable(feature = "rust1", since = "1.0.0")] impl Display for $ty { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { - float_to_decimal_common(fmt, self, false, 0) + float_to_decimal_common(fmt, self, 0) } } diff --git a/library/core/src/num/flt2dec/mod.rs b/library/core/src/num/flt2dec/mod.rs index e8f9d6574e2..93bdf5040e0 100644 --- a/library/core/src/num/flt2dec/mod.rs +++ b/library/core/src/num/flt2dec/mod.rs @@ -399,14 +399,10 @@ fn digits_to_exp_str<'a>( /// Sign formatting options. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum Sign { - /// Prints `-` only for the negative non-zero values. - Minus, // -inf -1 0 0 1 inf nan - /// Prints `-` only for any negative values (including the negative zero). - MinusRaw, // -inf -1 -0 0 1 inf nan - /// Prints `-` for the negative non-zero values, or `+` otherwise. - MinusPlus, // -inf -1 +0 +0 +1 +inf nan - /// Prints `-` for any negative values (including the negative zero), or `+` otherwise. - MinusPlusRaw, // -inf -1 -0 +0 +1 +inf nan + /// Prints `-` for any negative value. + Minus, // -inf -1 -0 0 1 inf nan + /// Prints `-` for any negative value, or `+` otherwise. + MinusPlus, // -inf -1 -0 +0 +1 +inf nan } /// Returns the static byte string corresponding to the sign to be formatted. @@ -414,30 +410,14 @@ pub enum Sign { fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static str { match (*decoded, sign) { (FullDecoded::Nan, _) => "", - (FullDecoded::Zero, Sign::Minus) => "", - (FullDecoded::Zero, Sign::MinusRaw) => { + (_, Sign::Minus) => { if negative { "-" } else { "" } } - (FullDecoded::Zero, Sign::MinusPlus) => "+", - (FullDecoded::Zero, Sign::MinusPlusRaw) => { - if negative { - "-" - } else { - "+" - } - } - (_, Sign::Minus | Sign::MinusRaw) => { - if negative { - "-" - } else { - "" - } - } - (_, Sign::MinusPlus | Sign::MinusPlusRaw) => { + (_, Sign::MinusPlus) => { if negative { "-" } else { diff --git a/library/core/tests/num/flt2dec/mod.rs b/library/core/tests/num/flt2dec/mod.rs index 8e95249a79d..960a7ca5ff5 100644 --- a/library/core/tests/num/flt2dec/mod.rs +++ b/library/core/tests/num/flt2dec/mod.rs @@ -514,51 +514,38 @@ where let f = &mut f_; assert_eq!(to_string(f, 0.0, Minus, 0), "0"); - assert_eq!(to_string(f, 0.0, MinusRaw, 0), "0"); + assert_eq!(to_string(f, 0.0, Minus, 0), "0"); assert_eq!(to_string(f, 0.0, MinusPlus, 0), "+0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, 0), "+0"); - assert_eq!(to_string(f, -0.0, Minus, 0), "0"); - assert_eq!(to_string(f, -0.0, MinusRaw, 0), "-0"); - assert_eq!(to_string(f, -0.0, MinusPlus, 0), "+0"); - assert_eq!(to_string(f, -0.0, MinusPlusRaw, 0), "-0"); + assert_eq!(to_string(f, -0.0, Minus, 0), "-0"); + assert_eq!(to_string(f, -0.0, MinusPlus, 0), "-0"); + assert_eq!(to_string(f, 0.0, Minus, 1), "0.0"); assert_eq!(to_string(f, 0.0, Minus, 1), "0.0"); - assert_eq!(to_string(f, 0.0, MinusRaw, 1), "0.0"); assert_eq!(to_string(f, 0.0, MinusPlus, 1), "+0.0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, 1), "+0.0"); - assert_eq!(to_string(f, -0.0, Minus, 8), "0.00000000"); - assert_eq!(to_string(f, -0.0, MinusRaw, 8), "-0.00000000"); - assert_eq!(to_string(f, -0.0, MinusPlus, 8), "+0.00000000"); - assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8), "-0.00000000"); + assert_eq!(to_string(f, -0.0, Minus, 8), "-0.00000000"); + assert_eq!(to_string(f, -0.0, MinusPlus, 8), "-0.00000000"); assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0), "inf"); - assert_eq!(to_string(f, 1.0 / 0.0, MinusRaw, 0), "inf"); + assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0), "inf"); assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 0), "+inf"); - assert_eq!(to_string(f, 1.0 / 0.0, MinusPlusRaw, 0), "+inf"); assert_eq!(to_string(f, 0.0 / 0.0, Minus, 0), "NaN"); - assert_eq!(to_string(f, 0.0 / 0.0, MinusRaw, 1), "NaN"); - assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 8), "NaN"); - assert_eq!(to_string(f, 0.0 / 0.0, MinusPlusRaw, 64), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, Minus, 1), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 64), "NaN"); assert_eq!(to_string(f, -1.0 / 0.0, Minus, 0), "-inf"); - assert_eq!(to_string(f, -1.0 / 0.0, MinusRaw, 1), "-inf"); - assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 8), "-inf"); - assert_eq!(to_string(f, -1.0 / 0.0, MinusPlusRaw, 64), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, Minus, 1), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 64), "-inf"); assert_eq!(to_string(f, 3.14, Minus, 0), "3.14"); - assert_eq!(to_string(f, 3.14, MinusRaw, 0), "3.14"); + assert_eq!(to_string(f, 3.14, Minus, 0), "3.14"); assert_eq!(to_string(f, 3.14, MinusPlus, 0), "+3.14"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, 0), "+3.14"); assert_eq!(to_string(f, -3.14, Minus, 0), "-3.14"); - assert_eq!(to_string(f, -3.14, MinusRaw, 0), "-3.14"); + assert_eq!(to_string(f, -3.14, Minus, 0), "-3.14"); assert_eq!(to_string(f, -3.14, MinusPlus, 0), "-3.14"); - assert_eq!(to_string(f, -3.14, MinusPlusRaw, 0), "-3.14"); assert_eq!(to_string(f, 3.14, Minus, 1), "3.14"); - assert_eq!(to_string(f, 3.14, MinusRaw, 2), "3.14"); - assert_eq!(to_string(f, 3.14, MinusPlus, 3), "+3.140"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, 4), "+3.1400"); + assert_eq!(to_string(f, 3.14, Minus, 2), "3.14"); + assert_eq!(to_string(f, 3.14, MinusPlus, 4), "+3.1400"); + assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000"); assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000"); - assert_eq!(to_string(f, -3.14, MinusRaw, 8), "-3.14000000"); assert_eq!(to_string(f, -3.14, MinusPlus, 8), "-3.14000000"); - assert_eq!(to_string(f, -3.14, MinusPlusRaw, 8), "-3.14000000"); assert_eq!(to_string(f, 7.5e-11, Minus, 0), "0.000000000075"); assert_eq!(to_string(f, 7.5e-11, Minus, 3), "0.000000000075"); @@ -615,68 +602,48 @@ where let f = &mut f_; assert_eq!(to_string(f, 0.0, Minus, (-4, 16), false), "0"); - assert_eq!(to_string(f, 0.0, MinusRaw, (-4, 16), false), "0"); + assert_eq!(to_string(f, 0.0, Minus, (-4, 16), false), "0"); assert_eq!(to_string(f, 0.0, MinusPlus, (-4, 16), false), "+0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, (-4, 16), false), "+0"); - assert_eq!(to_string(f, -0.0, Minus, (-4, 16), false), "0"); - assert_eq!(to_string(f, -0.0, MinusRaw, (-4, 16), false), "-0"); - assert_eq!(to_string(f, -0.0, MinusPlus, (-4, 16), false), "+0"); - assert_eq!(to_string(f, -0.0, MinusPlusRaw, (-4, 16), false), "-0"); + assert_eq!(to_string(f, -0.0, Minus, (-4, 16), false), "-0"); + assert_eq!(to_string(f, -0.0, MinusPlus, (-4, 16), false), "-0"); assert_eq!(to_string(f, 0.0, Minus, (0, 0), true), "0E0"); - assert_eq!(to_string(f, 0.0, MinusRaw, (0, 0), false), "0e0"); - assert_eq!(to_string(f, 0.0, MinusPlus, (-9, -5), true), "+0E0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, (5, 9), false), "+0e0"); - assert_eq!(to_string(f, -0.0, Minus, (0, 0), true), "0E0"); - assert_eq!(to_string(f, -0.0, MinusRaw, (0, 0), false), "-0e0"); - assert_eq!(to_string(f, -0.0, MinusPlus, (-9, -5), true), "+0E0"); - assert_eq!(to_string(f, -0.0, MinusPlusRaw, (5, 9), false), "-0e0"); + assert_eq!(to_string(f, 0.0, Minus, (0, 0), false), "0e0"); + assert_eq!(to_string(f, 0.0, MinusPlus, (5, 9), false), "+0e0"); + assert_eq!(to_string(f, -0.0, Minus, (0, 0), true), "-0E0"); + assert_eq!(to_string(f, -0.0, MinusPlus, (5, 9), false), "-0e0"); assert_eq!(to_string(f, 1.0 / 0.0, Minus, (-4, 16), false), "inf"); - assert_eq!(to_string(f, 1.0 / 0.0, MinusRaw, (-4, 16), true), "inf"); - assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, (-4, 16), false), "+inf"); - assert_eq!(to_string(f, 1.0 / 0.0, MinusPlusRaw, (-4, 16), true), "+inf"); + assert_eq!(to_string(f, 1.0 / 0.0, Minus, (-4, 16), true), "inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, (-4, 16), true), "+inf"); assert_eq!(to_string(f, 0.0 / 0.0, Minus, (0, 0), false), "NaN"); - assert_eq!(to_string(f, 0.0 / 0.0, MinusRaw, (0, 0), true), "NaN"); - assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, (-9, -5), false), "NaN"); - assert_eq!(to_string(f, 0.0 / 0.0, MinusPlusRaw, (5, 9), true), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, Minus, (0, 0), true), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, (5, 9), true), "NaN"); assert_eq!(to_string(f, -1.0 / 0.0, Minus, (0, 0), false), "-inf"); - assert_eq!(to_string(f, -1.0 / 0.0, MinusRaw, (0, 0), true), "-inf"); - assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, (-9, -5), false), "-inf"); - assert_eq!(to_string(f, -1.0 / 0.0, MinusPlusRaw, (5, 9), true), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, Minus, (0, 0), true), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, (5, 9), true), "-inf"); assert_eq!(to_string(f, 3.14, Minus, (-4, 16), false), "3.14"); - assert_eq!(to_string(f, 3.14, MinusRaw, (-4, 16), false), "3.14"); assert_eq!(to_string(f, 3.14, MinusPlus, (-4, 16), false), "+3.14"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, (-4, 16), false), "+3.14"); assert_eq!(to_string(f, -3.14, Minus, (-4, 16), false), "-3.14"); - assert_eq!(to_string(f, -3.14, MinusRaw, (-4, 16), false), "-3.14"); assert_eq!(to_string(f, -3.14, MinusPlus, (-4, 16), false), "-3.14"); - assert_eq!(to_string(f, -3.14, MinusPlusRaw, (-4, 16), false), "-3.14"); assert_eq!(to_string(f, 3.14, Minus, (0, 0), true), "3.14E0"); - assert_eq!(to_string(f, 3.14, MinusRaw, (0, 0), false), "3.14e0"); - assert_eq!(to_string(f, 3.14, MinusPlus, (-9, -5), true), "+3.14E0"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, (5, 9), false), "+3.14e0"); + assert_eq!(to_string(f, 3.14, Minus, (0, 0), false), "3.14e0"); + assert_eq!(to_string(f, 3.14, MinusPlus, (5, 9), false), "+3.14e0"); assert_eq!(to_string(f, -3.14, Minus, (0, 0), true), "-3.14E0"); - assert_eq!(to_string(f, -3.14, MinusRaw, (0, 0), false), "-3.14e0"); - assert_eq!(to_string(f, -3.14, MinusPlus, (-9, -5), true), "-3.14E0"); - assert_eq!(to_string(f, -3.14, MinusPlusRaw, (5, 9), false), "-3.14e0"); + assert_eq!(to_string(f, -3.14, Minus, (0, 0), false), "-3.14e0"); + assert_eq!(to_string(f, -3.14, MinusPlus, (5, 9), false), "-3.14e0"); assert_eq!(to_string(f, 0.1, Minus, (-4, 16), false), "0.1"); - assert_eq!(to_string(f, 0.1, MinusRaw, (-4, 16), false), "0.1"); + assert_eq!(to_string(f, 0.1, Minus, (-4, 16), false), "0.1"); assert_eq!(to_string(f, 0.1, MinusPlus, (-4, 16), false), "+0.1"); - assert_eq!(to_string(f, 0.1, MinusPlusRaw, (-4, 16), false), "+0.1"); assert_eq!(to_string(f, -0.1, Minus, (-4, 16), false), "-0.1"); - assert_eq!(to_string(f, -0.1, MinusRaw, (-4, 16), false), "-0.1"); assert_eq!(to_string(f, -0.1, MinusPlus, (-4, 16), false), "-0.1"); - assert_eq!(to_string(f, -0.1, MinusPlusRaw, (-4, 16), false), "-0.1"); assert_eq!(to_string(f, 0.1, Minus, (0, 0), true), "1E-1"); - assert_eq!(to_string(f, 0.1, MinusRaw, (0, 0), false), "1e-1"); - assert_eq!(to_string(f, 0.1, MinusPlus, (-9, -5), true), "+1E-1"); - assert_eq!(to_string(f, 0.1, MinusPlusRaw, (5, 9), false), "+1e-1"); + assert_eq!(to_string(f, 0.1, Minus, (0, 0), false), "1e-1"); + assert_eq!(to_string(f, 0.1, MinusPlus, (5, 9), false), "+1e-1"); assert_eq!(to_string(f, -0.1, Minus, (0, 0), true), "-1E-1"); - assert_eq!(to_string(f, -0.1, MinusRaw, (0, 0), false), "-1e-1"); - assert_eq!(to_string(f, -0.1, MinusPlus, (-9, -5), true), "-1E-1"); - assert_eq!(to_string(f, -0.1, MinusPlusRaw, (5, 9), false), "-1e-1"); + assert_eq!(to_string(f, -0.1, Minus, (0, 0), false), "-1e-1"); + assert_eq!(to_string(f, -0.1, MinusPlus, (5, 9), false), "-1e-1"); assert_eq!(to_string(f, 7.5e-11, Minus, (-4, 16), false), "7.5e-11"); assert_eq!(to_string(f, 7.5e-11, Minus, (-11, 10), false), "0.000000000075"); @@ -734,68 +701,51 @@ where let f = &mut f_; assert_eq!(to_string(f, 0.0, Minus, 1, true), "0E0"); - assert_eq!(to_string(f, 0.0, MinusRaw, 1, false), "0e0"); - assert_eq!(to_string(f, 0.0, MinusPlus, 1, true), "+0E0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, 1, false), "+0e0"); - assert_eq!(to_string(f, -0.0, Minus, 1, true), "0E0"); - assert_eq!(to_string(f, -0.0, MinusRaw, 1, false), "-0e0"); - assert_eq!(to_string(f, -0.0, MinusPlus, 1, true), "+0E0"); - assert_eq!(to_string(f, -0.0, MinusPlusRaw, 1, false), "-0e0"); + assert_eq!(to_string(f, 0.0, Minus, 1, false), "0e0"); + assert_eq!(to_string(f, 0.0, MinusPlus, 1, false), "+0e0"); + assert_eq!(to_string(f, -0.0, Minus, 1, true), "-0E0"); + assert_eq!(to_string(f, -0.0, MinusPlus, 1, false), "-0e0"); assert_eq!(to_string(f, 0.0, Minus, 2, true), "0.0E0"); - assert_eq!(to_string(f, 0.0, MinusRaw, 2, false), "0.0e0"); - assert_eq!(to_string(f, 0.0, MinusPlus, 2, true), "+0.0E0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, 2, false), "+0.0e0"); - assert_eq!(to_string(f, -0.0, Minus, 8, true), "0.0000000E0"); - assert_eq!(to_string(f, -0.0, MinusRaw, 8, false), "-0.0000000e0"); - assert_eq!(to_string(f, -0.0, MinusPlus, 8, true), "+0.0000000E0"); - assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8, false), "-0.0000000e0"); + assert_eq!(to_string(f, 0.0, Minus, 2, false), "0.0e0"); + assert_eq!(to_string(f, 0.0, MinusPlus, 2, false), "+0.0e0"); + assert_eq!(to_string(f, -0.0, Minus, 8, false), "-0.0000000e0"); + assert_eq!(to_string(f, -0.0, MinusPlus, 8, false), "-0.0000000e0"); assert_eq!(to_string(f, 1.0 / 0.0, Minus, 1, false), "inf"); - assert_eq!(to_string(f, 1.0 / 0.0, MinusRaw, 1, true), "inf"); - assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 1, false), "+inf"); - assert_eq!(to_string(f, 1.0 / 0.0, MinusPlusRaw, 1, true), "+inf"); + assert_eq!(to_string(f, 1.0 / 0.0, Minus, 1, true), "inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 1, true), "+inf"); assert_eq!(to_string(f, 0.0 / 0.0, Minus, 8, false), "NaN"); - assert_eq!(to_string(f, 0.0 / 0.0, MinusRaw, 8, true), "NaN"); - assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 8, false), "NaN"); - assert_eq!(to_string(f, 0.0 / 0.0, MinusPlusRaw, 8, true), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, Minus, 8, true), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 8, true), "NaN"); assert_eq!(to_string(f, -1.0 / 0.0, Minus, 64, false), "-inf"); - assert_eq!(to_string(f, -1.0 / 0.0, MinusRaw, 64, true), "-inf"); - assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 64, false), "-inf"); - assert_eq!(to_string(f, -1.0 / 0.0, MinusPlusRaw, 64, true), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, Minus, 64, true), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 64, true), "-inf"); assert_eq!(to_string(f, 3.14, Minus, 1, true), "3E0"); - assert_eq!(to_string(f, 3.14, MinusRaw, 1, false), "3e0"); - assert_eq!(to_string(f, 3.14, MinusPlus, 1, true), "+3E0"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, 1, false), "+3e0"); + assert_eq!(to_string(f, 3.14, Minus, 1, false), "3e0"); + assert_eq!(to_string(f, 3.14, MinusPlus, 1, false), "+3e0"); assert_eq!(to_string(f, -3.14, Minus, 2, true), "-3.1E0"); - assert_eq!(to_string(f, -3.14, MinusRaw, 2, false), "-3.1e0"); - assert_eq!(to_string(f, -3.14, MinusPlus, 2, true), "-3.1E0"); - assert_eq!(to_string(f, -3.14, MinusPlusRaw, 2, false), "-3.1e0"); + assert_eq!(to_string(f, -3.14, Minus, 2, false), "-3.1e0"); + assert_eq!(to_string(f, -3.14, MinusPlus, 2, false), "-3.1e0"); assert_eq!(to_string(f, 3.14, Minus, 3, true), "3.14E0"); - assert_eq!(to_string(f, 3.14, MinusRaw, 3, false), "3.14e0"); - assert_eq!(to_string(f, 3.14, MinusPlus, 3, true), "+3.14E0"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, 3, false), "+3.14e0"); + assert_eq!(to_string(f, 3.14, Minus, 3, false), "3.14e0"); + assert_eq!(to_string(f, 3.14, MinusPlus, 3, false), "+3.14e0"); assert_eq!(to_string(f, -3.14, Minus, 4, true), "-3.140E0"); - assert_eq!(to_string(f, -3.14, MinusRaw, 4, false), "-3.140e0"); - assert_eq!(to_string(f, -3.14, MinusPlus, 4, true), "-3.140E0"); - assert_eq!(to_string(f, -3.14, MinusPlusRaw, 4, false), "-3.140e0"); + assert_eq!(to_string(f, -3.14, Minus, 4, false), "-3.140e0"); + assert_eq!(to_string(f, -3.14, MinusPlus, 4, false), "-3.140e0"); assert_eq!(to_string(f, 0.195, Minus, 1, false), "2e-1"); - assert_eq!(to_string(f, 0.195, MinusRaw, 1, true), "2E-1"); - assert_eq!(to_string(f, 0.195, MinusPlus, 1, false), "+2e-1"); - assert_eq!(to_string(f, 0.195, MinusPlusRaw, 1, true), "+2E-1"); + assert_eq!(to_string(f, 0.195, Minus, 1, true), "2E-1"); + assert_eq!(to_string(f, 0.195, MinusPlus, 1, true), "+2E-1"); assert_eq!(to_string(f, -0.195, Minus, 2, false), "-2.0e-1"); - assert_eq!(to_string(f, -0.195, MinusRaw, 2, true), "-2.0E-1"); - assert_eq!(to_string(f, -0.195, MinusPlus, 2, false), "-2.0e-1"); - assert_eq!(to_string(f, -0.195, MinusPlusRaw, 2, true), "-2.0E-1"); + assert_eq!(to_string(f, -0.195, Minus, 2, true), "-2.0E-1"); + assert_eq!(to_string(f, -0.195, MinusPlus, 2, true), "-2.0E-1"); assert_eq!(to_string(f, 0.195, Minus, 3, false), "1.95e-1"); - assert_eq!(to_string(f, 0.195, MinusRaw, 3, true), "1.95E-1"); - assert_eq!(to_string(f, 0.195, MinusPlus, 3, false), "+1.95e-1"); - assert_eq!(to_string(f, 0.195, MinusPlusRaw, 3, true), "+1.95E-1"); + assert_eq!(to_string(f, 0.195, Minus, 3, true), "1.95E-1"); + assert_eq!(to_string(f, 0.195, MinusPlus, 3, true), "+1.95E-1"); assert_eq!(to_string(f, -0.195, Minus, 4, false), "-1.950e-1"); - assert_eq!(to_string(f, -0.195, MinusRaw, 4, true), "-1.950E-1"); - assert_eq!(to_string(f, -0.195, MinusPlus, 4, false), "-1.950e-1"); - assert_eq!(to_string(f, -0.195, MinusPlusRaw, 4, true), "-1.950E-1"); + assert_eq!(to_string(f, -0.195, Minus, 4, true), "-1.950E-1"); + assert_eq!(to_string(f, -0.195, MinusPlus, 4, true), "-1.950E-1"); assert_eq!(to_string(f, 9.5, Minus, 1, false), "1e1"); assert_eq!(to_string(f, 9.5, Minus, 2, false), "9.5e0"); @@ -1007,68 +957,48 @@ where let f = &mut f_; assert_eq!(to_string(f, 0.0, Minus, 0), "0"); - assert_eq!(to_string(f, 0.0, MinusRaw, 0), "0"); assert_eq!(to_string(f, 0.0, MinusPlus, 0), "+0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, 0), "+0"); - assert_eq!(to_string(f, -0.0, Minus, 0), "0"); - assert_eq!(to_string(f, -0.0, MinusRaw, 0), "-0"); - assert_eq!(to_string(f, -0.0, MinusPlus, 0), "+0"); - assert_eq!(to_string(f, -0.0, MinusPlusRaw, 0), "-0"); + assert_eq!(to_string(f, -0.0, Minus, 0), "-0"); + assert_eq!(to_string(f, -0.0, MinusPlus, 0), "-0"); assert_eq!(to_string(f, 0.0, Minus, 1), "0.0"); - assert_eq!(to_string(f, 0.0, MinusRaw, 1), "0.0"); assert_eq!(to_string(f, 0.0, MinusPlus, 1), "+0.0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, 1), "+0.0"); - assert_eq!(to_string(f, -0.0, Minus, 8), "0.00000000"); - assert_eq!(to_string(f, -0.0, MinusRaw, 8), "-0.00000000"); - assert_eq!(to_string(f, -0.0, MinusPlus, 8), "+0.00000000"); - assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8), "-0.00000000"); + assert_eq!(to_string(f, -0.0, Minus, 8), "-0.00000000"); + assert_eq!(to_string(f, -0.0, MinusPlus, 8), "-0.00000000"); assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0), "inf"); - assert_eq!(to_string(f, 1.0 / 0.0, MinusRaw, 1), "inf"); - assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 8), "+inf"); - assert_eq!(to_string(f, 1.0 / 0.0, MinusPlusRaw, 64), "+inf"); + assert_eq!(to_string(f, 1.0 / 0.0, Minus, 1), "inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 64), "+inf"); assert_eq!(to_string(f, 0.0 / 0.0, Minus, 0), "NaN"); - assert_eq!(to_string(f, 0.0 / 0.0, MinusRaw, 1), "NaN"); - assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 8), "NaN"); - assert_eq!(to_string(f, 0.0 / 0.0, MinusPlusRaw, 64), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, Minus, 1), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 64), "NaN"); assert_eq!(to_string(f, -1.0 / 0.0, Minus, 0), "-inf"); - assert_eq!(to_string(f, -1.0 / 0.0, MinusRaw, 1), "-inf"); - assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 8), "-inf"); - assert_eq!(to_string(f, -1.0 / 0.0, MinusPlusRaw, 64), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, Minus, 1), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 64), "-inf"); assert_eq!(to_string(f, 3.14, Minus, 0), "3"); - assert_eq!(to_string(f, 3.14, MinusRaw, 0), "3"); + assert_eq!(to_string(f, 3.14, Minus, 0), "3"); assert_eq!(to_string(f, 3.14, MinusPlus, 0), "+3"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, 0), "+3"); assert_eq!(to_string(f, -3.14, Minus, 0), "-3"); - assert_eq!(to_string(f, -3.14, MinusRaw, 0), "-3"); + assert_eq!(to_string(f, -3.14, Minus, 0), "-3"); assert_eq!(to_string(f, -3.14, MinusPlus, 0), "-3"); - assert_eq!(to_string(f, -3.14, MinusPlusRaw, 0), "-3"); assert_eq!(to_string(f, 3.14, Minus, 1), "3.1"); - assert_eq!(to_string(f, 3.14, MinusRaw, 2), "3.14"); - assert_eq!(to_string(f, 3.14, MinusPlus, 3), "+3.140"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, 4), "+3.1400"); + assert_eq!(to_string(f, 3.14, Minus, 2), "3.14"); + assert_eq!(to_string(f, 3.14, MinusPlus, 4), "+3.1400"); + assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000"); assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000"); - assert_eq!(to_string(f, -3.14, MinusRaw, 8), "-3.14000000"); assert_eq!(to_string(f, -3.14, MinusPlus, 8), "-3.14000000"); - assert_eq!(to_string(f, -3.14, MinusPlusRaw, 8), "-3.14000000"); assert_eq!(to_string(f, 0.195, Minus, 0), "0"); - assert_eq!(to_string(f, 0.195, MinusRaw, 0), "0"); assert_eq!(to_string(f, 0.195, MinusPlus, 0), "+0"); - assert_eq!(to_string(f, 0.195, MinusPlusRaw, 0), "+0"); assert_eq!(to_string(f, -0.195, Minus, 0), "-0"); - assert_eq!(to_string(f, -0.195, MinusRaw, 0), "-0"); + assert_eq!(to_string(f, -0.195, Minus, 0), "-0"); assert_eq!(to_string(f, -0.195, MinusPlus, 0), "-0"); - assert_eq!(to_string(f, -0.195, MinusPlusRaw, 0), "-0"); assert_eq!(to_string(f, 0.195, Minus, 1), "0.2"); - assert_eq!(to_string(f, 0.195, MinusRaw, 2), "0.20"); - assert_eq!(to_string(f, 0.195, MinusPlus, 3), "+0.195"); - assert_eq!(to_string(f, 0.195, MinusPlusRaw, 4), "+0.1950"); + assert_eq!(to_string(f, 0.195, Minus, 2), "0.20"); + assert_eq!(to_string(f, 0.195, MinusPlus, 4), "+0.1950"); assert_eq!(to_string(f, -0.195, Minus, 5), "-0.19500"); - assert_eq!(to_string(f, -0.195, MinusRaw, 6), "-0.195000"); - assert_eq!(to_string(f, -0.195, MinusPlus, 7), "-0.1950000"); - assert_eq!(to_string(f, -0.195, MinusPlusRaw, 8), "-0.19500000"); + assert_eq!(to_string(f, -0.195, Minus, 6), "-0.195000"); + assert_eq!(to_string(f, -0.195, MinusPlus, 8), "-0.19500000"); assert_eq!(to_string(f, 999.5, Minus, 0), "1000"); assert_eq!(to_string(f, 999.5, Minus, 1), "999.5"); diff --git a/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff b/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff index caa02abf019..3a50ed224b5 100644 --- a/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff +++ b/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff @@ -51,7 +51,7 @@ } bb2: { - discriminant(_6) = 2; // scope 1 at $DIR/funky_arms.rs:21:17: 21:41 + discriminant(_6) = 1; // scope 1 at $DIR/funky_arms.rs:21:17: 21:41 goto -> bb4; // scope 1 at $DIR/funky_arms.rs:19:16: 22:6 } From 6fdb8d8b360b91a10045fe74467b98d218b7ffe9 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 31 Oct 2020 17:21:23 -0700 Subject: [PATCH 095/370] Update signed fmt/-0f32 docs "semantic equivalence" is too strong a phrasing here, which is why actually explaining what kind of circumstances might produce a -0 was chosen instead. --- library/alloc/src/fmt.rs | 5 ++--- library/std/src/primitive_docs.rs | 8 +++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index f9424b1d747..439b0adde20 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -157,9 +157,8 @@ //! //! * `+` - This is intended for numeric types and indicates that the sign //! should always be printed. Positive signs are never printed by -//! default, and the negative sign is only printed by default for the -//! `Signed` trait. This flag indicates that the correct sign (`+` or `-`) -//! should always be printed. +//! default, and the negative sign is only printed by default for signed values. +//! This flag indicates that the correct sign (`+` or `-`) should always be printed. //! * `-` - Currently not used //! * `#` - This flag indicates that the "alternate" form of printing should //! be used. The alternate forms are: diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index d4bb2083d00..b48718df31c 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -805,10 +805,12 @@ mod prim_tuple {} /// often discard insignificant digits: `println!("{}", 1.0f32 / 5.0f32)` will /// print `0.2`. /// -/// Additionally, `f32` can represent a couple of special values: +/// Additionally, `f32` can represent some special values: /// -/// - `-0`: this is just due to how floats are encoded. It is semantically -/// equivalent to `0` and `-0.0 == 0.0` results in `true`. +/// - `-0`: this value exists due to how floats are encoded. -0 == 0 is true, but for other +/// operations they are not equal and the difference can be useful to certain algorithms. +/// For example, operations on negative numbers that underflow to 0 will usually generate -0 +/// instead of +0. /// - [∞](#associatedconstant.INFINITY) and /// [−∞](#associatedconstant.NEG_INFINITY): these result from calculations /// like `1.0 / 0.0`. From e8dfbaca76616a32cabba30ec343cd4fcb28bda9 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 1 Nov 2020 10:31:08 -0800 Subject: [PATCH 096/370] Rephrase -0.0 docs --- library/std/src/primitive_docs.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index b48718df31c..64b22b64f4b 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -807,10 +807,10 @@ mod prim_tuple {} /// /// Additionally, `f32` can represent some special values: /// -/// - `-0`: this value exists due to how floats are encoded. -0 == 0 is true, but for other -/// operations they are not equal and the difference can be useful to certain algorithms. -/// For example, operations on negative numbers that underflow to 0 will usually generate -0 -/// instead of +0. +/// - -0.0: IEEE 754 floating point numbers have a bit that indicates their sign, so -0.0 is a +/// possible value. For comparison `-0.0 == +0.0` is true but floating point operations can +/// carry the sign bit through arithmetic operations. This means `-1.0 * 0.0` produces -0.0 and +/// a negative number rounded to a value smaller than a float can represent also produces -0.0. /// - [∞](#associatedconstant.INFINITY) and /// [−∞](#associatedconstant.NEG_INFINITY): these result from calculations /// like `1.0 / 0.0`. From b3ae90b4c20ae28c5dc1c141997869f9fd3148a6 Mon Sep 17 00:00:00 2001 From: Camelid Date: Tue, 23 Mar 2021 17:20:12 -0700 Subject: [PATCH 097/370] Tell GitHub to highlight `config.toml.example` as TOML This should be a nice small quality of life improvement when looking at `config.toml.example` on GitHub or looking at diffs of it in PRs. --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index d29c15fe712..51a670b5fbe 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9,6 +9,7 @@ src/etc/installer/gfx/* binary src/vendor/** -text Cargo.lock linguist-generated=false +config.toml.example linguist-language=TOML # Older git versions try to fix line endings on images and fonts, this prevents it. *.png binary From 3d8ce0aa55c182e569ad7015a0af752ef92e2572 Mon Sep 17 00:00:00 2001 From: Camelid Date: Tue, 9 Mar 2021 22:11:53 -0800 Subject: [PATCH 098/370] rustdoc: Use diagnostics for error when including sources This error probably almost never happens, but we should still use the diagnostic infrastructure. My guess is that the error was added back before rustdoc used the rustc diagnostic infrastructure (it was all `println!` and `eprintln!` back then!) and since it likely rarely occurs and this code doesn't change that much, no one thought to transition it to using diagnostics. Note that the old error was actually a warning (it didn't stop the rest of doc building). It seems very unlikely that this would fail without the rest of the doc build failing, so it makes more sense for it to be a hard error. The error looks like this: error: failed to render source code for `src/test/rustdoc/smart-punct.rs`: "bar": foo --> src/test/rustdoc/smart-punct.rs:3:1 | 3 | / #![crate_name = "foo"] 4 | | 5 | | //! This is the "start" of the 'document'! How'd you know that "it's" ... 6 | | //! ... | 22 | | //! I say "don't smart-punct me -- please!" 23 | | //! ``` | |_______^ I wasn't sure how to trigger the error, so to create that message I temporarily made rustdoc always emit it. That's also why it says "bar" and "foo" instead of a real error message. Note that the span of the diagnostic starts at line 3 because line 1 of that file is a (non-doc) comment and line 2 is a blank line. --- src/librustdoc/html/sources.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 1b6a82fed11..001c8b09044 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -54,12 +54,10 @@ impl DocFolder for SourceCollector<'_, '_> { self.scx.include_sources = match self.emit_source(&filename) { Ok(()) => true, Err(e) => { - println!( - "warning: source code was requested to be rendered, \ - but processing `{}` had an error: {}", - filename, e + self.scx.tcx.sess.span_err( + item.span.inner(), + &format!("failed to render source code for `{}`: {}", filename, e), ); - println!(" skipping rendering of source code"); false } }; From a421cfed74a10a46a082f747448992ea603559ce Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Sat, 6 Feb 2021 23:41:42 +0900 Subject: [PATCH 099/370] Add regression test to ensure `#[allow(unstable_name_collisions)]` works --- src/test/ui/inference/issue-81522.rs | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/test/ui/inference/issue-81522.rs diff --git a/src/test/ui/inference/issue-81522.rs b/src/test/ui/inference/issue-81522.rs new file mode 100644 index 00000000000..902f8fdde58 --- /dev/null +++ b/src/test/ui/inference/issue-81522.rs @@ -0,0 +1,31 @@ +// Regression test for #81522. +// Ensures that `#[allow(unstable_name_collisions)]` appended to things other than function +// suppresses the corresponding diagnostics emitted from inside them. +// But note that this attribute doesn't work for macro invocations if it is appended directly. + +// aux-build:inference_unstable_iterator.rs +// aux-build:inference_unstable_itertools.rs +// run-pass + +extern crate inference_unstable_iterator; +extern crate inference_unstable_itertools; + +#[allow(unused_imports)] +use inference_unstable_iterator::IpuIterator; +use inference_unstable_itertools::IpuItertools; + +fn main() { + // expression statement + #[allow(unstable_name_collisions)] + 'x'.ipu_flatten(); + + // let statement + #[allow(unstable_name_collisions)] + let _ = 'x'.ipu_flatten(); + + // block expression + #[allow(unstable_name_collisions)] + { + 'x'.ipu_flatten(); + } +} From 120e5bdac00f9066491e34401d381b107aea06d6 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Tue, 9 Feb 2021 20:49:08 +0900 Subject: [PATCH 100/370] Pass HirId of expr in question instead of function body --- .../rustc_typeck/src/check/method/probe.rs | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 0742549f890..7142be9c09e 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -83,6 +83,8 @@ struct ProbeContext<'a, 'tcx> { unsatisfied_predicates: Vec<(ty::Predicate<'tcx>, Option>)>, is_suggestion: IsSuggestion, + + scope_expr_id: hir::HirId, } impl<'a, 'tcx> Deref for ProbeContext<'a, 'tcx> { @@ -285,7 +287,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, scope_expr_id, ProbeScope::AllTraits, - |probe_cx| probe_cx.pick(), + |probe_cx| probe_cx.pick(scope_expr_id), ) .ok() .map(|pick| pick.item) @@ -317,7 +319,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, scope_expr_id, scope, - |probe_cx| probe_cx.pick(), + |probe_cx| probe_cx.pick(scope_expr_id), ) } @@ -448,6 +450,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { orig_values, steps.steps, is_suggestion, + scope_expr_id, ); probe_cx.assemble_inherent_candidates(); @@ -547,6 +550,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { orig_steps_var_values: OriginalQueryValues<'tcx>, steps: Lrc>>, is_suggestion: IsSuggestion, + scope_expr_id: hir::HirId, ) -> ProbeContext<'a, 'tcx> { ProbeContext { fcx, @@ -564,6 +568,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { private_candidate: None, unsatisfied_predicates: Vec::new(), is_suggestion, + scope_expr_id, } } @@ -1031,7 +1036,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /////////////////////////////////////////////////////////////////////////// // THE ACTUAL SEARCH - fn pick(mut self) -> PickResult<'tcx> { + fn pick(mut self, scope_expr_id: hir::HirId) -> PickResult<'tcx> { assert!(self.method_name.is_some()); if let Some(r) = self.pick_core() { @@ -1077,7 +1082,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if let Some((kind, def_id)) = private_candidate { return Err(MethodError::PrivateMatch(kind, def_id, out_of_scope_traits)); } - let lev_candidate = self.probe_for_lev_candidate()?; + let lev_candidate = self.probe_for_lev_candidate(scope_expr_id)?; Err(MethodError::NoMatch(NoMatchData::new( static_candidates, @@ -1312,7 +1317,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ) { self.tcx.struct_span_lint_hir( lint::builtin::UNSTABLE_NAME_COLLISIONS, - self.fcx.body_id, + self.scope_expr_id, self.span, |lint| { let def_kind = stable_pick.item.kind.as_def_kind(); @@ -1580,7 +1585,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// Similarly to `probe_for_return_type`, this method attempts to find the best matching /// candidate method where the method name may have been misspelt. Similarly to other /// Levenshtein based suggestions, we provide at most one such suggestion. - fn probe_for_lev_candidate(&mut self) -> Result, MethodError<'tcx>> { + fn probe_for_lev_candidate( + &mut self, + scope_expr_id: hir::HirId, + ) -> Result, MethodError<'tcx>> { debug!("probing for method names similar to {:?}", self.method_name); let steps = self.steps.clone(); @@ -1594,6 +1602,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.orig_steps_var_values.clone(), steps, IsSuggestion(true), + scope_expr_id, ); pcx.allow_similar_names = true; pcx.assemble_inherent_candidates(); From 06b3636f4ed23c1ad0ed18ecc1408147ec862c1a Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Sat, 27 Feb 2021 20:55:00 +0900 Subject: [PATCH 101/370] Remove unnecessary passing of scope_expr_id --- compiler/rustc_typeck/src/check/method/probe.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 7142be9c09e..8bf7a5f5223 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -287,7 +287,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, scope_expr_id, ProbeScope::AllTraits, - |probe_cx| probe_cx.pick(scope_expr_id), + |probe_cx| probe_cx.pick(), ) .ok() .map(|pick| pick.item) @@ -319,7 +319,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, scope_expr_id, scope, - |probe_cx| probe_cx.pick(scope_expr_id), + |probe_cx| probe_cx.pick(), ) } @@ -1036,7 +1036,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /////////////////////////////////////////////////////////////////////////// // THE ACTUAL SEARCH - fn pick(mut self, scope_expr_id: hir::HirId) -> PickResult<'tcx> { + fn pick(mut self) -> PickResult<'tcx> { assert!(self.method_name.is_some()); if let Some(r) = self.pick_core() { @@ -1082,7 +1082,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if let Some((kind, def_id)) = private_candidate { return Err(MethodError::PrivateMatch(kind, def_id, out_of_scope_traits)); } - let lev_candidate = self.probe_for_lev_candidate(scope_expr_id)?; + let lev_candidate = self.probe_for_lev_candidate()?; Err(MethodError::NoMatch(NoMatchData::new( static_candidates, @@ -1585,10 +1585,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// Similarly to `probe_for_return_type`, this method attempts to find the best matching /// candidate method where the method name may have been misspelt. Similarly to other /// Levenshtein based suggestions, we provide at most one such suggestion. - fn probe_for_lev_candidate( - &mut self, - scope_expr_id: hir::HirId, - ) -> Result, MethodError<'tcx>> { + fn probe_for_lev_candidate(&mut self) -> Result, MethodError<'tcx>> { debug!("probing for method names similar to {:?}", self.method_name); let steps = self.steps.clone(); @@ -1602,7 +1599,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.orig_steps_var_values.clone(), steps, IsSuggestion(true), - scope_expr_id, + self.scope_expr_id, ); pcx.allow_similar_names = true; pcx.assemble_inherent_candidates(); From 8c8841811414ba3348f8c604b0ce01200cc8be91 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Wed, 24 Mar 2021 23:26:18 -0400 Subject: [PATCH 102/370] Try to make Vec benchmarks only run code they are benchmarking Many of the Vec benchmarks assert what values should be produced by the benchmarked code. In some cases, these asserts dominate the runtime of the benchmarks they are in, causing the benchmarks to understate the impact of an optimization or regression. --- library/alloc/benches/vec.rs | 93 ++++++++++-------------------------- 1 file changed, 25 insertions(+), 68 deletions(-) diff --git a/library/alloc/benches/vec.rs b/library/alloc/benches/vec.rs index 7a098219ce4..48709e89823 100644 --- a/library/alloc/benches/vec.rs +++ b/library/alloc/benches/vec.rs @@ -4,23 +4,13 @@ use test::{black_box, Bencher}; #[bench] fn bench_new(b: &mut Bencher) { - b.iter(|| { - let v: Vec = Vec::new(); - assert_eq!(v.len(), 0); - assert_eq!(v.capacity(), 0); - v - }) + b.iter(|| Vec::::new()) } fn do_bench_with_capacity(b: &mut Bencher, src_len: usize) { b.bytes = src_len as u64; - b.iter(|| { - let v: Vec = Vec::with_capacity(src_len); - assert_eq!(v.len(), 0); - assert_eq!(v.capacity(), src_len); - v - }) + b.iter(|| Vec::::with_capacity(src_len)) } #[bench] @@ -46,12 +36,7 @@ fn bench_with_capacity_1000(b: &mut Bencher) { fn do_bench_from_fn(b: &mut Bencher, src_len: usize) { b.bytes = src_len as u64; - b.iter(|| { - let dst = (0..src_len).collect::>(); - assert_eq!(dst.len(), src_len); - assert!(dst.iter().enumerate().all(|(i, x)| i == *x)); - dst - }) + b.iter(|| (0..src_len).collect::>()) } #[bench] @@ -77,12 +62,7 @@ fn bench_from_fn_1000(b: &mut Bencher) { fn do_bench_from_elem(b: &mut Bencher, src_len: usize) { b.bytes = src_len as u64; - b.iter(|| { - let dst: Vec = repeat(5).take(src_len).collect(); - assert_eq!(dst.len(), src_len); - assert!(dst.iter().all(|x| *x == 5)); - dst - }) + b.iter(|| repeat(5).take(src_len).collect::>()) } #[bench] @@ -110,12 +90,7 @@ fn do_bench_from_slice(b: &mut Bencher, src_len: usize) { b.bytes = src_len as u64; - b.iter(|| { - let dst = src.clone()[..].to_vec(); - assert_eq!(dst.len(), src_len); - assert!(dst.iter().enumerate().all(|(i, x)| i == *x)); - dst - }); + b.iter(|| src.as_slice().to_vec()); } #[bench] @@ -144,9 +119,7 @@ fn do_bench_from_iter(b: &mut Bencher, src_len: usize) { b.bytes = src_len as u64; b.iter(|| { - let dst: Vec<_> = FromIterator::from_iter(src.clone()); - assert_eq!(dst.len(), src_len); - assert!(dst.iter().enumerate().all(|(i, x)| i == *x)); + let dst: Vec<_> = FromIterator::from_iter(src.iter().cloned()); dst }); } @@ -180,8 +153,6 @@ fn do_bench_extend(b: &mut Bencher, dst_len: usize, src_len: usize) { b.iter(|| { let mut dst = dst.clone(); dst.extend(src.clone()); - assert_eq!(dst.len(), dst_len + src_len); - assert!(dst.iter().enumerate().all(|(i, x)| i == *x)); dst }); } @@ -230,8 +201,6 @@ fn do_bench_extend_from_slice(b: &mut Bencher, dst_len: usize, src_len: usize) { b.iter(|| { let mut dst = dst.clone(); dst.extend_from_slice(&src); - assert_eq!(dst.len(), dst_len + src_len); - assert!(dst.iter().enumerate().all(|(i, x)| i == *x)); dst }); } @@ -290,12 +259,7 @@ fn do_bench_clone(b: &mut Bencher, src_len: usize) { b.bytes = src_len as u64; - b.iter(|| { - let dst = src.clone(); - assert_eq!(dst.len(), src_len); - assert!(dst.iter().enumerate().all(|(i, x)| i == *x)); - dst - }); + b.iter(|| src.clone()); } #[bench] @@ -329,8 +293,7 @@ fn do_bench_clone_from(b: &mut Bencher, times: usize, dst_len: usize, src_len: u for _ in 0..times { dst.clone_from(&src); - assert_eq!(dst.len(), src_len); - assert!(dst.iter().enumerate().all(|(i, x)| dst_len + i == *x)); + dst = black_box(dst); } dst }); @@ -463,11 +426,10 @@ macro_rules! bench_in_place { fn $fname(b: &mut Bencher) { b.iter(|| { let src: Vec<$type> = black_box(vec![$init; $count]); - let mut sink = src.into_iter() + src.into_iter() .enumerate() .map(|(idx, e)| idx as $type ^ e) - .collect::>(); - black_box(sink.as_mut_ptr()) + .collect::>() }); } )+ @@ -527,7 +489,6 @@ fn bench_in_place_zip_recycle(b: &mut Bencher) { .enumerate() .map(|(i, (d, s))| d.wrapping_add(i as u8) ^ s) .collect::>(); - assert_eq!(mangled.len(), 1000); data = black_box(mangled); }); } @@ -614,23 +575,6 @@ fn bench_nest_chain_chain_collect(b: &mut Bencher) { }); } -pub fn example_plain_slow(l: &[u32]) -> Vec { - let mut result = Vec::with_capacity(l.len()); - result.extend(l.iter().rev()); - result -} - -pub fn map_fast(l: &[(u32, u32)]) -> Vec { - let mut result = Vec::with_capacity(l.len()); - for i in 0..l.len() { - unsafe { - *result.get_unchecked_mut(i) = l[i].0; - result.set_len(i); - } - } - result -} - #[bench] fn bench_range_map_collect(b: &mut Bencher) { b.iter(|| (0..LEN).map(|_| u32::default()).collect::>()); @@ -669,7 +613,11 @@ fn bench_rev_1(b: &mut Bencher) { #[bench] fn bench_rev_2(b: &mut Bencher) { let data = black_box([0; LEN]); - b.iter(|| example_plain_slow(&data)); + b.iter(|| { + let mut v = Vec::::with_capacity(data.len()); + v.extend(data.iter().rev()); + v + }); } #[bench] @@ -685,7 +633,16 @@ fn bench_map_regular(b: &mut Bencher) { #[bench] fn bench_map_fast(b: &mut Bencher) { let data = black_box([(0, 0); LEN]); - b.iter(|| map_fast(&data)); + b.iter(|| { + let mut result = Vec::with_capacity(data.len()); + for i in 0..data.len() { + unsafe { + *result.get_unchecked_mut(i) = data[i].0; + result.set_len(i); + } + } + result + }); } fn random_sorted_fill(mut seed: u32, buf: &mut [u32]) { From 11e40ce240d884303bee142a727decaeeef43bdb Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 25 Mar 2021 10:27:53 +0000 Subject: [PATCH 103/370] ExitStatus: print "exit status: {}" rather than "exit code: {}" Proper Unix terminology is "exit status" (vs "wait status"). "exit code" is imprecise on Unix and therefore unclear. (As far as I can tell, "exit code" is correct terminology on Windows.) This new wording is unfortunately inconsistent with the identifier names in the Rust stdlib. It is the identifier names that are wrong, as discussed at length in eg https://doc.rust-lang.org/nightly/std/process/struct.ExitStatus.html https://doc.rust-lang.org/nightly/std/os/unix/process/trait.ExitStatusExt.html Unfortunately for API stability reasons it would be a lot of work, and a lot of disruption, to change the names in the stdlib (eg to rename `std::process::ExitStatus` to `std::process::ChildStatus` or something), but we should fix the message output. Many (probably most) readers of these messages about exit statuses will be users and system administrators, not programmers, who won't even know that Rust has this wrong terminology. So I think the right thing is to fix the documentation (as I have already done) and, now, the terminology in the implementation. This is a user-visible change to the behaviour of all Rust programs which run Unix subprocesses. Hopefully no-one is matching against the exit status string, except perhaps in tests. Signed-off-by: Ian Jackson --- library/std/src/sys/unix/process/process_unix.rs | 2 +- library/std/src/sys/unix/process/process_unix/tests.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 47aaca82af9..77a450fc571 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -529,7 +529,7 @@ impl From for ExitStatus { impl fmt::Display for ExitStatus { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(code) = self.code() { - write!(f, "exit code: {}", code) + write!(f, "exit status: {}", code) } else if let Some(signal) = self.signal() { if self.core_dumped() { write!(f, "signal: {} (core dumped)", signal) diff --git a/library/std/src/sys/unix/process/process_unix/tests.rs b/library/std/src/sys/unix/process/process_unix/tests.rs index 5819d2c2a5a..02c469fbcdf 100644 --- a/library/std/src/sys/unix/process/process_unix/tests.rs +++ b/library/std/src/sys/unix/process/process_unix/tests.rs @@ -9,8 +9,8 @@ fn exitstatus_display_tests() { t(0x0000f, "signal: 15"); t(0x0008b, "signal: 11 (core dumped)"); - t(0x00000, "exit code: 0"); - t(0x0ff00, "exit code: 255"); + t(0x00000, "exit status: 0"); + t(0x0ff00, "exit status: 255"); // On MacOS, 0x0137f is WIFCONTINUED, not WIFSTOPPED. Probably *BSD is similar. // https://github.com/rust-lang/rust/pull/82749#issuecomment-790525956 From 7c89cc4a6f68a9c544ff1b000c8f7ef1c3535278 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 25 Mar 2021 11:40:32 -0400 Subject: [PATCH 104/370] Add SharedResource abstraction and use it in write_shared This cleans up the code quite a bit, and also makes the next commit much easier. --- src/librustdoc/html/render/context.rs | 13 +- src/librustdoc/html/render/write_shared.rs | 217 +++++++++++---------- 2 files changed, 115 insertions(+), 115 deletions(-) diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 64d413a5f31..468bd9997a6 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -79,17 +79,6 @@ crate struct Context<'tcx> { rustc_data_structures::static_assert_size!(Context<'_>, 152); impl<'tcx> Context<'tcx> { - pub(super) fn path(&self, filename: &str) -> PathBuf { - // We use splitn vs Path::extension here because we might get a filename - // like `style.min.css` and we want to process that into - // `style-suffix.min.css`. Path::extension would just return `css` - // which would result in `style.min-suffix.css` which isn't what we - // want. - let (base, ext) = filename.split_once('.').unwrap(); - let filename = format!("{}{}.{}", base, self.shared.resource_suffix, ext); - self.dst.join(&filename) - } - pub(super) fn tcx(&self) -> TyCtxt<'tcx> { self.shared.tcx } @@ -487,7 +476,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { |buf: &mut Buffer| all.print(buf), &self.shared.style_files, ); - self.shared.fs.write(&final_file, v.as_bytes())?; + self.shared.fs.write(final_file, v.as_bytes())?; // Generating settings page. page.title = "Rustdoc settings"; diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 501d8e8e02e..2ab423c238c 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -14,7 +14,7 @@ use serde::Serialize; use super::{collect_paths_for_type, ensure_trailing_slash, Context, BASIC_KEYWORDS}; use crate::clean::Crate; use crate::config::RenderOptions; -use crate::docfs::{DocFS, PathError}; +use crate::docfs::PathError; use crate::error::Error; use crate::formats::FormatRenderer; use crate::html::{layout, static_files}; @@ -40,6 +40,81 @@ crate static FILES_UNVERSIONED: Lazy> = Lazy::new(|| { } }); +enum SharedResource<'a> { + /// This file will never change, no matter what toolchain is used to build it. + /// + /// It does not have a resource suffix. + Unversioned { name: &'a str }, + /// This file may change depending on the toolchain. + /// + /// It has a resource suffix. + ToolchainSpecific { basename: &'a str }, + /// This file may change for any crate within a build. + /// + /// This differs from normal crate-specific files because it has a resource suffix. + CrateSpecific { basename: &'a str }, +} + +impl SharedResource<'_> { + fn extension(&self) -> Option<&OsStr> { + use SharedResource::*; + match self { + Unversioned { name } + | ToolchainSpecific { basename: name } + | CrateSpecific { basename: name } => Path::new(name).extension(), + } + } + + fn path(&self, cx: &Context<'_>) -> PathBuf { + match self { + SharedResource::Unversioned { name } => cx.dst.join(name), + SharedResource::ToolchainSpecific { basename } => cx.suffix_path(basename), + SharedResource::CrateSpecific { basename } => cx.suffix_path(basename), + } + } +} + +impl Context<'_> { + fn suffix_path(&self, filename: &str) -> PathBuf { + // We use splitn vs Path::extension here because we might get a filename + // like `style.min.css` and we want to process that into + // `style-suffix.min.css`. Path::extension would just return `css` + // which would result in `style.min-suffix.css` which isn't what we + // want. + let (base, ext) = filename.split_once('.').unwrap(); + let filename = format!("{}{}.{}", base, self.shared.resource_suffix, ext); + self.dst.join(&filename) + } + + fn write_shared>(&self, resource: SharedResource<'_>, contents: C) -> Result<(), Error> + { + self.shared.fs.write(resource.path(self), contents) + } + + fn write_minify( + &self, + resource: SharedResource<'_>, + contents: &str, + minify: bool, + ) -> Result<(), Error> { + let tmp; + let contents = if minify { + tmp = if resource.extension() == Some(&OsStr::new("css")) { + minifier::css::minify(contents).map_err(|e| { + Error::new(format!("failed to minify CSS file: {}", e), resource.path(self)) + })? + } else { + minifier::js::minify(contents) + }; + tmp.as_bytes() + } else { + contents.as_bytes() + }; + + self.write_shared(resource, contents) + } +} + pub(super) fn write_shared( cx: &Context<'_>, krate: &Crate, @@ -52,27 +127,22 @@ pub(super) fn write_shared( let lock_file = cx.dst.join(".lock"); let _lock = try_err!(flock::Lock::new(&lock_file, true, true, true), &lock_file); + // The weird `: &_` is to work around a borrowck bug: https://github.com/rust-lang/rust/issues/41078#issuecomment-293646723 + let write_minify = |p, c: &_| { + cx.write_minify( + SharedResource::ToolchainSpecific { basename: p }, + c, + options.enable_minification, + ) + }; + let write_toolchain = + |p: &_, c: &_| cx.write_shared(SharedResource::ToolchainSpecific { basename: p }, c); + // Add all the static files. These may already exist, but we just // overwrite them anyway to make sure that they're fresh and up-to-date. - - write_minify( - &cx.shared.fs, - cx.path("rustdoc.css"), - static_files::RUSTDOC_CSS, - options.enable_minification, - )?; - write_minify( - &cx.shared.fs, - cx.path("settings.css"), - static_files::SETTINGS_CSS, - options.enable_minification, - )?; - write_minify( - &cx.shared.fs, - cx.path("noscript.css"), - static_files::NOSCRIPT_CSS, - options.enable_minification, - )?; + write_minify("rustdoc.css", static_files::RUSTDOC_CSS)?; + write_minify("settings.css", static_files::SETTINGS_CSS)?; + write_minify("noscript.css", static_files::NOSCRIPT_CSS)?; // To avoid "light.css" to be overwritten, we'll first run over the received themes and only // then we'll run over the "official" styles. @@ -85,106 +155,66 @@ pub(super) fn write_shared( // Handle the official themes match theme { - "light" => write_minify( - &cx.shared.fs, - cx.path("light.css"), - static_files::themes::LIGHT, - options.enable_minification, - )?, - "dark" => write_minify( - &cx.shared.fs, - cx.path("dark.css"), - static_files::themes::DARK, - options.enable_minification, - )?, - "ayu" => write_minify( - &cx.shared.fs, - cx.path("ayu.css"), - static_files::themes::AYU, - options.enable_minification, - )?, + "light" => write_minify("light.css", static_files::themes::LIGHT)?, + "dark" => write_minify("dark.css", static_files::themes::DARK)?, + "ayu" => write_minify("ayu.css", static_files::themes::AYU)?, _ => { // Handle added third-party themes let content = try_err!(fs::read(&entry.path), &entry.path); - cx.shared - .fs - .write(cx.path(&format!("{}.{}", theme, extension)), content.as_slice())?; + // This is not exactly right: if compiled a second time with the same toolchain but different CLI args, the file could be different. + // But docs.rs doesn't use this, so hopefully the issue doesn't come up. + write_toolchain(&format!("{}.{}", theme, extension), content.as_slice())?; } }; themes.insert(theme.to_owned()); } - let write = |p, c| cx.shared.fs.write(p, c); if (*cx.shared).layout.logo.is_empty() { - write(cx.path("rust-logo.png"), static_files::RUST_LOGO)?; + write_toolchain("rust-logo.png", static_files::RUST_LOGO)?; } if (*cx.shared).layout.favicon.is_empty() { - write(cx.path("favicon.svg"), static_files::RUST_FAVICON_SVG)?; - write(cx.path("favicon-16x16.png"), static_files::RUST_FAVICON_PNG_16)?; - write(cx.path("favicon-32x32.png"), static_files::RUST_FAVICON_PNG_32)?; + write_toolchain("favicon.svg", static_files::RUST_FAVICON_SVG)?; + write_toolchain("favicon-16x16.png", static_files::RUST_FAVICON_PNG_16)?; + write_toolchain("favicon-32x32.png", static_files::RUST_FAVICON_PNG_32)?; } - write(cx.path("brush.svg"), static_files::BRUSH_SVG)?; - write(cx.path("wheel.svg"), static_files::WHEEL_SVG)?; - write(cx.path("down-arrow.svg"), static_files::DOWN_ARROW_SVG)?; + write_toolchain("brush.svg", static_files::BRUSH_SVG)?; + write_toolchain("wheel.svg", static_files::WHEEL_SVG)?; + write_toolchain("down-arrow.svg", static_files::DOWN_ARROW_SVG)?; let mut themes: Vec<&String> = themes.iter().collect(); themes.sort(); write_minify( - &cx.shared.fs, - cx.path("main.js"), + "main.js", &static_files::MAIN_JS.replace( "/* INSERT THEMES HERE */", &format!(" = {}", serde_json::to_string(&themes).unwrap()), ), - options.enable_minification, - )?; - write_minify( - &cx.shared.fs, - cx.path("settings.js"), - static_files::SETTINGS_JS, - options.enable_minification, )?; + write_minify("settings.js", static_files::SETTINGS_JS)?; if cx.shared.include_sources { - write_minify( - &cx.shared.fs, - cx.path("source-script.js"), - static_files::sidebar::SOURCE_SCRIPT, - options.enable_minification, - )?; + write_minify("source-script.js", static_files::sidebar::SOURCE_SCRIPT)?; } { write_minify( - &cx.shared.fs, - cx.path("storage.js"), + "storage.js", &format!( "var resourcesSuffix = \"{}\";{}", cx.shared.resource_suffix, static_files::STORAGE_JS ), - options.enable_minification, )?; } if let Some(ref css) = cx.shared.layout.css_file_extension { - let out = cx.path("theme.css"); let buffer = try_err!(fs::read_to_string(css), css); - if !options.enable_minification { - cx.shared.fs.write(&out, &buffer)?; - } else { - write_minify(&cx.shared.fs, out, &buffer, options.enable_minification)?; - } + write_minify("theme.css", &buffer)?; } - write_minify( - &cx.shared.fs, - cx.path("normalize.css"), - static_files::NORMALIZE_CSS, - options.enable_minification, - )?; - for (file, contents) in &*FILES_UNVERSIONED { - write(cx.dst.join(file), contents)?; + write_minify("normalize.css", static_files::NORMALIZE_CSS)?; + for (name, contents) in &*FILES_UNVERSIONED { + cx.write_shared(SharedResource::Unversioned { name }, contents)?; } fn collect(path: &Path, krate: &str, key: &str) -> io::Result<(Vec, Vec)> { @@ -324,7 +354,7 @@ pub(super) fn write_shared( "var N = null;var sourcesIndex = {{}};\n{}\ncreateSourceSidebar();\n", all_sources.join("\n") ); - cx.shared.fs.write(&dst, v.as_bytes())?; + cx.write_shared(SharedResource::CrateSpecific { basename: "source-files.js" }, v)?; } // Update the search index and crate list. @@ -341,13 +371,12 @@ pub(super) fn write_shared( let mut v = String::from("var searchIndex = JSON.parse('{\\\n"); v.push_str(&all_indexes.join(",\\\n")); v.push_str("\\\n}');\ninitSearch(searchIndex);"); - cx.shared.fs.write(&dst, &v)?; + cx.write_shared(SharedResource::CrateSpecific { basename: "search-index.js" }, v)?; } - let crate_list_dst = cx.dst.join(&format!("crates{}.js", cx.shared.resource_suffix)); let crate_list = format!("window.ALL_CRATES = [{}];", krates.iter().map(|k| format!("\"{}\"", k)).join(",")); - cx.shared.fs.write(&crate_list_dst, &crate_list)?; + cx.write_shared(SharedResource::CrateSpecific { basename: "crates.js" }, crate_list)?; if options.enable_index_page { if let Some(index_page) = options.index_page.clone() { @@ -481,21 +510,3 @@ pub(super) fn write_shared( } Ok(()) } - -fn write_minify( - fs: &DocFS, - dst: PathBuf, - contents: &str, - enable_minification: bool, -) -> Result<(), Error> { - if enable_minification { - if dst.extension() == Some(&OsStr::new("css")) { - let res = try_none!(minifier::css::minify(contents).ok(), &dst); - fs.write(dst, res.as_bytes()) - } else { - fs.write(dst, minifier::js::minify(contents).as_bytes()) - } - } else { - fs.write(dst, contents.as_bytes()) - } -} From fe60f19f7e98af78526364563fa6b40825fa97a8 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 1 Mar 2021 16:02:09 -0500 Subject: [PATCH 105/370] Ban custom inner attributes in expressions and statements --- compiler/rustc_expand/src/expand.rs | 20 +- compiler/rustc_resolve/src/macros.rs | 21 +- src/test/ui/proc-macro/inner-attrs.rs | 21 +- src/test/ui/proc-macro/inner-attrs.stderr | 32 +++ src/test/ui/proc-macro/inner-attrs.stdout | 314 ++++++++++++---------- 5 files changed, 246 insertions(+), 162 deletions(-) create mode 100644 src/test/ui/proc-macro/inner-attrs.stderr diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 2674ccced6f..470788a972a 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -206,30 +206,36 @@ ast_fragments! { } } +pub enum SupportsMacroExpansion { + No, + Yes { supports_inner_attrs: bool }, +} + impl AstFragmentKind { crate fn dummy(self, span: Span) -> AstFragment { self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment") } - /// Fragment supports macro expansion and not just inert attributes, `cfg` and `cfg_attr`. - pub fn supports_macro_expansion(self) -> bool { + pub fn supports_macro_expansion(self) -> SupportsMacroExpansion { match self { AstFragmentKind::OptExpr | AstFragmentKind::Expr - | AstFragmentKind::Pat - | AstFragmentKind::Ty | AstFragmentKind::Stmts - | AstFragmentKind::Items + | AstFragmentKind::Ty + | AstFragmentKind::Pat => SupportsMacroExpansion::Yes { supports_inner_attrs: false }, + AstFragmentKind::Items | AstFragmentKind::TraitItems | AstFragmentKind::ImplItems - | AstFragmentKind::ForeignItems => true, + | AstFragmentKind::ForeignItems => { + SupportsMacroExpansion::Yes { supports_inner_attrs: true } + } AstFragmentKind::Arms | AstFragmentKind::Fields | AstFragmentKind::FieldPats | AstFragmentKind::GenericParams | AstFragmentKind::Params | AstFragmentKind::StructFields - | AstFragmentKind::Variants => false, + | AstFragmentKind::Variants => SupportsMacroExpansion::No, } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 2e47d4cecee..2efce1e1984 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -17,7 +17,7 @@ use rustc_errors::struct_span_err; use rustc_expand::base::Annotatable; use rustc_expand::base::{Indeterminate, ResolverExpand, SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::compile_declarative_macro; -use rustc_expand::expand::{AstFragment, Invocation, InvocationKind}; +use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion}; use rustc_feature::is_builtin_attr_name; use rustc_hir::def::{self, DefKind, NonMacroAttrKind}; use rustc_hir::def_id; @@ -278,12 +278,12 @@ impl<'a> ResolverExpand for Resolver<'a> { // Derives are not included when `invocations` are collected, so we have to add them here. let parent_scope = &ParentScope { derives, ..parent_scope }; - let require_inert = !invoc.fragment_kind.supports_macro_expansion(); + let supports_macro_expansion = invoc.fragment_kind.supports_macro_expansion(); let node_id = self.lint_node_id(eager_expansion_root); let (ext, res) = self.smart_resolve_macro_path( path, kind, - require_inert, + supports_macro_expansion, inner_attr, parent_scope, node_id, @@ -457,7 +457,7 @@ impl<'a> Resolver<'a> { &mut self, path: &ast::Path, kind: MacroKind, - require_inert: bool, + supports_macro_expansion: SupportsMacroExpansion, inner_attr: bool, parent_scope: &ParentScope<'a>, node_id: NodeId, @@ -505,8 +505,17 @@ impl<'a> Resolver<'a> { let unexpected_res = if ext.macro_kind() != kind { Some((kind.article(), kind.descr_expected())) - } else if require_inert && matches!(res, Res::Def(..)) { - Some(("a", "non-macro attribute")) + } else if matches!(res, Res::Def(..)) { + match supports_macro_expansion { + SupportsMacroExpansion::No => Some(("a", "non-macro attribute")), + SupportsMacroExpansion::Yes { supports_inner_attrs } => { + if inner_attr && !supports_inner_attrs { + Some(("a", "non-macro inner attribute")) + } else { + None + } + } + } } else { None }; diff --git a/src/test/ui/proc-macro/inner-attrs.rs b/src/test/ui/proc-macro/inner-attrs.rs index 6a353ca3263..5707621f80e 100644 --- a/src/test/ui/proc-macro/inner-attrs.rs +++ b/src/test/ui/proc-macro/inner-attrs.rs @@ -1,10 +1,10 @@ -// check-pass // compile-flags: -Z span-debug --error-format human // aux-build:test-macros.rs #![feature(custom_inner_attributes)] #![feature(proc_macro_hygiene)] #![feature(stmt_expr_attributes)] +#![feature(rustc_attrs)] #![no_std] // Don't load unnecessary hygiene information from std extern crate std; @@ -25,17 +25,34 @@ struct MyStruct { fn bar() { (#![print_target_and_args(fifth)] 1, 2); + //~^ ERROR expected non-macro inner attribute, found attribute macro + + #[print_target_and_args(tuple_attrs)] ( + #![cfg_attr(FALSE, rustc_dummy)] + 3, 4, { + #![cfg_attr(not(FALSE), rustc_dummy(innermost))] + 5 + } + ); + + #[print_target_and_args(array_attrs)] [ + #![rustc_dummy(inner)] + true; 0 + ]; [#![print_target_and_args(sixth)] 1 , 2]; + //~^ ERROR expected non-macro inner attribute, found attribute macro [#![print_target_and_args(seventh)] true ; 5]; - + //~^ ERROR expected non-macro inner attribute, found attribute macro match 0 { #![print_target_and_args(eighth)] + //~^ ERROR expected non-macro inner attribute, found attribute macro _ => {} } MyStruct { #![print_target_and_args(ninth)] field: true }; + //~^ ERROR expected non-macro inner attribute, found attribute macro } extern { diff --git a/src/test/ui/proc-macro/inner-attrs.stderr b/src/test/ui/proc-macro/inner-attrs.stderr new file mode 100644 index 00000000000..db774cbfb8f --- /dev/null +++ b/src/test/ui/proc-macro/inner-attrs.stderr @@ -0,0 +1,32 @@ +error: expected non-macro inner attribute, found attribute macro `print_target_and_args` + --> $DIR/inner-attrs.rs:27:9 + | +LL | (#![print_target_and_args(fifth)] 1, 2); + | ^^^^^^^^^^^^^^^^^^^^^ not a non-macro inner attribute + +error: expected non-macro inner attribute, found attribute macro `print_target_and_args` + --> $DIR/inner-attrs.rs:43:9 + | +LL | [#![print_target_and_args(sixth)] 1 , 2]; + | ^^^^^^^^^^^^^^^^^^^^^ not a non-macro inner attribute + +error: expected non-macro inner attribute, found attribute macro `print_target_and_args` + --> $DIR/inner-attrs.rs:45:9 + | +LL | [#![print_target_and_args(seventh)] true ; 5]; + | ^^^^^^^^^^^^^^^^^^^^^ not a non-macro inner attribute + +error: expected non-macro inner attribute, found attribute macro `print_target_and_args` + --> $DIR/inner-attrs.rs:49:12 + | +LL | #![print_target_and_args(eighth)] + | ^^^^^^^^^^^^^^^^^^^^^ not a non-macro inner attribute + +error: expected non-macro inner attribute, found attribute macro `print_target_and_args` + --> $DIR/inner-attrs.rs:54:19 + | +LL | MyStruct { #![print_target_and_args(ninth)] field: true }; + | ^^^^^^^^^^^^^^^^^^^^^ not a non-macro inner attribute + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/proc-macro/inner-attrs.stdout b/src/test/ui/proc-macro/inner-attrs.stdout index 2fd8d8a242e..ae04544e533 100644 --- a/src/test/ui/proc-macro/inner-attrs.stdout +++ b/src/test/ui/proc-macro/inner-attrs.stdout @@ -290,231 +290,251 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ span: $DIR/inner-attrs.rs:17:1: 20:2 (#0), }, ] -PRINT-ATTR_ARGS INPUT (DISPLAY): fifth +PRINT-ATTR_ARGS INPUT (DISPLAY): tuple_attrs PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ Ident { - ident: "fifth", - span: $DIR/inner-attrs.rs:27:31: 27:36 (#0), + ident: "tuple_attrs", + span: $DIR/inner-attrs.rs:30:29: 30:40 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): (1, 2) ; +PRINT-ATTR INPUT (DISPLAY): (# ! [cfg_attr(FALSE, rustc_dummy)] 3, 4, + { # ! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Group { delimiter: Parenthesis, stream: TokenStream [ + Punct { + ch: '#', + spacing: Joint, + span: $DIR/inner-attrs.rs:31:9: 31:10 (#0), + }, + Punct { + ch: '!', + spacing: Alone, + span: $DIR/inner-attrs.rs:31:10: 31:11 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "cfg_attr", + span: $DIR/inner-attrs.rs:31:12: 31:20 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "FALSE", + span: $DIR/inner-attrs.rs:31:21: 31:26 (#0), + }, + Punct { + ch: ',', + spacing: Alone, + span: $DIR/inner-attrs.rs:31:26: 31:27 (#0), + }, + Ident { + ident: "rustc_dummy", + span: $DIR/inner-attrs.rs:31:28: 31:39 (#0), + }, + ], + span: $DIR/inner-attrs.rs:31:20: 31:40 (#0), + }, + ], + span: $DIR/inner-attrs.rs:31:11: 31:41 (#0), + }, Literal { kind: Integer, - symbol: "1", + symbol: "3", suffix: None, - span: $DIR/inner-attrs.rs:27:5: 27:45 (#0), + span: $DIR/inner-attrs.rs:32:9: 32:10 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/inner-attrs.rs:27:5: 27:45 (#0), + span: $DIR/inner-attrs.rs:32:10: 32:11 (#0), }, Literal { kind: Integer, - symbol: "2", + symbol: "4", suffix: None, - span: $DIR/inner-attrs.rs:27:5: 27:45 (#0), - }, - ], - span: $DIR/inner-attrs.rs:27:5: 27:45 (#0), - }, - Punct { - ch: ';', - spacing: Alone, - span: $DIR/inner-attrs.rs:27:5: 27:45 (#0), - }, -] -PRINT-ATTR_ARGS INPUT (DISPLAY): sixth -PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ - Ident { - ident: "sixth", - span: $DIR/inner-attrs.rs:29:31: 29:36 (#0), - }, -] -PRINT-ATTR INPUT (DISPLAY): [1, 2] ; -PRINT-ATTR INPUT (DEBUG): TokenStream [ - Group { - delimiter: Bracket, - stream: TokenStream [ - Literal { - kind: Integer, - symbol: "1", - suffix: None, - span: $DIR/inner-attrs.rs:29:5: 29:46 (#0), + span: $DIR/inner-attrs.rs:32:12: 32:13 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/inner-attrs.rs:29:5: 29:46 (#0), + span: $DIR/inner-attrs.rs:32:13: 32:14 (#0), }, - Literal { - kind: Integer, - symbol: "2", - suffix: None, - span: $DIR/inner-attrs.rs:29:5: 29:46 (#0), + Group { + delimiter: Brace, + stream: TokenStream [ + Punct { + ch: '#', + spacing: Joint, + span: $DIR/inner-attrs.rs:33:13: 33:14 (#0), + }, + Punct { + ch: '!', + spacing: Alone, + span: $DIR/inner-attrs.rs:33:14: 33:15 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "cfg_attr", + span: $DIR/inner-attrs.rs:33:16: 33:24 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "not", + span: $DIR/inner-attrs.rs:33:25: 33:28 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "FALSE", + span: $DIR/inner-attrs.rs:33:29: 33:34 (#0), + }, + ], + span: $DIR/inner-attrs.rs:33:28: 33:35 (#0), + }, + Punct { + ch: ',', + spacing: Alone, + span: $DIR/inner-attrs.rs:33:35: 33:36 (#0), + }, + Ident { + ident: "rustc_dummy", + span: $DIR/inner-attrs.rs:33:37: 33:48 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "innermost", + span: $DIR/inner-attrs.rs:33:49: 33:58 (#0), + }, + ], + span: $DIR/inner-attrs.rs:33:48: 33:59 (#0), + }, + ], + span: $DIR/inner-attrs.rs:33:24: 33:60 (#0), + }, + ], + span: $DIR/inner-attrs.rs:33:15: 33:61 (#0), + }, + Literal { + kind: Integer, + symbol: "5", + suffix: None, + span: $DIR/inner-attrs.rs:34:13: 34:14 (#0), + }, + ], + span: $DIR/inner-attrs.rs:32:15: 35:10 (#0), }, ], - span: $DIR/inner-attrs.rs:29:5: 29:46 (#0), + span: $DIR/inner-attrs.rs:30:43: 36:6 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/inner-attrs.rs:29:5: 29:46 (#0), + span: $DIR/inner-attrs.rs:36:6: 36:7 (#0), }, ] -PRINT-ATTR_ARGS INPUT (DISPLAY): seventh +PRINT-ATTR_ARGS INPUT (DISPLAY): array_attrs PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ Ident { - ident: "seventh", - span: $DIR/inner-attrs.rs:30:31: 30:38 (#0), + ident: "array_attrs", + span: $DIR/inner-attrs.rs:38:29: 38:40 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): [true ; 5] ; +PRINT-ATTR INPUT (DISPLAY): [# ! [rustc_dummy(inner)] true ; 0] ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Group { delimiter: Bracket, stream: TokenStream [ + Punct { + ch: '#', + spacing: Joint, + span: $DIR/inner-attrs.rs:38:43: 41:7 (#0), + }, + Punct { + ch: '!', + spacing: Alone, + span: $DIR/inner-attrs.rs:38:43: 41:7 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "rustc_dummy", + span: $DIR/inner-attrs.rs:38:43: 41:7 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "inner", + span: $DIR/inner-attrs.rs:38:43: 41:7 (#0), + }, + ], + span: $DIR/inner-attrs.rs:38:43: 41:7 (#0), + }, + ], + span: $DIR/inner-attrs.rs:38:43: 41:7 (#0), + }, Ident { ident: "true", - span: $DIR/inner-attrs.rs:30:5: 30:51 (#0), + span: $DIR/inner-attrs.rs:38:43: 41:7 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/inner-attrs.rs:30:5: 30:51 (#0), + span: $DIR/inner-attrs.rs:38:43: 41:7 (#0), }, Literal { kind: Integer, - symbol: "5", + symbol: "0", suffix: None, - span: $DIR/inner-attrs.rs:30:5: 30:51 (#0), + span: $DIR/inner-attrs.rs:38:43: 41:7 (#0), }, ], - span: $DIR/inner-attrs.rs:30:5: 30:51 (#0), + span: $DIR/inner-attrs.rs:38:43: 41:7 (#0), }, Punct { ch: ';', spacing: Alone, - span: $DIR/inner-attrs.rs:30:5: 30:51 (#0), - }, -] -PRINT-ATTR_ARGS INPUT (DISPLAY): eighth -PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ - Ident { - ident: "eighth", - span: $DIR/inner-attrs.rs:34:34: 34:40 (#0), - }, -] -PRINT-ATTR INPUT (DISPLAY): match 0 { _ => { } } -PRINT-ATTR INPUT (DEBUG): TokenStream [ - Ident { - ident: "match", - span: $DIR/inner-attrs.rs:33:5: 36:6 (#0), - }, - Literal { - kind: Integer, - symbol: "0", - suffix: None, - span: $DIR/inner-attrs.rs:33:5: 36:6 (#0), - }, - Group { - delimiter: Brace, - stream: TokenStream [ - Ident { - ident: "_", - span: $DIR/inner-attrs.rs:33:5: 36:6 (#0), - }, - Punct { - ch: '=', - spacing: Joint, - span: $DIR/inner-attrs.rs:33:5: 36:6 (#0), - }, - Punct { - ch: '>', - spacing: Alone, - span: $DIR/inner-attrs.rs:33:5: 36:6 (#0), - }, - Group { - delimiter: Brace, - stream: TokenStream [], - span: $DIR/inner-attrs.rs:33:5: 36:6 (#0), - }, - ], - span: $DIR/inner-attrs.rs:33:5: 36:6 (#0), - }, -] -PRINT-ATTR_ARGS INPUT (DISPLAY): ninth -PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ - Ident { - ident: "ninth", - span: $DIR/inner-attrs.rs:38:41: 38:46 (#0), - }, -] -PRINT-ATTR INPUT (DISPLAY): MyStruct { field : true, } ; -PRINT-ATTR INPUT (DEBUG): TokenStream [ - Ident { - ident: "MyStruct", - span: $DIR/inner-attrs.rs:38:5: 38:63 (#0), - }, - Group { - delimiter: Brace, - stream: TokenStream [ - Ident { - ident: "field", - span: $DIR/inner-attrs.rs:38:5: 38:63 (#0), - }, - Punct { - ch: ':', - spacing: Alone, - span: $DIR/inner-attrs.rs:38:5: 38:63 (#0), - }, - Ident { - ident: "true", - span: $DIR/inner-attrs.rs:38:5: 38:63 (#0), - }, - Punct { - ch: ',', - spacing: Alone, - span: $DIR/inner-attrs.rs:38:5: 38:63 (#0), - }, - ], - span: $DIR/inner-attrs.rs:38:5: 38:63 (#0), - }, - Punct { - ch: ';', - spacing: Alone, - span: $DIR/inner-attrs.rs:38:5: 38:63 (#0), + span: $DIR/inner-attrs.rs:38:43: 41:7 (#0), }, ] PRINT-ATTR_ARGS INPUT (DISPLAY): tenth PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ Ident { ident: "tenth", - span: $DIR/inner-attrs.rs:43:42: 43:47 (#0), + span: $DIR/inner-attrs.rs:60:42: 60:47 (#0), }, ] PRINT-ATTR INPUT (DISPLAY): fn weird_extern() { } PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "fn", - span: $DIR/inner-attrs.rs:42:5: 44:6 (#0), + span: $DIR/inner-attrs.rs:59:5: 61:6 (#0), }, Ident { ident: "weird_extern", - span: $DIR/inner-attrs.rs:42:5: 44:6 (#0), + span: $DIR/inner-attrs.rs:59:5: 61:6 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [], - span: $DIR/inner-attrs.rs:42:5: 44:6 (#0), + span: $DIR/inner-attrs.rs:59:5: 61:6 (#0), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/inner-attrs.rs:42:5: 44:6 (#0), + span: $DIR/inner-attrs.rs:59:5: 61:6 (#0), }, ] From 7504b9bb96236a340c41c95f95cf3c4a09341afc Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 25 Mar 2021 18:05:49 -0400 Subject: [PATCH 106/370] Avoid double-collection for expression nonterminals --- compiler/rustc_parse/src/parser/expr.rs | 15 +++++++++++++++ compiler/rustc_parse/src/parser/mod.rs | 2 +- compiler/rustc_parse/src/parser/nonterminal.rs | 17 +---------------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index d64e5173b92..fe190bfe9d9 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -92,6 +92,21 @@ impl<'a> Parser<'a> { self.parse_expr_res(Restrictions::empty(), None) } + /// Parses an expression, forcing tokens to be collected + pub fn parse_expr_force_collect(&mut self) -> PResult<'a, P> { + // If we have outer attributes, then the call to `collect_tokens_trailing_token` + // will be made for us. + if matches!(self.token.kind, TokenKind::Pound | TokenKind::DocComment(..)) { + self.parse_expr() + } else { + // If we don't have outer attributes, then we need to ensure + // that collection happens by using `collect_tokens_no_attrs`. + // Expression don't support custom inner attributes, so `parse_expr` + // will never try to collect tokens if we don't have outer attributes. + self.collect_tokens_no_attrs(|this| this.parse_expr()) + } + } + pub(super) fn parse_anon_const_expr(&mut self) -> PResult<'a, AnonConst> { self.parse_expr().map(|value| AnonConst { id: DUMMY_NODE_ID, value }) } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 71103840f13..f0ee76d328c 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -987,7 +987,7 @@ impl<'a> Parser<'a> { } // Collect tokens because they are used during lowering to HIR. - let expr = self.collect_tokens_no_attrs(|this| this.parse_expr())?; + let expr = self.parse_expr_force_collect()?; let span = expr.span; match &expr.kind { diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index fc25e883666..0c49d103583 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -128,22 +128,7 @@ impl<'a> Parser<'a> { })?) } - // If there are attributes present, then `parse_expr` will end up collecting tokens, - // turning the outer `collect_tokens_no_attrs` into a no-op due to the already present - // tokens. If there are *not* attributes present, then the outer - // `collect_tokens_no_attrs` will ensure that we will end up collecting tokens for the - // expressions. - // - // This is less efficient than it could be, since the outer `collect_tokens_no_attrs` - // still needs to snapshot the `TokenCursor` before calling `parse_expr`, even when - // `parse_expr` will end up collecting tokens. Ideally, this would work more like - // `parse_item`, and take in a `ForceCollect` parameter. However, this would require - // adding a `ForceCollect` parameter in a bunch of places in expression parsing - // for little gain. If the perf impact from this turns out to be noticeable, we should - // revisit this apporach. - NonterminalKind::Expr => { - token::NtExpr(self.collect_tokens_no_attrs(|this| this.parse_expr())?) - } + NonterminalKind::Expr => token::NtExpr(self.parse_expr_force_collect()?), NonterminalKind::Literal => { // The `:literal` matcher does not support attributes token::NtLiteral( From f77ebd4ffaea7fc5af49425cafefe141e7458cc3 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 25 Mar 2021 12:46:35 -0400 Subject: [PATCH 107/370] Add unstable option to only emit shared/crate-specific files The intended use case is for docs.rs, which can now copy exactly the files it cares about, rather than having to guess based on whether they have a resource suffix or not. In particular, some files have a resource suffix but cannot be shared between crates: https://github.com/rust-lang/docs.rs/pull/1312#issuecomment-798783688 The end goal is to fix https://github.com/rust-lang/docs.rs/issues/1327 by reverting https://github.com/rust-lang/docs.rs/pull/1324. This obsoletes `--print=unversioned-files`, which I plan to remove as soon as docs.rs stops using it. --- src/librustdoc/config.rs | 43 ++++++++++++++++++ src/librustdoc/formats/renderer.rs | 5 +++ src/librustdoc/html/render/context.rs | 5 ++- src/librustdoc/html/render/write_shared.rs | 47 +++++++++++++++----- src/librustdoc/lib.rs | 8 ++++ src/test/run-make/emit-shared-files/Makefile | 32 +++++++++++++ src/test/run-make/emit-shared-files/x.rs | 1 + 7 files changed, 129 insertions(+), 12 deletions(-) create mode 100644 src/test/run-make/emit-shared-files/Makefile create mode 100644 src/test/run-make/emit-shared-files/x.rs diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index ecb6378f31f..a7a2db62100 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -3,6 +3,7 @@ use std::convert::TryFrom; use std::ffi::OsStr; use std::fmt; use std::path::PathBuf; +use std::str::FromStr; use rustc_data_structures::fx::FxHashMap; use rustc_session::config::{self, parse_crate_types_from_list, parse_externs, CrateType}; @@ -266,6 +267,34 @@ crate struct RenderOptions { /// If `true`, generate a JSON file in the crate folder instead of HTML redirection files. crate generate_redirect_map: bool, crate unstable_features: rustc_feature::UnstableFeatures, + crate emit: Vec, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +crate enum EmitType { + Unversioned, + Toolchain, + CrateSpecific, +} + +impl FromStr for EmitType { + type Err = (); + + fn from_str(s: &str) -> Result { + use EmitType::*; + match s { + "unversioned-shared-resources" => Ok(Unversioned), + "toolchain-shared-resources" => Ok(Toolchain), + "crate-specific" => Ok(CrateSpecific), + _ => Err(()), + } + } +} + +impl RenderOptions { + crate fn should_emit_crate(&self) -> bool { + self.emit.is_empty() || self.emit.contains(&EmitType::CrateSpecific) + } } impl Options { @@ -334,6 +363,19 @@ impl Options { // check for deprecated options check_deprecated_options(&matches, &diag); + let mut emit = Vec::new(); + for list in matches.opt_strs("emit") { + for kind in list.split(',') { + match kind.parse() { + Ok(kind) => emit.push(kind), + Err(()) => { + diag.err(&format!("unrecognized emission type: {}", kind)); + return Err(1); + } + } + } + } + let to_check = matches.opt_strs("check-theme"); if !to_check.is_empty() { let paths = theme::load_css_paths(static_files::themes::LIGHT.as_bytes()); @@ -641,6 +683,7 @@ impl Options { unstable_features: rustc_feature::UnstableFeatures::from_environment( crate_name.as_deref(), ), + emit, }, crate_name, output_format, diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index 9dcef3a20d6..f0b390add73 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -58,10 +58,15 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>( ) -> Result<(), Error> { let prof = &tcx.sess.prof; + let emit_crate = options.should_emit_crate(); let (mut format_renderer, krate) = prof .extra_verbose_generic_activity("create_renderer", T::descr()) .run(|| T::init(krate, options, edition, cache, tcx))?; + if !emit_crate { + return Ok(()); + } + // Render the crate documentation let crate_name = krate.name; let mut work = vec![(format_renderer.make_child_renderer(), krate.module)]; diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 468bd9997a6..17cedeb5a51 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -288,6 +288,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { ) -> Result<(Self, clean::Crate), Error> { // need to save a copy of the options for rendering the index page let md_opts = options.clone(); + let emit_crate = options.should_emit_crate(); let RenderOptions { output, external_html, @@ -393,7 +394,9 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { let dst = output; scx.ensure_dir(&dst)?; - krate = sources::render(&dst, &mut scx, krate)?; + if emit_crate { + krate = sources::render(&dst, &mut scx, krate)?; + } // Build our search index let index = build_index(&krate, &mut cache, tcx); diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 2ab423c238c..af346bb8225 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -13,7 +13,7 @@ use serde::Serialize; use super::{collect_paths_for_type, ensure_trailing_slash, Context, BASIC_KEYWORDS}; use crate::clean::Crate; -use crate::config::RenderOptions; +use crate::config::{EmitType, RenderOptions}; use crate::docfs::PathError; use crate::error::Error; use crate::formats::FormatRenderer; @@ -72,6 +72,18 @@ impl SharedResource<'_> { SharedResource::CrateSpecific { basename } => cx.suffix_path(basename), } } + + fn should_emit(&self, emit: &[EmitType]) -> bool { + if emit.is_empty() { + return true; + } + let kind = match self { + SharedResource::Unversioned { .. } => EmitType::Unversioned, + SharedResource::ToolchainSpecific { .. } => EmitType::Toolchain, + SharedResource::CrateSpecific { .. } => EmitType::CrateSpecific, + }; + emit.contains(&kind) + } } impl Context<'_> { @@ -86,9 +98,17 @@ impl Context<'_> { self.dst.join(&filename) } - fn write_shared>(&self, resource: SharedResource<'_>, contents: C) -> Result<(), Error> - { - self.shared.fs.write(resource.path(self), contents) + fn write_shared>( + &self, + resource: SharedResource<'_>, + contents: C, + emit: &[EmitType], + ) -> Result<(), Error> { + if resource.should_emit(emit) { + self.shared.fs.write(resource.path(self), contents) + } else { + Ok(()) + } } fn write_minify( @@ -96,6 +116,7 @@ impl Context<'_> { resource: SharedResource<'_>, contents: &str, minify: bool, + emit: &[EmitType], ) -> Result<(), Error> { let tmp; let contents = if minify { @@ -111,7 +132,7 @@ impl Context<'_> { contents.as_bytes() }; - self.write_shared(resource, contents) + self.write_shared(resource, contents, emit) } } @@ -133,10 +154,14 @@ pub(super) fn write_shared( SharedResource::ToolchainSpecific { basename: p }, c, options.enable_minification, + &options.emit, ) }; - let write_toolchain = - |p: &_, c: &_| cx.write_shared(SharedResource::ToolchainSpecific { basename: p }, c); + let write_toolchain = |p: &_, c: &_| { + cx.write_shared(SharedResource::ToolchainSpecific { basename: p }, c, &options.emit) + }; + let write_crate = + |p, c: &_| cx.write_shared(SharedResource::CrateSpecific { basename: p }, c, &options.emit); // Add all the static files. These may already exist, but we just // overwrite them anyway to make sure that they're fresh and up-to-date. @@ -214,7 +239,7 @@ pub(super) fn write_shared( } write_minify("normalize.css", static_files::NORMALIZE_CSS)?; for (name, contents) in &*FILES_UNVERSIONED { - cx.write_shared(SharedResource::Unversioned { name }, contents)?; + cx.write_shared(SharedResource::Unversioned { name }, contents, &options.emit)?; } fn collect(path: &Path, krate: &str, key: &str) -> io::Result<(Vec, Vec)> { @@ -354,7 +379,7 @@ pub(super) fn write_shared( "var N = null;var sourcesIndex = {{}};\n{}\ncreateSourceSidebar();\n", all_sources.join("\n") ); - cx.write_shared(SharedResource::CrateSpecific { basename: "source-files.js" }, v)?; + write_crate("source-files.js", &v)?; } // Update the search index and crate list. @@ -371,12 +396,12 @@ pub(super) fn write_shared( let mut v = String::from("var searchIndex = JSON.parse('{\\\n"); v.push_str(&all_indexes.join(",\\\n")); v.push_str("\\\n}');\ninitSearch(searchIndex);"); - cx.write_shared(SharedResource::CrateSpecific { basename: "search-index.js" }, v)?; + write_crate("search-index.js", &v)?; } let crate_list = format!("window.ALL_CRATES = [{}];", krates.iter().map(|k| format!("\"{}\"", k)).join(",")); - cx.write_shared(SharedResource::CrateSpecific { basename: "crates.js" }, crate_list)?; + write_crate("crates.js", &crate_list)?; if options.enable_index_page { if let Some(index_page) = options.index_page.clone() { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index dabc21e3a44..ebdd56611db 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -527,6 +527,14 @@ fn opts() -> Vec { unstable("print", |o| { o.optmulti("", "print", "Rustdoc information to print on stdout", "[unversioned-files]") }), + unstable("emit", |o| { + o.optmulti( + "", + "emit", + "Comma separated list of types of output for rustdoc to emit", + "[unversioned-shared-resources,toolchain-shared-resources,crate-specific]", + ) + }), ] } diff --git a/src/test/run-make/emit-shared-files/Makefile b/src/test/run-make/emit-shared-files/Makefile new file mode 100644 index 00000000000..06358f6eb2c --- /dev/null +++ b/src/test/run-make/emit-shared-files/Makefile @@ -0,0 +1,32 @@ +-include ../../run-make-fulldeps/tools.mk + +CRATE_ONLY = $(TMPDIR)/crate-only +TOOLCHAIN_ONLY = $(TMPDIR)/toolchain-only +ALL_SHARED = $(TMPDIR)/all-shared + +all: crate-only toolchain-only all-shared + +crate-only: + $(RUSTDOC) -Z unstable-options --emit=crate-specific --output $(CRATE_ONLY) --resource-suffix=-xxx x.rs + [ -e $(CRATE_ONLY)/search-index-xxx.js ] + [ -e $(CRATE_ONLY)/settings.html ] + [ -e $(CRATE_ONLY)/x/all.html ] + [ -e $(CRATE_ONLY)/x/index.html ] + ! [ -e $(CRATE_ONLY)/storage-xxx.js ] + ! [ -e $(CRATE_ONLY)/SourceSerifPro-It.ttf.woff ] + +toolchain-only: + $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources --output $(TOOLCHAIN_ONLY) --resource-suffix=-xxx x.rs + [ -e $(TOOLCHAIN_ONLY)/storage-xxx.js ] + ! [ -e $(TOOLCHAIN_ONLY)/SourceSerifPro-It.ttf.woff ] + ! [ -e $(TOOLCHAIN_ONLY)/search-index-xxx.js ] + ! [ -e $(TOOLCHAIN_ONLY)/x/index.html ] + +all-shared: + $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources,unversioned-shared-resources --output $(ALL_SHARED) --resource-suffix=-xxx x.rs + [ -e $(ALL_SHARED)/storage-xxx.js ] + [ -e $(ALL_SHARED)/SourceSerifPro-It.ttf.woff ] + ! [ -e $(ALL_SHARED)/search-index-xxx.js ] + ! [ -e $(ALL_SHARED)/settings.html ] + ! [ -e $(ALL_SHARED)/x ] + ! [ -e $(ALL_SHARED)/src ] diff --git a/src/test/run-make/emit-shared-files/x.rs b/src/test/run-make/emit-shared-files/x.rs new file mode 100644 index 00000000000..5df7576133a --- /dev/null +++ b/src/test/run-make/emit-shared-files/x.rs @@ -0,0 +1 @@ +// nothing to see here From 5afb167bf5fda1dc4a1f1d0d96086c764242846b Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Thu, 25 Mar 2021 21:34:08 -0600 Subject: [PATCH 108/370] Update backtrace to 0.3.56 Fixes #78184 --- library/backtrace | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/backtrace b/library/backtrace index af078ecc0b0..710fc18ddcb 160000 --- a/library/backtrace +++ b/library/backtrace @@ -1 +1 @@ -Subproject commit af078ecc0b069ec594982f92d4c6c58af99efbb5 +Subproject commit 710fc18ddcb6c7677b3c96359abb35da37f2a488 From 4590d544cc1a2a3f36a09c2c5e75bba1ad97cfdf Mon Sep 17 00:00:00 2001 From: JohnTitor Date: Fri, 26 Mar 2021 14:32:19 +0900 Subject: [PATCH 109/370] Use the direct link to the platform support page --- RELEASES.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index dfb21ed8380..a994cc781ab 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -35,7 +35,7 @@ Compiler - [Added tier 3 support for `i386-unknown-linux-gnu` and `i486-unknown-linux-gnu` targets.][80662] - [The `target-cpu=native` option will now detect individual features of CPUs.][80749] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -183,7 +183,7 @@ Compiler - [The `x86_64-unknown-freebsd` is now built with the full toolset.][79484] - [Dropped support for all cloudabi targets.][78439] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -360,7 +360,7 @@ Compiler - [Output from threads spawned in tests is now captured.][78227] - [Change os and vendor values to "none" and "unknown" for some targets][78951] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -465,7 +465,7 @@ Compiler Note: If you're using cargo you must explicitly pass the `--target` flag. - [Added tier 2\* support for `aarch64-unknown-linux-musl`.][76420] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -604,7 +604,7 @@ Compiler - [Upgrade the FreeBSD toolchain to version 11.4][75204] - [`RUST_BACKTRACE`'s output is now more compact.][75048] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -889,7 +889,7 @@ Compiler - [Added tier 3 support for the `thumbv7a-uwp-windows-msvc` target.][72133] - [Upgraded to LLVM 10.][67759] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. @@ -1398,7 +1398,7 @@ Compiler pointing to the location where they were called, rather than `core`'s internals. ][67887] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -1496,7 +1496,7 @@ Compiler - [You can now provide `--extern` flag without a path, indicating that it is available from the search path or specified with an `-L` flag.][64882] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. [argfile-docs]: https://doc.rust-lang.org/nightly/rustc/command-line-arguments.html#path-load-command-line-flags-from-a-path @@ -1620,7 +1620,7 @@ Compiler - [Added tier 3 support for the `mips64-unknown-linux-muslabi64`, and `mips64el-unknown-linux-muslabi64` targets.][65843] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -1770,7 +1770,7 @@ Compiler output of successful tests.][62600] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -1864,7 +1864,7 @@ Compiler - [Added tier 3 support for the `riscv32i-unknown-none-elf` target.][62784] - [Upgraded to LLVM 9.][62592] -\* Refer to Rust's [platform support page][forge-platform-support] for more +\* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries @@ -1951,7 +1951,7 @@ Compatibility Notes [`Duration::mul_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f32 [`Duration::mul_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f64 [`any::type_name`]: https://doc.rust-lang.org/std/any/fn.type_name.html -[forge-platform-support]: https://forge.rust-lang.org/release/platform-support.html +[platform-support-doc]: https://doc.rust-lang.org/nightly/rustc/platform-support.html [pipeline-internals]: https://internals.rust-lang.org/t/evaluating-pipelined-rustc-compilation/10199 Version 1.37.0 (2019-08-15) From 09bab382910f8e32f6ee4a7aa90403ad99a26470 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 22 Mar 2021 18:09:33 +0100 Subject: [PATCH 110/370] Fix #83045 by moving some crate loading verification code to a better place. --- compiler/rustc_metadata/src/creader.rs | 11 +++++-- .../run-make-fulldeps/issue-83045/Makefile | 33 +++++++++++++++++++ src/test/run-make-fulldeps/issue-83045/a.rs | 1 + src/test/run-make-fulldeps/issue-83045/b.rs | 1 + src/test/run-make-fulldeps/issue-83045/c.rs | 1 + 5 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 src/test/run-make-fulldeps/issue-83045/Makefile create mode 100644 src/test/run-make-fulldeps/issue-83045/a.rs create mode 100644 src/test/run-make-fulldeps/issue-83045/b.rs create mode 100644 src/test/run-make-fulldeps/issue-83045/c.rs diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 9335384aa6c..9578f5d5863 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -350,7 +350,6 @@ impl<'a> CrateLoader<'a> { let Library { source, metadata } = lib; let crate_root = metadata.get_root(); let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash()); - self.verify_no_symbol_conflicts(&crate_root)?; let private_dep = self.sess.opts.externs.get(&name.as_str()).map_or(false, |e| e.is_private_dep); @@ -358,8 +357,6 @@ impl<'a> CrateLoader<'a> { // Claim this crate number and cache it let cnum = self.cstore.alloc_new_crate_num(); - self.verify_no_stable_crate_id_hash_conflicts(&crate_root, cnum)?; - info!( "register crate `{}` (cnum = {}. private_dep = {})", crate_root.name(), @@ -394,6 +391,14 @@ impl<'a> CrateLoader<'a> { None }; + // Perform some verification *after* resolve_crate_deps() above is + // known to have been successful. It seems that - in error cases - the + // cstore can be in a temporarily invalid state between cnum allocation + // and dependency resolution and the verification code would produce + // ICEs in that case (see #83045). + self.verify_no_symbol_conflicts(&crate_root)?; + self.verify_no_stable_crate_id_hash_conflicts(&crate_root, cnum)?; + let crate_metadata = CrateMetadata::new( self.sess, metadata, diff --git a/src/test/run-make-fulldeps/issue-83045/Makefile b/src/test/run-make-fulldeps/issue-83045/Makefile new file mode 100644 index 00000000000..34853cb1d31 --- /dev/null +++ b/src/test/run-make-fulldeps/issue-83045/Makefile @@ -0,0 +1,33 @@ +include ../../run-make-fulldeps/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 +# find the dependency of a direct dependency. +# +# The test case makes sure that the compiler produces the expected +# error message but does not ICE immediately after. +# +# See https://github.com/rust-lang/rust/issues/83045 + +# This is a platform-independent issue, no need to waste time testing +# everywhere. +# only-x86_64 +# only-linux + +# NOTE: We use BARE_RUSTC below so that the compiler can't find liba.rlib +# If we used RUSTC the additional '-L TMPDIR' option would allow rustc to +# actually find the crate. +# +# We check that we get the expected error message +# But that we do not get an ICE + +all: + $(RUSTC) --crate-name=a --crate-type=rlib a.rs --verbose + $(RUSTC) --crate-name=b --crate-type=rlib --extern a=$(TMPDIR)/liba.rlib b.rs --verbose + $(BARE_RUSTC) --out-dir $(TMPDIR) \ + --extern b=$(TMPDIR)/libb.rlib \ + --crate-type=rlib \ + --edition=2018 \ + c.rs 2>&1 | tee $(TMPDIR)/output.txt || exit 0 + $(CGREP) E0463 < $(TMPDIR)/output.txt + $(CGREP) -v "internal compiler error" < $(TMPDIR)/output.txt diff --git a/src/test/run-make-fulldeps/issue-83045/a.rs b/src/test/run-make-fulldeps/issue-83045/a.rs new file mode 100644 index 00000000000..66d9f758e9d --- /dev/null +++ b/src/test/run-make-fulldeps/issue-83045/a.rs @@ -0,0 +1 @@ +// empty on purpose diff --git a/src/test/run-make-fulldeps/issue-83045/b.rs b/src/test/run-make-fulldeps/issue-83045/b.rs new file mode 100644 index 00000000000..f4876cfa457 --- /dev/null +++ b/src/test/run-make-fulldeps/issue-83045/b.rs @@ -0,0 +1 @@ +extern crate a; diff --git a/src/test/run-make-fulldeps/issue-83045/c.rs b/src/test/run-make-fulldeps/issue-83045/c.rs new file mode 100644 index 00000000000..e0c4525499e --- /dev/null +++ b/src/test/run-make-fulldeps/issue-83045/c.rs @@ -0,0 +1 @@ +use b as _; From 656f6ac975d3b8af6e780f1bc02e826e1629ed6a Mon Sep 17 00:00:00 2001 From: 12101111 Date: Fri, 26 Mar 2021 17:29:52 +0800 Subject: [PATCH 111/370] Handle llvm_version with suffix like "12.0.0libcxx" --- src/tools/compiletest/src/header.rs | 6 +++++- src/tools/compiletest/src/tests.rs | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index ff0d845be93..83ea676e8f4 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -973,7 +973,11 @@ fn parse_normalization_string(line: &mut &str) -> Option { } pub fn extract_llvm_version(version: &str) -> Option { - let version_without_suffix = version.trim_end_matches("git").split('-').next().unwrap(); + let pat = |c: char| !c.is_ascii_digit() && c != '.'; + let version_without_suffix = match version.find(pat) { + Some(pos) => &version[..pos], + None => version, + }; let components: Vec = version_without_suffix .split('.') .map(|s| s.parse().expect("Malformed version component")) diff --git a/src/tools/compiletest/src/tests.rs b/src/tools/compiletest/src/tests.rs index ea9bc1c1a5b..233f2e648dc 100644 --- a/src/tools/compiletest/src/tests.rs +++ b/src/tools/compiletest/src/tests.rs @@ -68,4 +68,8 @@ fn test_extract_llvm_version() { assert_eq!(extract_llvm_version("9.0.1-rust-1.43.0-dev"), Some(90001)); assert_eq!(extract_llvm_version("9.3.1-rust-1.43.0-dev"), Some(90301)); assert_eq!(extract_llvm_version("10.0.0-rust"), Some(100000)); + assert_eq!(extract_llvm_version("11.1.0"), Some(110100)); + assert_eq!(extract_llvm_version("12.0.0libcxx"), Some(120000)); + assert_eq!(extract_llvm_version("12.0.0-rc3"), Some(120000)); + assert_eq!(extract_llvm_version("13.0.0git"), Some(130000)); } From 0dbed6161a94aeb84fdae332f5b93476b6626515 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Fri, 12 Mar 2021 21:32:44 +0100 Subject: [PATCH 112/370] Rework `std::sys::windows::alloc` Add documentation to the system functions and `SAFETY` comments. Refactored helper functions, fixing the correctness of `get_header`. --- library/std/src/sys/windows/alloc.rs | 191 ++++++++++++++++++--- library/std/src/sys/windows/alloc/tests.rs | 9 + library/std/src/sys/windows/c.rs | 7 - 3 files changed, 174 insertions(+), 33 deletions(-) create mode 100644 library/std/src/sys/windows/alloc/tests.rs diff --git a/library/std/src/sys/windows/alloc.rs b/library/std/src/sys/windows/alloc.rs index 99b4d6c72a0..8ef256a06d4 100644 --- a/library/std/src/sys/windows/alloc.rs +++ b/library/std/src/sys/windows/alloc.rs @@ -1,51 +1,179 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::alloc::{GlobalAlloc, Layout, System}; +use crate::ptr; use crate::sys::c; use crate::sys_common::alloc::{realloc_fallback, MIN_ALIGN}; +#[cfg(test)] +mod tests; + +// Heap memory management on Windows is done by using the system Heap API (heapapi.h) +// See https://docs.microsoft.com/windows/win32/api/heapapi/ + +// Flag to indicate that the memory returned by `HeapAlloc` should be zeroed. +const HEAP_ZERO_MEMORY: c::DWORD = 0x00000008; + +extern "system" { + // Get a handle to the default heap of the current process, or null if the operation fails. + // + // See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-getprocessheap + fn GetProcessHeap() -> c::HANDLE; + + // Allocate a block of `dwBytes` bytes of memory from a given heap `hHeap`. + // The allocated memory may be uninitialized, or zeroed if `dwFlags` is + // set to `HEAP_ZERO_MEMORY`. + // + // Returns a pointer to the newly-allocated memory or null if the operation fails. + // The returned pointer will be aligned to at least `MIN_ALIGN`. + // + // SAFETY: + // - `hHeap` must be a non-null handle returned by `GetProcessHeap`. + // - `dwFlags` must be set to either zero or `HEAP_ZERO_MEMORY`. + // + // Note that `dwBytes` is allowed to be zero, contrary to some other allocators. + // + // See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapalloc + fn HeapAlloc(hHeap: c::HANDLE, dwFlags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID; + + // Reallocate a block of memory behind a given pointer `lpMem` from a given heap `hHeap`, + // to a block of at least `dwBytes` bytes, either shrinking the block in place, + // or allocating at a new location, copying memory, and freeing the original location. + // + // Returns a pointer to the reallocated memory or null if the operation fails. + // The returned pointer will be aligned to at least `MIN_ALIGN`. + // If the operation fails the given block will never have been freed. + // + // SAFETY: + // - `hHeap` must be a non-null handle returned by `GetProcessHeap`. + // - `dwFlags` must be set to zero. + // - `lpMem` must be a non-null pointer to an allocated block returned by `HeapAlloc` or + // `HeapReAlloc`, that has not already been freed. + // If the block was successfully reallocated at a new location, pointers pointing to + // the freed memory, such as `lpMem`, must not be dereferenced ever again. + // + // Note that `dwBytes` is allowed to be zero, contrary to some other allocators. + // + // See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heaprealloc + fn HeapReAlloc( + hHeap: c::HANDLE, + dwFlags: c::DWORD, + lpMem: c::LPVOID, + dwBytes: c::SIZE_T, + ) -> c::LPVOID; + + // Free a block of memory behind a given pointer `lpMem` from a given heap `hHeap`. + // Returns a nonzero value if the operation is successful, and zero if the operation fails. + // + // SAFETY: + // - `dwFlags` must be set to zero. + // - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`, + // that has not already been freed. + // If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`, + // must not be dereferenced ever again. + // + // Note that both `hHeap` is allowed to be any value, and `lpMem` is allowed to be null, + // both of which will not cause the operation to fail. + // + // See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree + fn HeapFree(hHeap: c::HANDLE, dwFlags: c::DWORD, lpMem: c::LPVOID) -> c::BOOL; +} + +// Header containing a pointer to the start of an allocated block. +// SAFETY: size and alignment must be <= `MIN_ALIGN`. #[repr(C)] struct Header(*mut u8); -unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header { - &mut *(ptr as *mut Header).offset(-1) -} - -unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 { - let aligned = ptr.add(align - (ptr as usize & (align - 1))); - *get_header(aligned) = Header(ptr); - aligned -} - +// Allocates a block of optionally zeroed memory for a given `layout`. +// Returns a pointer satisfying the guarantees of `System` about allocated pointers. #[inline] -unsafe fn allocate_with_flags(layout: Layout, flags: c::DWORD) -> *mut u8 { - if layout.align() <= MIN_ALIGN { - return c::HeapAlloc(c::GetProcessHeap(), flags, layout.size()) as *mut u8; +unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 { + let heap = unsafe { GetProcessHeap() }; + if heap.is_null() { + // Allocation has failed, could not get the current process heap. + return ptr::null_mut(); } - let size = layout.size() + layout.align(); - let ptr = c::HeapAlloc(c::GetProcessHeap(), flags, size); - if ptr.is_null() { ptr as *mut u8 } else { align_ptr(ptr as *mut u8, layout.align()) } + // Allocated memory will be either zeroed or uninitialized. + let flags = if zeroed { HEAP_ZERO_MEMORY } else { 0 }; + + if layout.align() <= MIN_ALIGN { + // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`. + // The returned pointer points to the start of an allocated block. + unsafe { HeapAlloc(heap, flags, layout.size()) as *mut u8 } + } else { + // Allocate extra padding in order to be able to satisfy the alignment. + let total = layout.align() + layout.size(); + + // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`. + let ptr = unsafe { HeapAlloc(heap, flags, total) as *mut u8 }; + if ptr.is_null() { + // Allocation has failed. + return ptr::null_mut(); + } + + // Create a correctly aligned pointer offset from the start of the allocated block, + // and write a header before it. + + let offset = layout.align() - (ptr as usize & (layout.align() - 1)); + // SAFETY: `MIN_ALIGN` <= `offset` <= `layout.align()` and the size of the allocated + // block is `layout.align() + layout.size()`. `aligned` will thus be a correctly aligned + // pointer inside the allocated block with at least `layout.size()` bytes after it and at + // least `MIN_ALIGN` bytes of padding before it. + let aligned = unsafe { ptr.add(offset) }; + // SAFETY: Because the size and alignment of a header is <= `MIN_ALIGN` and `aligned` + // is aligned to at least `MIN_ALIGN` and has at least `MIN_ALIGN` bytes of padding before + // it, it is safe to write a header directly before it. + unsafe { ptr::write((aligned as *mut Header).offset(-1), Header(ptr)) }; + + // SAFETY: The returned pointer does not point to the to the start of an allocated block, + // but there is a header readable directly before it containing the location of the start + // of the block. + aligned + } } +// All pointers returned by this allocator have, in addition to the guarantees of `GlobalAlloc`, the +// following properties: +// +// If the pointer was allocated or reallocated with a `layout` specifying an alignment <= `MIN_ALIGN` +// the pointer will be aligned to at least `MIN_ALIGN` and point to the start of the allocated block. +// +// If the pointer was allocated or reallocated with a `layout` specifying an alignment > `MIN_ALIGN` +// the pointer will be aligned to the specified alignment and not point to the start of the allocated block. +// Instead there will be a header readable directly before the returned pointer, containing the actual +// location of the start of the block. #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - allocate_with_flags(layout, 0) + // SAFETY: pointers returned by `allocate` satisfy the guarantees of `System` + unsafe { allocate(layout, false) } } #[inline] unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - allocate_with_flags(layout, c::HEAP_ZERO_MEMORY) + // SAFETY: pointers returned by `allocate` satisfy the guarantees of `System` + unsafe { allocate(layout, true) } } #[inline] unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - if layout.align() <= MIN_ALIGN { - let err = c::HeapFree(c::GetProcessHeap(), 0, ptr as c::LPVOID); - debug_assert!(err != 0, "Failed to free heap memory: {}", c::GetLastError()); - } else { - let header = get_header(ptr); - let err = c::HeapFree(c::GetProcessHeap(), 0, header.0 as c::LPVOID); + let block = { + if layout.align() <= MIN_ALIGN { + ptr + } else { + // The location of the start of the block is stored in the padding before `ptr`. + + // SAFETY: Because of the contract of `System`, `ptr` is guaranteed to be non-null + // and have a header readable directly before it. + unsafe { ptr::read((ptr as *mut Header).offset(-1)).0 } + } + }; + + // SAFETY: `block` is a pointer to the start of an allocated block. + unsafe { + let err = HeapFree(GetProcessHeap(), 0, block as c::LPVOID); debug_assert!(err != 0, "Failed to free heap memory: {}", c::GetLastError()); } } @@ -53,9 +181,20 @@ unsafe impl GlobalAlloc for System { #[inline] unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { if layout.align() <= MIN_ALIGN { - c::HeapReAlloc(c::GetProcessHeap(), 0, ptr as c::LPVOID, new_size) as *mut u8 + let heap = unsafe { GetProcessHeap() }; + if heap.is_null() { + // Reallocation has failed, could not get the current process heap. + return ptr::null_mut(); + } + + // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`, + // `ptr` is a pointer to the start of an allocated block. + // The returned pointer points to the start of an allocated block. + unsafe { HeapReAlloc(heap, 0, ptr as c::LPVOID, new_size) as *mut u8 } } else { - realloc_fallback(self, ptr, layout, new_size) + // SAFETY: `realloc_fallback` is implemented using `dealloc` and `alloc`, which will + // correctly handle `ptr` and return a pointer satisfying the guarantees of `System` + unsafe { realloc_fallback(self, ptr, layout, new_size) } } } } diff --git a/library/std/src/sys/windows/alloc/tests.rs b/library/std/src/sys/windows/alloc/tests.rs new file mode 100644 index 00000000000..674a3e1d92d --- /dev/null +++ b/library/std/src/sys/windows/alloc/tests.rs @@ -0,0 +1,9 @@ +use super::{Header, MIN_ALIGN}; +use crate::mem; + +#[test] +fn alloc_header() { + // Header must fit in the padding before an aligned pointer + assert!(mem::size_of::
() <= MIN_ALIGN); + assert!(mem::align_of::
() <= MIN_ALIGN); +} diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index 9789ed085e2..3e4176ef7f8 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -285,8 +285,6 @@ pub const FD_SETSIZE: usize = 64; pub const STACK_SIZE_PARAM_IS_A_RESERVATION: DWORD = 0x00010000; -pub const HEAP_ZERO_MEMORY: DWORD = 0x00000008; - pub const STATUS_SUCCESS: NTSTATUS = 0x00000000; #[repr(C)] @@ -1017,11 +1015,6 @@ extern "system" { timeout: *const timeval, ) -> c_int; - pub fn GetProcessHeap() -> HANDLE; - pub fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID; - pub fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID; - pub fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL; - // >= Vista / Server 2008 // https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createsymboliclinkw pub fn CreateSymbolicLinkW( From b01bf0e9d311332d7942619845281af4b9da54bb Mon Sep 17 00:00:00 2001 From: CDirkx Date: Mon, 22 Mar 2021 04:22:11 +0100 Subject: [PATCH 113/370] Apply suggestions from code review Co-authored-by: David Tolnay --- library/std/src/sys/windows/alloc.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/windows/alloc.rs b/library/std/src/sys/windows/alloc.rs index 8ef256a06d4..3f810ffa8ca 100644 --- a/library/std/src/sys/windows/alloc.rs +++ b/library/std/src/sys/windows/alloc.rs @@ -148,13 +148,15 @@ unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { // SAFETY: pointers returned by `allocate` satisfy the guarantees of `System` - unsafe { allocate(layout, false) } + let zeroed = false; + unsafe { allocate(layout, zeroed) } } #[inline] unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { // SAFETY: pointers returned by `allocate` satisfy the guarantees of `System` - unsafe { allocate(layout, true) } + let zeroed = true; + unsafe { allocate(layout, zeroed) } } #[inline] From 7889a32c0fb764c1692ab33154668ef70992db64 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 26 Mar 2021 13:33:03 +0100 Subject: [PATCH 114/370] Rustup to rustc 1.53.0-nightly (52e3dffa5 2021-03-25) --- build_sysroot/Cargo.lock | 8 ++++---- rust-toolchain | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index 22557726889..09c5d7590ab 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -110,9 +110,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.9.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" dependencies = [ "compiler_builtins", "rustc-std-workspace-alloc", @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "538c092e5586f4cdd7dd8078c4a79220e3e168880218124dcbce860f0ea938c6" +checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7" dependencies = [ "rustc-std-workspace-core", ] diff --git a/rust-toolchain b/rust-toolchain index a0b828e39a4..b3de18e5550 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-03-18" +channel = "nightly-2021-03-26" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From f3e8f6dc0834134de85157c801d414e764ed6fef Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 26 Mar 2021 14:35:51 +0100 Subject: [PATCH 115/370] Rustfmt --- src/constant.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/constant.rs b/src/constant.rs index 1b64d6770d2..fcd41c84465 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -124,7 +124,9 @@ pub(crate) fn codegen_constant<'tcx>( }; let const_val = match const_.val { ConstKind::Value(const_val) => const_val, - ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) if fx.tcx.is_static(def.did) => { + ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + if fx.tcx.is_static(def.did) => + { assert!(substs.is_empty()); assert!(promoted.is_none()); From 4cce9e3db2d8a93fe72994e0a39e15e69cdbc7c2 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Fri, 26 Mar 2021 14:47:25 +0100 Subject: [PATCH 116/370] Cache `GetProcessHeap` --- library/std/src/sys/windows/alloc.rs | 70 +++++++++++++++++++++------- 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/library/std/src/sys/windows/alloc.rs b/library/std/src/sys/windows/alloc.rs index 3f810ffa8ca..bc4725dfc7b 100644 --- a/library/std/src/sys/windows/alloc.rs +++ b/library/std/src/sys/windows/alloc.rs @@ -1,7 +1,9 @@ #![deny(unsafe_op_in_unsafe_fn)] use crate::alloc::{GlobalAlloc, Layout, System}; +use crate::ffi::c_void; use crate::ptr; +use crate::sync::atomic::{AtomicPtr, Ordering}; use crate::sys::c; use crate::sys_common::alloc::{realloc_fallback, MIN_ALIGN}; @@ -17,6 +19,9 @@ const HEAP_ZERO_MEMORY: c::DWORD = 0x00000008; extern "system" { // Get a handle to the default heap of the current process, or null if the operation fails. // + // SAFETY: Successful calls to this function within the same process are assumed to + // always return the same handle, which remains valid for the entire lifetime of the process. + // // See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-getprocessheap fn GetProcessHeap() -> c::HANDLE; @@ -66,29 +71,59 @@ extern "system" { // Returns a nonzero value if the operation is successful, and zero if the operation fails. // // SAFETY: + // - `hHeap` must be a non-null handle returned by `GetProcessHeap`. // - `dwFlags` must be set to zero. // - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`, // that has not already been freed. // If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`, // must not be dereferenced ever again. // - // Note that both `hHeap` is allowed to be any value, and `lpMem` is allowed to be null, - // both of which will not cause the operation to fail. + // Note that `lpMem` is allowed to be null, which will not cause the operation to fail. // // See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree fn HeapFree(hHeap: c::HANDLE, dwFlags: c::DWORD, lpMem: c::LPVOID) -> c::BOOL; } +// Cached handle to the default heap of the current process. +// Either a non-null handle returned by `GetProcessHeap`, or null when not yet initialized or `GetProcessHeap` failed. +static HEAP: AtomicPtr = AtomicPtr::new(ptr::null_mut()); + +// Get a handle to the default heap of the current process, or null if the operation fails. +// SAFETY: If this operation is successful, `HEAP` will be successfully initialized and contain +// a non-null handle returned by `GetProcessHeap`. +#[inline] +unsafe fn init_or_get_process_heap() -> c::HANDLE { + let heap = HEAP.load(Ordering::Relaxed); + if heap.is_null() { + // `HEAP` has not yet been successfully initialized + let heap = unsafe { GetProcessHeap() }; + if !heap.is_null() { + // SAFETY: No locking is needed because within the same process, + // successful calls to `GetProcessHeap` will always return the same value, even on different threads. + HEAP.store(heap, Ordering::Relaxed); + + // SAFETY: `HEAP` contains a non-null handle returned by `GetProcessHeap` + heap + } else { + // Could not get the current process heap. + ptr::null_mut() + } + } else { + // SAFETY: `HEAP` contains a non-null handle returned by `GetProcessHeap` + heap + } +} + // Header containing a pointer to the start of an allocated block. -// SAFETY: size and alignment must be <= `MIN_ALIGN`. +// SAFETY: Size and alignment must be <= `MIN_ALIGN`. #[repr(C)] struct Header(*mut u8); -// Allocates a block of optionally zeroed memory for a given `layout`. -// Returns a pointer satisfying the guarantees of `System` about allocated pointers. +// Allocate a block of optionally zeroed memory for a given `layout`. +// SAFETY: Returns a pointer satisfying the guarantees of `System` about allocated pointers. #[inline] unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 { - let heap = unsafe { GetProcessHeap() }; + let heap = unsafe { init_or_get_process_heap() }; if heap.is_null() { // Allocation has failed, could not get the current process heap. return ptr::null_mut(); @@ -147,14 +182,14 @@ unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 { unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - // SAFETY: pointers returned by `allocate` satisfy the guarantees of `System` + // SAFETY: Pointers returned by `allocate` satisfy the guarantees of `System` let zeroed = false; unsafe { allocate(layout, zeroed) } } #[inline] unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - // SAFETY: pointers returned by `allocate` satisfy the guarantees of `System` + // SAFETY: Pointers returned by `allocate` satisfy the guarantees of `System` let zeroed = true; unsafe { allocate(layout, zeroed) } } @@ -173,9 +208,14 @@ unsafe impl GlobalAlloc for System { } }; + // SAFETY: because `ptr` has been successfully allocated with this allocator, + // `HEAP` must have been successfully initialized and contain a non-null handle + // returned by `GetProcessHeap`. + let heap = HEAP.load(Ordering::Relaxed); + // SAFETY: `block` is a pointer to the start of an allocated block. unsafe { - let err = HeapFree(GetProcessHeap(), 0, block as c::LPVOID); + let err = HeapFree(heap, 0, block as c::LPVOID); debug_assert!(err != 0, "Failed to free heap memory: {}", c::GetLastError()); } } @@ -183,14 +223,12 @@ unsafe impl GlobalAlloc for System { #[inline] unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { if layout.align() <= MIN_ALIGN { - let heap = unsafe { GetProcessHeap() }; - if heap.is_null() { - // Reallocation has failed, could not get the current process heap. - return ptr::null_mut(); - } + // SAFETY: because `ptr` has been successfully allocated with this allocator, + // `HEAP` must have been successfully initialized and contain a non-null handle + // returned by `GetProcessHeap`. + let heap = HEAP.load(Ordering::Relaxed); - // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`, - // `ptr` is a pointer to the start of an allocated block. + // SAFETY: `ptr` is a pointer to the start of an allocated block. // The returned pointer points to the start of an allocated block. unsafe { HeapReAlloc(heap, 0, ptr as c::LPVOID, new_size) as *mut u8 } } else { From b362958453910169876686a839c6818fec2950c5 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 8 Mar 2021 15:32:33 -0800 Subject: [PATCH 117/370] Add function core::iter::zip This makes it a little easier to `zip` iterators: ```rust for (x, y) in zip(xs, ys) {} // vs. for (x, y) in xs.into_iter().zip(ys) {} ``` You can `zip(&mut xs, &ys)` for the conventional `iter_mut()` and `iter()`, respectively. This can also support arbitrary nesting, where it's easier to see the item layout than with arbitrary `zip` chains: ```rust for ((x, y), z) in zip(zip(xs, ys), zs) {} for (x, (y, z)) in zip(xs, zip(ys, zs)) {} // vs. for ((x, y), z) in xs.into_iter().zip(ys).zip(xz) {} for (x, (y, z)) in xs.into_iter().zip((ys.into_iter().zip(xz)) {} ``` It may also format more nicely, especially when the first iterator is a longer chain of methods -- for example: ```rust iter::zip( trait_ref.substs.types().skip(1), impl_trait_ref.substs.types().skip(1), ) // vs. trait_ref .substs .types() .skip(1) .zip(impl_trait_ref.substs.types().skip(1)) ``` This replaces the tuple-pair `IntoIterator` in rust-lang/rust#78204. There is prior art for the utility of this in [`itertools::zip`]. [`itertools::zip`]: https://docs.rs/itertools/0.10.0/itertools/fn.zip.html --- library/core/src/iter/adapters/mod.rs | 3 +++ library/core/src/iter/adapters/zip.rs | 35 +++++++++++++++++++++++++-- library/core/src/iter/mod.rs | 2 ++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index 41a7b13232a..3859d76ad5e 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -51,6 +51,9 @@ pub use self::map_while::MapWhile; #[unstable(feature = "trusted_random_access", issue = "none")] pub use self::zip::TrustedRandomAccess; +#[unstable(feature = "iter_zip", issue = "none")] +pub use self::zip::zip; + /// This trait provides transitive access to source-stage in an interator-adapter pipeline /// under the conditions that /// * the iterator source `S` itself implements `SourceIter` diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs index ea7a809c6ba..ad630ba95b8 100644 --- a/library/core/src/iter/adapters/zip.rs +++ b/library/core/src/iter/adapters/zip.rs @@ -5,8 +5,8 @@ use crate::iter::{InPlaceIterable, SourceIter, TrustedLen}; /// An iterator that iterates two other iterators simultaneously. /// -/// This `struct` is created by [`Iterator::zip`]. See its documentation -/// for more. +/// This `struct` is created by [`zip`] or [`Iterator::zip`]. +/// See their documentation for more. #[derive(Clone)] #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -33,6 +33,37 @@ impl Zip { } } +/// Converts the arguments to iterators and zips them. +/// +/// See the documentation of [`Iterator::zip`] for more. +/// +/// # Examples +/// +/// ``` +/// #![feature(iter_zip)] +/// use std::iter::zip; +/// +/// let xs = [1, 2, 3]; +/// let ys = [4, 5, 6]; +/// for (x, y) in zip(&xs, &ys) { +/// println!("x:{}, y:{}", x, y); +/// } +/// +/// // Nested zips are also possible: +/// let zs = [7, 8, 9]; +/// for ((x, y), z) in zip(zip(&xs, &ys), &zs) { +/// println!("x:{}, y:{}, z:{}", x, y, z); +/// } +/// ``` +#[unstable(feature = "iter_zip", issue = "none")] +pub fn zip(a: A, b: B) -> Zip +where + A: IntoIterator, + B: IntoIterator, +{ + ZipImpl::new(a.into_iter(), b.into_iter()) +} + #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Zip where diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs index c57ba2bf626..8d905feeb49 100644 --- a/library/core/src/iter/mod.rs +++ b/library/core/src/iter/mod.rs @@ -389,6 +389,8 @@ pub use self::traits::{ DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator, Product, Sum, }; +#[unstable(feature = "iter_zip", issue = "none")] +pub use self::adapters::zip; #[stable(feature = "iter_cloned", since = "1.1.0")] pub use self::adapters::Cloned; #[stable(feature = "iter_copied", since = "1.36.0")] From 3b1f5e34620d6bfa32a127258e2c2d9f2f4d693b Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 8 Mar 2021 15:32:41 -0800 Subject: [PATCH 118/370] Use iter::zip in library/ --- library/alloc/src/lib.rs | 1 + library/alloc/src/vec/mod.rs | 9 +++------ library/core/src/array/iter.rs | 4 ++-- library/core/src/fmt/mod.rs | 5 +++-- library/core/src/num/bignum.rs | 6 ++++-- library/core/src/slice/ascii.rs | 3 ++- library/std/src/lib.rs | 1 + library/std/src/sys/unix/ext/net/addr.rs | 4 ++-- 8 files changed, 18 insertions(+), 15 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 40f2de8f70d..fb243100990 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -108,6 +108,7 @@ // that the feature-gate isn't enabled. Ideally, it wouldn't check for the feature gate for docs // from other crates, but since this can only appear for lang items, it doesn't seem worth fixing. #![feature(intra_doc_pointers)] +#![feature(iter_zip)] #![feature(lang_items)] #![feature(layout_for_ptr)] #![feature(maybe_uninit_ref)] diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index ff93c772b5b..708898ad2e7 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -58,7 +58,7 @@ use core::convert::TryFrom; use core::fmt; use core::hash::{Hash, Hasher}; use core::intrinsics::{arith_offset, assume}; -use core::iter::FromIterator; +use core::iter::{self, FromIterator}; use core::marker::PhantomData; use core::mem::{self, ManuallyDrop, MaybeUninit}; use core::ops::{self, Index, IndexMut, Range, RangeBounds}; @@ -2268,11 +2268,8 @@ impl ExtendFromWithinSpec for Vec { // - caller guaratees that src is a valid index let to_clone = unsafe { this.get_unchecked(src) }; - to_clone - .iter() - .cloned() - .zip(spare.iter_mut()) - .map(|(src, dst)| dst.write(src)) + iter::zip(to_clone, spare) + .map(|(src, dst)| dst.write(src.clone())) // Note: // - Element was just initialized with `MaybeUninit::write`, so it's ok to increace len // - len is increased after each element to prevent leaks (see issue #82533) diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index f82454addd0..c36542f6314 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -2,7 +2,7 @@ use crate::{ fmt, - iter::{ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess}, + iter::{self, ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess}, mem::{self, MaybeUninit}, ops::Range, ptr, @@ -215,7 +215,7 @@ impl Clone for IntoIter { let mut new = Self { data: MaybeUninit::uninit_array(), alive: 0..0 }; // Clone all alive elements. - for (src, dst) in self.as_slice().iter().zip(&mut new.data) { + for (src, dst) in iter::zip(self.as_slice(), &mut new.data) { // Write a clone into the new array, then update its alive range. // If cloning panics, we'll correctly drop the previous items. dst.write(src.clone()); diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index d211ad4b2f7..d696ffa8277 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -4,6 +4,7 @@ use crate::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell}; use crate::char::EscapeDebugExtArgs; +use crate::iter; use crate::marker::PhantomData; use crate::mem; use crate::num::flt2dec; @@ -1088,7 +1089,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { match args.fmt { None => { // We can use default formatting parameters for all arguments. - for (arg, piece) in args.args.iter().zip(args.pieces.iter()) { + for (arg, piece) in iter::zip(args.args, args.pieces) { formatter.buf.write_str(*piece)?; (arg.formatter)(arg.value, &mut formatter)?; idx += 1; @@ -1097,7 +1098,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { Some(fmt) => { // Every spec has a corresponding argument that is preceded by // a string piece. - for (arg, piece) in fmt.iter().zip(args.pieces.iter()) { + for (arg, piece) in iter::zip(fmt, args.pieces) { formatter.buf.write_str(*piece)?; // SAFETY: arg and args.args come from the same Arguments, // which guarantees the indexes are always within bounds. diff --git a/library/core/src/num/bignum.rs b/library/core/src/num/bignum.rs index 6a1a1e19761..197b85fba1f 100644 --- a/library/core/src/num/bignum.rs +++ b/library/core/src/num/bignum.rs @@ -181,11 +181,12 @@ macro_rules! define_bignum { /// Adds `other` to itself and returns its own mutable reference. pub fn add<'a>(&'a mut self, other: &$name) -> &'a mut $name { use crate::cmp; + use crate::iter; use crate::num::bignum::FullOps; let mut sz = cmp::max(self.size, other.size); let mut carry = false; - for (a, b) in self.base[..sz].iter_mut().zip(&other.base[..sz]) { + for (a, b) in iter::zip(&mut self.base[..sz], &other.base[..sz]) { let (c, v) = (*a).full_add(*b, carry); *a = v; carry = c; @@ -219,11 +220,12 @@ macro_rules! define_bignum { /// Subtracts `other` from itself and returns its own mutable reference. pub fn sub<'a>(&'a mut self, other: &$name) -> &'a mut $name { use crate::cmp; + use crate::iter; use crate::num::bignum::FullOps; let sz = cmp::max(self.size, other.size); let mut noborrow = true; - for (a, b) in self.base[..sz].iter_mut().zip(&other.base[..sz]) { + for (a, b) in iter::zip(&mut self.base[..sz], &other.base[..sz]) { let (c, v) = (*a).full_add(!*b, noborrow); *a = v; noborrow = c; diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 42032bc9035..009ef9e0a9c 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -1,5 +1,6 @@ //! Operations on ASCII `[u8]`. +use crate::iter; use crate::mem; #[lang = "slice_u8"] @@ -19,7 +20,7 @@ impl [u8] { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool { - self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a.eq_ignore_ascii_case(b)) + self.len() == other.len() && iter::zip(self, other).all(|(a, b)| a.eq_ignore_ascii_case(b)) } /// Converts this slice to its ASCII upper case equivalent in-place. diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 8b34fb05055..3719eeb1840 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -278,6 +278,7 @@ #![feature(integer_atomics)] #![feature(into_future)] #![feature(intra_doc_pointers)] +#![feature(iter_zip)] #![feature(lang_items)] #![feature(link_args)] #![feature(linkage)] diff --git a/library/std/src/sys/unix/ext/net/addr.rs b/library/std/src/sys/unix/ext/net/addr.rs index 6e7d1f1678a..459f3590e64 100644 --- a/library/std/src/sys/unix/ext/net/addr.rs +++ b/library/std/src/sys/unix/ext/net/addr.rs @@ -2,7 +2,7 @@ use crate::ffi::OsStr; use crate::os::unix::ffi::OsStrExt; use crate::path::Path; use crate::sys::cvt; -use crate::{ascii, fmt, io, mem}; +use crate::{ascii, fmt, io, iter, mem}; // FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here? #[cfg(not(unix))] @@ -41,7 +41,7 @@ pub(super) unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, &"path must be shorter than SUN_LEN", )); } - for (dst, src) in addr.sun_path.iter_mut().zip(bytes.iter()) { + for (dst, src) in iter::zip(&mut addr.sun_path, bytes) { *dst = *src as libc::c_char; } // null byte for pathname addresses is already there because we zeroed the From 72ebebe474aae7203a27fdc1296617edd01321f1 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 8 Mar 2021 15:32:41 -0800 Subject: [PATCH 119/370] Use iter::zip in compiler/ --- compiler/rustc_apfloat/src/ieee.rs | 5 +-- compiler/rustc_apfloat/src/lib.rs | 1 + compiler/rustc_ast/src/lib.rs | 1 + compiler/rustc_ast/src/tokenstream.rs | 2 +- compiler/rustc_ast_lowering/src/item.rs | 5 +-- compiler/rustc_ast_lowering/src/lib.rs | 1 + .../src/deriving/generic/mod.rs | 8 ++--- compiler/rustc_builtin_macros/src/lib.rs | 1 + compiler/rustc_codegen_llvm/src/back/lto.rs | 5 ++- compiler/rustc_codegen_llvm/src/builder.rs | 9 ++--- .../src/debuginfo/metadata.rs | 8 ++--- .../rustc_codegen_llvm/src/debuginfo/mod.rs | 5 ++- compiler/rustc_codegen_llvm/src/lib.rs | 1 + compiler/rustc_codegen_ssa/src/lib.rs | 1 + compiler/rustc_codegen_ssa/src/mir/mod.rs | 4 +-- compiler/rustc_errors/src/emitter.rs | 4 +-- compiler/rustc_errors/src/lib.rs | 1 + compiler/rustc_errors/src/styled_buffer.rs | 5 +-- compiler/rustc_expand/src/lib.rs | 1 + compiler/rustc_expand/src/mbe/macro_check.rs | 4 ++- compiler/rustc_index/src/bit_set.rs | 6 ++-- compiler/rustc_index/src/lib.rs | 1 + .../src/infer/canonical/query_response.rs | 4 ++- .../src/infer/error_reporting/mod.rs | 31 +++++++++-------- compiler/rustc_infer/src/lib.rs | 1 + .../src/traits/error_reporting/mod.rs | 3 +- compiler/rustc_lint/src/context.rs | 3 +- compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_lint/src/types.rs | 8 ++--- compiler/rustc_macros/src/symbols/tests.rs | 2 +- compiler/rustc_middle/src/infer/canonical.rs | 6 ++-- compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_middle/src/mir/mod.rs | 6 ++-- compiler/rustc_middle/src/mir/terminator.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/layout.rs | 6 ++-- compiler/rustc_middle/src/ty/print/pretty.rs | 3 +- compiler/rustc_middle/src/ty/relate.rs | 20 ++++------- compiler/rustc_middle/src/ty/util.rs | 6 ++-- .../src/borrow_check/diagnostics/mod.rs | 12 +++---- .../borrow_check/diagnostics/region_name.rs | 6 ++-- .../src/borrow_check/invalidation.rs | 3 +- compiler/rustc_mir/src/borrow_check/mod.rs | 3 +- .../src/borrow_check/places_conflict.rs | 3 +- .../src/borrow_check/type_check/mod.rs | 2 +- .../src/borrow_check/universal_regions.rs | 2 +- .../src/dataflow/framework/lattice.rs | 5 +-- .../rustc_mir/src/dataflow/impls/borrows.rs | 3 +- .../src/dataflow/move_paths/builder.rs | 3 +- compiler/rustc_mir/src/lib.rs | 1 + .../rustc_mir/src/transform/coverage/debug.rs | 5 ++- .../src/transform/deduplicate_blocks.rs | 8 ++--- .../rustc_mir/src/transform/match_branches.rs | 5 +-- .../src/build/expr/as_place.rs | 4 ++- .../rustc_mir_build/src/build/expr/into.rs | 5 ++- compiler/rustc_mir_build/src/lib.rs | 1 + compiler/rustc_passes/src/lib.rs | 1 + compiler/rustc_passes/src/liveness.rs | 5 +-- .../rustc_passes/src/liveness/rwu_table.rs | 3 +- compiler/rustc_passes/src/stability.rs | 3 +- compiler/rustc_query_system/src/lib.rs | 1 + compiler/rustc_query_system/src/query/job.rs | 4 +-- .../rustc_resolve/src/late/diagnostics.rs | 6 ++-- compiler/rustc_resolve/src/lib.rs | 1 + compiler/rustc_span/src/hygiene.rs | 2 +- compiler/rustc_trait_selection/src/lib.rs | 1 + .../src/traits/auto_trait.rs | 5 ++- .../src/traits/coherence.rs | 33 +++++++++---------- .../src/traits/const_evaluatable.rs | 5 ++- .../src/traits/error_reporting/mod.rs | 3 +- .../error_reporting/on_unimplemented.rs | 12 +++---- .../src/traits/select/mod.rs | 2 +- .../rustc_trait_selection/src/traits/wf.rs | 6 +--- compiler/rustc_typeck/src/astconv/errors.rs | 3 +- compiler/rustc_typeck/src/check/callee.rs | 3 +- compiler/rustc_typeck/src/check/check.rs | 3 +- compiler/rustc_typeck/src/check/closure.rs | 14 ++++---- .../rustc_typeck/src/check/compare_method.rs | 13 +++----- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 3 +- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 3 +- .../src/check/fn_ctxt/suggestions.rs | 3 +- .../rustc_typeck/src/check/method/confirm.rs | 6 ++-- compiler/rustc_typeck/src/check/upvar.rs | 4 ++- compiler/rustc_typeck/src/check/wfcheck.rs | 7 ++-- compiler/rustc_typeck/src/collect.rs | 3 +- compiler/rustc_typeck/src/expr_use_visitor.rs | 3 +- compiler/rustc_typeck/src/lib.rs | 1 + 87 files changed, 213 insertions(+), 204 deletions(-) diff --git a/compiler/rustc_apfloat/src/ieee.rs b/compiler/rustc_apfloat/src/ieee.rs index 71bcb8f090d..96277950cfe 100644 --- a/compiler/rustc_apfloat/src/ieee.rs +++ b/compiler/rustc_apfloat/src/ieee.rs @@ -2273,6 +2273,7 @@ impl Loss { mod sig { use super::{limbs_for_bits, ExpInt, Limb, Loss, LIMB_BITS}; use core::cmp::Ordering; + use core::iter; use core::mem; pub(super) fn is_all_zeros(limbs: &[Limb]) -> bool { @@ -2483,7 +2484,7 @@ mod sig { pub(super) fn add(a: &mut [Limb], b: &[Limb], mut c: Limb) -> Limb { assert!(c <= 1); - for (a, &b) in a.iter_mut().zip(b) { + for (a, &b) in iter::zip(a, b) { let (r, overflow) = a.overflowing_add(b); let (r, overflow2) = r.overflowing_add(c); *a = r; @@ -2497,7 +2498,7 @@ mod sig { pub(super) fn sub(a: &mut [Limb], b: &[Limb], mut c: Limb) -> Limb { assert!(c <= 1); - for (a, &b) in a.iter_mut().zip(b) { + for (a, &b) in iter::zip(a, b) { let (r, overflow) = a.overflowing_sub(b); let (r, overflow2) = r.overflowing_sub(c); *a = r; diff --git a/compiler/rustc_apfloat/src/lib.rs b/compiler/rustc_apfloat/src/lib.rs index c1aa74029f5..c648147d108 100644 --- a/compiler/rustc_apfloat/src/lib.rs +++ b/compiler/rustc_apfloat/src/lib.rs @@ -33,6 +33,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![no_std] #![forbid(unsafe_code)] +#![feature(iter_zip)] #![feature(nll)] #![cfg_attr(bootstrap, feature(or_patterns))] diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index a823d375fcf..032a4e6c782 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -14,6 +14,7 @@ #![feature(const_fn_transmute)] #![feature(const_panic)] #![feature(crate_visibility_modifier)] +#![feature(iter_zip)] #![feature(label_break_value)] #![feature(nll)] #![cfg_attr(bootstrap, feature(or_patterns))] diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index c5c3142602b..1e63ca172e7 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -341,7 +341,7 @@ impl TokenStream { pub fn eq_unspanned(&self, other: &TokenStream) -> bool { let mut t1 = self.trees(); let mut t2 = other.trees(); - for (t1, t2) in t1.by_ref().zip(t2.by_ref()) { + for (t1, t2) in iter::zip(&mut t1, &mut t2) { if !t1.eq_unspanned(&t2) { return false; } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index edd0c5fb964..ea01632d75d 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -18,6 +18,7 @@ use rustc_target::spec::abi; use smallvec::{smallvec, SmallVec}; use tracing::debug; +use std::iter; use std::mem; pub(super) struct ItemLowerer<'a, 'lowering, 'hir> { @@ -206,7 +207,7 @@ impl<'hir> LoweringContext<'_, 'hir> { UseTreeKind::Glob => {} UseTreeKind::Simple(_, id1, id2) => { for (_, &id) in - self.expect_full_res_from_use(base_id).skip(1).zip([id1, id2].iter()) + iter::zip(self.expect_full_res_from_use(base_id).skip(1), &[id1, id2]) { vec.push(id); } @@ -537,7 +538,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // won't be dealing with macros in the rest of the compiler. // Essentially a single `use` which imports two names is desugared into // two imports. - for (res, &new_node_id) in resolutions.zip([id1, id2].iter()) { + for (res, &new_node_id) in iter::zip(resolutions, &[id1, id2]) { let ident = *ident; let mut path = path.clone(); for seg in &mut path.segments { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 046e7fc70fc..192c3280327 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -33,6 +33,7 @@ #![feature(crate_visibility_modifier)] #![cfg_attr(bootstrap, feature(or_patterns))] #![feature(box_patterns)] +#![feature(iter_zip)] #![recursion_limit = "256"] use rustc_ast::node_id::NodeMap; diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index da85cc73ffd..04753926c3e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -1034,7 +1034,7 @@ impl<'a> MethodDef<'a> { // make a series of nested matches, to destructure the // structs. This is actually right-to-left, but it shouldn't // matter. - for (arg_expr, pat) in self_args.iter().zip(patterns) { + for (arg_expr, pat) in iter::zip(self_args, patterns) { body = cx.expr_match( trait_.span, arg_expr.clone(), @@ -1351,7 +1351,7 @@ impl<'a> MethodDef<'a> { let mut discriminant_test = cx.expr_bool(sp, true); let mut first_ident = None; - for (&ident, self_arg) in vi_idents.iter().zip(&self_args) { + for (&ident, self_arg) in iter::zip(&vi_idents, &self_args) { let self_addr = cx.expr_addr_of(sp, self_arg.clone()); let variant_value = deriving::call_intrinsic(cx, sp, sym::discriminant_value, vec![self_addr]); @@ -1571,9 +1571,7 @@ impl<'a> TraitDef<'a> { let subpats = self.create_subpatterns(cx, paths, mutbl, use_temporaries); let pattern = match *struct_def { VariantData::Struct(..) => { - let field_pats = subpats - .into_iter() - .zip(&ident_exprs) + let field_pats = iter::zip(subpats, &ident_exprs) .map(|(pat, &(sp, ident, ..))| { if ident.is_none() { cx.span_bug(sp, "a braced struct with unnamed fields in `derive`"); diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index fe4bede6a48..d7926ed0e0b 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -7,6 +7,7 @@ #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] #![feature(decl_macro)] +#![feature(iter_zip)] #![feature(nll)] #![cfg_attr(bootstrap, feature(or_patterns))] #![feature(proc_macro_internals)] diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 5effe687528..4226ed7d99b 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -24,6 +24,7 @@ use tracing::{debug, info}; use std::ffi::{CStr, CString}; use std::fs::File; use std::io; +use std::iter; use std::path::Path; use std::ptr; use std::slice; @@ -916,9 +917,7 @@ impl ThinLTOKeysMap { modules: &[llvm::ThinLTOModule], names: &[CString], ) -> Self { - let keys = modules - .iter() - .zip(names.iter()) + let keys = iter::zip(modules, names) .map(|(module, name)| { let key = build_string(|rust_str| unsafe { llvm::LLVMRustComputeLTOCacheKey(rust_str, module.identifier, data.0); diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index f4852c91e53..896e56a9a1e 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -21,6 +21,7 @@ use rustc_target::abi::{self, Align, Size}; use rustc_target::spec::{HasTargetSpec, Target}; use std::borrow::Cow; use std::ffi::CStr; +use std::iter; use std::ops::{Deref, Range}; use std::ptr; use tracing::debug; @@ -1352,18 +1353,14 @@ impl Builder<'a, 'll, 'tcx> { let param_tys = self.cx.func_params_types(fn_ty); - let all_args_match = param_tys - .iter() - .zip(args.iter().map(|&v| self.val_ty(v))) + let all_args_match = iter::zip(¶m_tys, args.iter().map(|&v| self.val_ty(v))) .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty); if all_args_match { return Cow::Borrowed(args); } - let casted_args: Vec<_> = param_tys - .into_iter() - .zip(args.iter()) + let casted_args: Vec<_> = iter::zip(param_tys, args) .enumerate() .map(|(i, (expected_ty, &actual_val))| { let actual_ty = self.val_ty(actual_val); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index d5b32e58cc3..d90e93f116c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1962,9 +1962,7 @@ fn prepare_enum_metadata( let discriminant_type_metadata = |discr: Primitive| { let enumerators_metadata: Vec<_> = match enum_type.kind() { - ty::Adt(def, _) => def - .discriminants(tcx) - .zip(&def.variants) + ty::Adt(def, _) => iter::zip(def.discriminants(tcx), &def.variants) .map(|((_, discr), v)| { let name = v.ident.as_str(); let is_unsigned = match discr.ty.kind() { @@ -2336,9 +2334,7 @@ fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> &'ll DIAr if substs.types().next().is_some() { let generics = cx.tcx.generics_of(def.did); let names = get_parameter_names(cx, generics); - let template_params: Vec<_> = substs - .iter() - .zip(names) + let template_params: Vec<_> = iter::zip(substs, names) .filter_map(|(kind, name)| { if let GenericArgKind::Type(ty) = kind.unpack() { let actual_type = diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index abb87cb3656..e157a38aa03 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -37,6 +37,7 @@ use rustc_target::abi::{LayoutOf, Primitive, Size}; use libc::c_uint; use smallvec::SmallVec; use std::cell::RefCell; +use std::iter; use tracing::debug; mod create_scope_map; @@ -448,9 +449,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { // Again, only create type information if full debuginfo is enabled let template_params: Vec<_> = if cx.sess().opts.debuginfo == DebugInfo::Full { let names = get_parameter_names(cx, generics); - substs - .iter() - .zip(names) + iter::zip(substs, names) .filter_map(|(kind, name)| { if let GenericArgKind::Type(ty) = kind.unpack() { let actual_type = diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index de7f5fc6e29..5ca4b226c38 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -11,6 +11,7 @@ #![feature(extended_key_value_attributes)] #![feature(extern_types)] #![feature(in_band_lifetimes)] +#![feature(iter_zip)] #![feature(nll)] #![cfg_attr(bootstrap, feature(or_patterns))] #![recursion_limit = "256"] diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 6eead2812ba..56b4ef79383 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -8,6 +8,7 @@ #![feature(nll)] #![cfg_attr(bootstrap, feature(or_patterns))] #![feature(associated_type_bounds)] +#![feature(iter_zip)] #![recursion_limit = "256"] #![feature(box_syntax)] diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 3f945478213..91df67b53d2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -282,9 +282,7 @@ fn create_funclets<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( IndexVec>, IndexVec>, ) { - block_bxs - .iter_enumerated() - .zip(cleanup_kinds) + iter::zip(block_bxs.iter_enumerated(), cleanup_kinds) .map(|((bb, &llbb), cleanup_kind)| { match *cleanup_kind { CleanupKind::Funclet if base::wants_msvc_seh(bx.sess()) => {} diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 66499fbb8da..633c64af3c5 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2214,9 +2214,7 @@ pub fn is_case_difference(sm: &SourceMap, suggested: &str, sp: Span) -> bool { }; let ascii_confusables = &['c', 'f', 'i', 'k', 'o', 's', 'u', 'v', 'w', 'x', 'y', 'z']; // All the chars that differ in capitalization are confusable (above): - let confusable = found - .chars() - .zip(suggested.chars()) + let confusable = iter::zip(found.chars(), suggested.chars()) .filter(|(f, s)| f != s) .all(|(f, s)| (ascii_confusables.contains(&f) || ascii_confusables.contains(&s))); confusable && found.to_lowercase() == suggested.to_lowercase() diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index fa855f544e8..6f3ce20fc8e 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -6,6 +6,7 @@ #![feature(crate_visibility_modifier)] #![feature(backtrace)] #![feature(extended_key_value_attributes)] +#![feature(iter_zip)] #![feature(nll)] #[macro_use] diff --git a/compiler/rustc_errors/src/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs index ef71ee36ea3..ec122e7be6e 100644 --- a/compiler/rustc_errors/src/styled_buffer.rs +++ b/compiler/rustc_errors/src/styled_buffer.rs @@ -1,6 +1,7 @@ // Code for creating styled buffers use crate::snippet::{Style, StyledString}; +use std::iter; #[derive(Debug)] pub struct StyledBuffer { @@ -20,11 +21,11 @@ impl StyledBuffer { let mut output: Vec> = vec![]; let mut styled_vec: Vec = vec![]; - for (row, row_style) in self.text.iter().zip(&self.styles) { + for (row, row_style) in iter::zip(&self.text, &self.styles) { let mut current_style = Style::NoStyle; let mut current_text = String::new(); - for (&c, &s) in row.iter().zip(row_style) { + for (&c, &s) in iter::zip(row, row_style) { if s != current_style { if !current_text.is_empty() { styled_vec.push(StyledString { text: current_text, style: current_style }); diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 14f04dcb51a..5fb85867501 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -2,6 +2,7 @@ #![feature(crate_visibility_modifier)] #![feature(decl_macro)] #![feature(destructuring_assignment)] +#![feature(iter_zip)] #![cfg_attr(bootstrap, feature(or_patterns))] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_internals)] diff --git a/compiler/rustc_expand/src/mbe/macro_check.rs b/compiler/rustc_expand/src/mbe/macro_check.rs index 91add4f9218..3497e5ad543 100644 --- a/compiler/rustc_expand/src/mbe/macro_check.rs +++ b/compiler/rustc_expand/src/mbe/macro_check.rs @@ -116,6 +116,8 @@ use rustc_span::{symbol::MacroRulesNormalizedIdent, MultiSpan, Span}; use smallvec::SmallVec; +use std::iter; + /// Stack represented as linked list. /// /// Those are used for environments because they grow incrementally and are not mutable. @@ -204,7 +206,7 @@ pub(super) fn check_meta_variables( sess.span_diagnostic.span_bug(span, "length mismatch between LHSes and RHSes") } let mut valid = true; - for (lhs, rhs) in lhses.iter().zip(rhses.iter()) { + for (lhs, rhs) in iter::zip(lhses, rhses) { let mut binders = Binders::default(); check_binders(sess, node_id, lhs, &Stack::Empty, &mut binders, &Stack::Empty, &mut valid); check_occurrences(sess, node_id, rhs, &Stack::Empty, &binders, &Stack::Empty, &mut valid); diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 100824f4b94..cfea5092bc3 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -356,7 +356,7 @@ where { assert_eq!(out_vec.len(), in_vec.len()); let mut changed = false; - for (out_elem, in_elem) in out_vec.iter_mut().zip(in_vec.iter()) { + for (out_elem, in_elem) in iter::zip(out_vec, in_vec) { let old_val = *out_elem; let new_val = op(old_val, *in_elem); *out_elem = new_val; @@ -842,7 +842,7 @@ impl BitMatrix { let (write_start, write_end) = self.range(write); let words = &mut self.words[..]; let mut changed = false; - for (read_index, write_index) in (read_start..read_end).zip(write_start..write_end) { + for (read_index, write_index) in iter::zip(read_start..read_end, write_start..write_end) { let word = words[write_index]; let new_word = word | words[read_index]; words[write_index] = new_word; @@ -858,7 +858,7 @@ impl BitMatrix { assert_eq!(with.domain_size(), self.num_columns); let (write_start, write_end) = self.range(write); let mut changed = false; - for (read_index, write_index) in (0..with.words().len()).zip(write_start..write_end) { + for (read_index, write_index) in iter::zip(0..with.words().len(), write_start..write_end) { let word = self.words[write_index]; let new_word = word | with.words()[read_index]; self.words[write_index] = new_word; diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 995034e81da..3ced3920cfd 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -2,6 +2,7 @@ #![feature(const_fn)] #![feature(const_panic)] #![feature(extend_one)] +#![feature(iter_zip)] #![feature(unboxed_closures)] #![feature(test)] #![feature(fn_traits)] diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 2ec9b9e0be4..f000d491b99 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -27,6 +27,7 @@ use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; use rustc_middle::ty::{self, BoundVar, Const, ToPredicate, Ty, TyCtxt}; use std::fmt::Debug; +use std::iter; impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// This method is meant to be invoked as the final step of a canonical query @@ -418,7 +419,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { // In terms of our example above, we are iterating over pairs like: // [(?A, Vec), ('static, '?1), (?B, ?0)] - for (original_value, result_value) in original_values.var_values.iter().zip(result_values) { + for (original_value, result_value) in iter::zip(&original_values.var_values, result_values) + { match result_value.unpack() { GenericArgKind::Type(result_value) => { // e.g., here `result_value` might be `?0` in the example above... diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index c171b11e3ff..a18c9569a8c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -73,7 +73,7 @@ use rustc_middle::ty::{ use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span}; use rustc_target::spec::abi; use std::ops::ControlFlow; -use std::{cmp, fmt}; +use std::{cmp, fmt, iter}; mod note; @@ -963,7 +963,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ty::GenericParamDefKind::Const { has_default: true } => Some(param.def_id), _ => None, }); - for (def_id, actual) in default_params.zip(substs.iter().rev()) { + for (def_id, actual) in iter::zip(default_params, substs.iter().rev()) { match actual.unpack() { GenericArgKind::Const(c) => { if self.tcx.const_param_default(def_id).subst(self.tcx, substs) != c { @@ -1040,7 +1040,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let len1 = sig1.inputs().len(); let len2 = sig2.inputs().len(); if len1 == len2 { - for (i, (l, r)) in sig1.inputs().iter().zip(sig2.inputs().iter()).enumerate() { + for (i, (l, r)) in iter::zip(sig1.inputs(), sig2.inputs()).enumerate() { let (x1, x2) = self.cmp(l, r); (values.0).0.extend(x1.0); (values.1).0.extend(x2.0); @@ -1161,12 +1161,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let common_len = cmp::min(len1, len2); let remainder1: Vec<_> = sub1.types().skip(common_len).collect(); let remainder2: Vec<_> = sub2.types().skip(common_len).collect(); - let common_default_params = remainder1 - .iter() - .rev() - .zip(remainder2.iter().rev()) - .filter(|(a, b)| a == b) - .count(); + let common_default_params = + iter::zip(remainder1.iter().rev(), remainder2.iter().rev()) + .filter(|(a, b)| a == b) + .count(); let len = sub1.len() - common_default_params; let consts_offset = len - sub1.consts().count(); @@ -1297,12 +1295,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { const SEPARATOR: &str = "::"; let separator_len = SEPARATOR.len(); - let split_idx: usize = t1_str - .split(SEPARATOR) - .zip(t2_str.split(SEPARATOR)) - .take_while(|(mod1_str, mod2_str)| mod1_str == mod2_str) - .map(|(mod_str, _)| mod_str.len() + separator_len) - .sum(); + let split_idx: usize = + iter::zip(t1_str.split(SEPARATOR), t2_str.split(SEPARATOR)) + .take_while(|(mod1_str, mod2_str)| mod1_str == mod2_str) + .map(|(mod_str, _)| mod_str.len() + separator_len) + .sum(); debug!( "cmp: separator_len={}, split_idx={}, min_len={}", @@ -1907,7 +1904,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .find_map(|(path, msg)| (&path_str == path).then_some(msg)) { let mut show_suggestion = true; - for (exp_ty, found_ty) in exp_substs.types().zip(found_substs.types()) { + for (exp_ty, found_ty) in + iter::zip(exp_substs.types(), found_substs.types()) + { match *exp_ty.kind() { ty::Ref(_, exp_ty, _) => { match (exp_ty.kind(), found_ty.kind()) { diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 4ec229ebcf5..d352214b579 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -19,6 +19,7 @@ #![feature(const_fn)] #![feature(const_panic)] #![feature(extend_one)] +#![feature(iter_zip)] #![feature(never_type)] #![cfg_attr(bootstrap, feature(or_patterns))] #![feature(in_band_lifetimes)] diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index ad15af9ab3f..0ac4b6b25bb 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -9,6 +9,7 @@ use rustc_middle::ty::TyCtxt; use rustc_span::symbol::Symbol; use rustc_span::{MultiSpan, Span}; use std::fmt; +use std::iter; impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn report_extra_impl_obligation( @@ -94,7 +95,7 @@ pub fn report_object_safety_error( note_span .push_span_label(trait_span, "this trait cannot be made into an object...".to_string()); } - for (span, msg) in multi_span.into_iter().zip(messages.into_iter()) { + for (span, msg) in iter::zip(multi_span, messages) { note_span.push_span_label(span, msg); } err.span_note( diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index c9de85a2f18..cf2f1489e02 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -45,6 +45,7 @@ use rustc_target::abi::LayoutOf; use tracing::debug; use std::cell::Cell; +use std::iter; use std::slice; /// Information about the registered lints. @@ -864,7 +865,7 @@ impl<'tcx> LateContext<'tcx> { pub fn match_def_path(&self, def_id: DefId, path: &[Symbol]) -> bool { let names = self.get_def_path(def_id); - names.len() == path.len() && names.into_iter().zip(path.iter()).all(|(a, &b)| a == b) + names.len() == path.len() && iter::zip(names, path).all(|(a, &b)| a == b) } /// Gets the absolute path of `def_id` as a vector of `Symbol`. diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index cacdf260548..c32f5714a67 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -33,6 +33,7 @@ #![feature(box_patterns)] #![feature(crate_visibility_modifier)] #![feature(iter_order_by)] +#![feature(iter_zip)] #![feature(never_type)] #![feature(nll)] #![cfg_attr(bootstrap, feature(or_patterns))] diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 2d311cc32f8..9c94bab04e9 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -17,6 +17,7 @@ use rustc_target::abi::{Integer, LayoutOf, TagEncoding, VariantIdx, Variants}; use rustc_target::spec::abi::Abi as SpecAbi; use std::cmp; +use std::iter; use std::ops::ControlFlow; use tracing::debug; @@ -1255,7 +1256,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { let sig = self.cx.tcx.fn_sig(def_id); let sig = self.cx.tcx.erase_late_bound_regions(sig); - for (input_ty, input_hir) in sig.inputs().iter().zip(decl.inputs) { + for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, false, false); } @@ -1355,10 +1356,7 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences { layout ); - let (largest, slargest, largest_index) = enum_definition - .variants - .iter() - .zip(variants) + let (largest, slargest, largest_index) = iter::zip(enum_definition.variants, variants) .map(|(variant, variant_layout)| { // Subtract the size of the enum tag. let bytes = variant_layout.size.bytes().saturating_sub(tag_size); diff --git a/compiler/rustc_macros/src/symbols/tests.rs b/compiler/rustc_macros/src/symbols/tests.rs index 82b4b876978..842d2a97718 100644 --- a/compiler/rustc_macros/src/symbols/tests.rs +++ b/compiler/rustc_macros/src/symbols/tests.rs @@ -43,7 +43,7 @@ fn test_symbols_macro(input: TokenStream, expected_errors: &[&str]) { "Macro generated a different number of errors than expected" ); - for (found_error, &expected_error) in found_errors.iter().zip(expected_errors.iter()) { + for (found_error, &expected_error) in found_errors.iter().zip(expected_errors) { let found_error_str = format!("{}", found_error); assert_eq!(found_error_str, expected_error); } diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index e106db38b2c..8a13ceec221 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -27,6 +27,7 @@ use crate::ty::{self, BoundVar, List, Region, TyCtxt}; use rustc_index::vec::IndexVec; use rustc_macros::HashStable; use smallvec::SmallVec; +use std::iter; use std::ops::Index; /// A "canonicalized" type `V` is one where all free inference @@ -315,10 +316,7 @@ impl<'tcx> CanonicalVarValues<'tcx> { use crate::ty::subst::GenericArgKind; CanonicalVarValues { - var_values: self - .var_values - .iter() - .zip(0..) + var_values: iter::zip(&self.var_values, 0..) .map(|(kind, i)| match kind.unpack() { GenericArgKind::Type(..) => { tcx.mk_ty(ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i).into())).into() diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 1561b3d7d29..bd0749792db 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -51,6 +51,7 @@ #![feature(exclusive_range_pattern)] #![feature(control_flow_enum)] #![feature(associated_type_defaults)] +#![feature(iter_zip)] #![recursion_limit = "512"] #[macro_use] diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index d05269913eb..807d6394800 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2329,7 +2329,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { CtorKind::Fn => fmt_tuple(fmt, &name), CtorKind::Fictive => { let mut struct_fmt = fmt.debug_struct(&name); - for (field, place) in variant_def.fields.iter().zip(places) { + for (field, place) in iter::zip(&variant_def.fields, places) { struct_fmt.field(&field.ident.as_str(), place); } struct_fmt.finish() @@ -2353,7 +2353,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { let mut struct_fmt = fmt.debug_struct(&name); if let Some(upvars) = tcx.upvars_mentioned(def_id) { - for (&var_id, place) in upvars.keys().zip(places) { + for (&var_id, place) in iter::zip(upvars.keys(), places) { let var_name = tcx.hir().name(var_id); struct_fmt.field(&var_name.as_str(), place); } @@ -2372,7 +2372,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { let mut struct_fmt = fmt.debug_struct(&name); if let Some(upvars) = tcx.upvars_mentioned(def_id) { - for (&var_id, place) in upvars.keys().zip(places) { + for (&var_id, place) in iter::zip(upvars.keys(), places) { let var_name = tcx.hir().name(var_id); struct_fmt.field(&var_name.as_str(), place); } diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 887dbefa9f2..c8db4aeb449 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -67,7 +67,7 @@ impl SwitchTargets { /// /// Note that this may yield 0 elements. Only the `otherwise` branch is mandatory. pub fn iter(&self) -> SwitchTargetsIter<'_> { - SwitchTargetsIter { inner: self.values.iter().zip(self.targets.iter()) } + SwitchTargetsIter { inner: iter::zip(&self.values, &self.targets) } } /// Returns a slice with all possible jump targets (including the fallback target). diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 57225b7abf7..8fdae695ceb 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -789,7 +789,7 @@ impl CanonicalUserType<'tcx> { return false; } - user_substs.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| { + iter::zip(user_substs.substs, BoundVar::new(0)..).all(|(kind, cvar)| { match kind.unpack() { GenericArgKind::Type(ty) => match ty.kind() { ty::Bound(debruijn, b) => { diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 3a75a6d907d..0d03cf4575f 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1251,13 +1251,13 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } else { // Try to use a ScalarPair for all tagged enums. let mut common_prim = None; - for (field_layouts, layout_variant) in variants.iter().zip(&layout_variants) { + for (field_layouts, layout_variant) in iter::zip(&variants, &layout_variants) { let offsets = match layout_variant.fields { FieldsShape::Arbitrary { ref offsets, .. } => offsets, _ => bug!(), }; let mut fields = - field_layouts.iter().zip(offsets).filter(|p| !p.0.is_zst()); + iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst()); let (field, offset) = match (fields.next(), fields.next()) { (None, None) => continue, (Some(pair), None) => pair, @@ -1626,7 +1626,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { const INVALID_FIELD_IDX: u32 = !0; let mut combined_inverse_memory_index = vec![INVALID_FIELD_IDX; promoted_memory_index.len() + memory_index.len()]; - let mut offsets_and_memory_index = offsets.into_iter().zip(memory_index); + let mut offsets_and_memory_index = iter::zip(offsets, memory_index); let combined_offsets = variant_fields .iter() .enumerate() diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 3b72cc011d6..f23c64cb036 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -19,6 +19,7 @@ use std::char; use std::collections::BTreeMap; use std::convert::TryFrom; use std::fmt::{self, Write as _}; +use std::iter; use std::ops::{ControlFlow, Deref, DerefMut}; // `pretty` is a separate module only for organization. @@ -1223,7 +1224,7 @@ pub trait PrettyPrinter<'tcx>: CtorKind::Fictive => { p!(" {{ "); let mut first = true; - for (field_def, field) in variant_def.fields.iter().zip(fields) { + for (field_def, field) in iter::zip(&variant_def.fields, fields) { if !first { p!(", "); } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index c936c30f456..1eb17d55a6a 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -149,7 +149,7 @@ pub fn relate_substs>( ) -> RelateResult<'tcx, SubstsRef<'tcx>> { let tcx = relation.tcx(); - let params = a_subst.iter().zip(b_subst).enumerate().map(|(i, (a, b))| { + let params = iter::zip(a_subst, b_subst).enumerate().map(|(i, (a, b))| { let variance = variances.map_or(ty::Invariant, |v| v[i]); relation.relate_with_variance(variance, a, b) }); @@ -179,12 +179,8 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { return Err(TypeError::ArgCount); } - let inputs_and_output = a - .inputs() - .iter() - .cloned() - .zip(b.inputs().iter().cloned()) - .map(|x| (x, false)) + let inputs_and_output = iter::zip(a.inputs(), b.inputs()) + .map(|(&a, &b)| ((a, b), false)) .chain(iter::once(((a.output(), b.output()), true))) .map(|((a, b), is_output)| { if is_output { @@ -308,7 +304,7 @@ impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> { ) -> RelateResult<'tcx, GeneratorWitness<'tcx>> { assert_eq!(a.0.len(), b.0.len()); let tcx = relation.tcx(); - let types = tcx.mk_type_list(a.0.iter().zip(b.0).map(|(a, b)| relation.relate(a, b)))?; + let types = tcx.mk_type_list(iter::zip(a.0, b.0).map(|(a, b)| relation.relate(a, b)))?; Ok(GeneratorWitness(types)) } } @@ -449,7 +445,7 @@ pub fn super_relate_tys>( (&ty::Tuple(as_), &ty::Tuple(bs)) => { if as_.len() == bs.len() { Ok(tcx.mk_tup( - as_.iter().zip(bs).map(|(a, b)| relation.relate(a.expect_ty(), b.expect_ty())), + iter::zip(as_, bs).map(|(a, b)| relation.relate(a.expect_ty(), b.expect_ty())), )?) } else if !(as_.is_empty() || bs.is_empty()) { Err(TypeError::TupleSize(expected_found(relation, as_.len(), bs.len()))) @@ -593,9 +589,7 @@ fn check_const_value_eq>( // Both the variant and each field have to be equal. if a_destructured.variant == b_destructured.variant { - for (a_field, b_field) in - a_destructured.fields.iter().zip(b_destructured.fields.iter()) - { + for (a_field, b_field) in iter::zip(a_destructured.fields, b_destructured.fields) { relation.consts(a_field, b_field)?; } @@ -631,7 +625,7 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List Ok(ty::Binder::bind(Trait( diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index cff8166974a..9926cca2f51 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -21,7 +21,7 @@ use rustc_macros::HashStable; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{Integer, Size, TargetDataLayout}; use smallvec::SmallVec; -use std::{cmp, fmt}; +use std::{cmp, fmt, iter}; #[derive(Copy, Clone, Debug)] pub struct Discr<'tcx> { @@ -414,9 +414,7 @@ impl<'tcx> TyCtxt<'tcx> { _ => bug!(), }; - let result = item_substs - .iter() - .zip(impl_substs.iter()) + let result = iter::zip(item_substs, impl_substs) .filter(|&(_, k)| { match k.unpack() { GenericArgKind::Lifetime(&ty::RegionKind::ReEarlyBound(ref ebr)) => { diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs index ec561fa3858..4f61b8d0910 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs @@ -18,6 +18,7 @@ use rustc_span::{ Span, }; use rustc_target::abi::VariantIdx; +use std::iter; use super::borrow_set::BorrowData; use super::MirBorrowckCtxt; @@ -970,13 +971,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind; debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr); if let hir::ExprKind::Closure(.., body_id, args_span, _) = expr { - for (captured_place, place) in self - .infcx - .tcx - .typeck(def_id.expect_local()) - .closure_min_captures_flattened(def_id) - .zip(places) - { + for (captured_place, place) in iter::zip( + self.infcx.tcx.typeck(def_id.expect_local()).closure_min_captures_flattened(def_id), + places, + ) { let upvar_hir_id = captured_place.get_root_variable(); //FIXME(project-rfc-2229#8): Use better span from captured_place let span = self.infcx.tcx.upvars_mentioned(local_did)?[&upvar_hir_id].span; diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs index 03738f1b40a..1f168c612f1 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs @@ -1,4 +1,5 @@ use std::fmt::{self, Display}; +use std::iter; use rustc_errors::DiagnosticBuilder; use rustc_hir as hir; @@ -536,7 +537,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // just worry about trying to match up the rustc type // with the HIR types: (ty::Tuple(elem_tys), hir::TyKind::Tup(elem_hir_tys)) => { - search_stack.extend(elem_tys.iter().map(|k| k.expect_ty()).zip(*elem_hir_tys)); + search_stack + .extend(iter::zip(elem_tys.iter().map(|k| k.expect_ty()), *elem_hir_tys)); } (ty::Slice(elem_ty), hir::TyKind::Slice(elem_hir_ty)) @@ -611,7 +613,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { args: &'hir hir::GenericArgs<'hir>, search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>, ) -> Option<&'hir hir::Lifetime> { - for (kind, hir_arg) in substs.iter().zip(args.args) { + for (kind, hir_arg) in iter::zip(substs, args.args) { match (kind.unpack(), hir_arg) { (GenericArgKind::Lifetime(r), hir::GenericArg::Lifetime(lt)) => { if r.to_region_vid() == needle_fr { diff --git a/compiler/rustc_mir/src/borrow_check/invalidation.rs b/compiler/rustc_mir/src/borrow_check/invalidation.rs index 17c4f3c6494..1055e30a3a4 100644 --- a/compiler/rustc_mir/src/borrow_check/invalidation.rs +++ b/compiler/rustc_mir/src/borrow_check/invalidation.rs @@ -5,6 +5,7 @@ use rustc_middle::mir::{BorrowKind, Mutability, Operand}; use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind}; use rustc_middle::mir::{Statement, StatementKind}; use rustc_middle::ty::TyCtxt; +use std::iter; use crate::dataflow::indexes::BorrowIndex; @@ -69,7 +70,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { self.mutate_place(location, **place, Shallow(None), JustWrite); } StatementKind::LlvmInlineAsm(asm) => { - for (o, output) in asm.asm.outputs.iter().zip(asm.outputs.iter()) { + for (o, output) in iter::zip(&asm.asm.outputs, &*asm.outputs) { if o.is_indirect { // FIXME(eddyb) indirect inline asm outputs should // be encoded through MIR place derefs instead. diff --git a/compiler/rustc_mir/src/borrow_check/mod.rs b/compiler/rustc_mir/src/borrow_check/mod.rs index 5b8bb7257e2..583f73d5775 100644 --- a/compiler/rustc_mir/src/borrow_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/mod.rs @@ -25,6 +25,7 @@ use either::Either; use smallvec::SmallVec; use std::cell::RefCell; use std::collections::BTreeMap; +use std::iter; use std::mem; use std::rc::Rc; @@ -595,7 +596,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc self.mutate_place(location, (**place, span), Shallow(None), JustWrite, flow_state); } StatementKind::LlvmInlineAsm(ref asm) => { - for (o, output) in asm.asm.outputs.iter().zip(asm.outputs.iter()) { + for (o, output) in iter::zip(&asm.asm.outputs, &*asm.outputs) { if o.is_indirect { // FIXME(eddyb) indirect inline asm outputs should // be encoded through MIR place derefs instead. diff --git a/compiler/rustc_mir/src/borrow_check/places_conflict.rs b/compiler/rustc_mir/src/borrow_check/places_conflict.rs index 02c7b7dc200..3654b51949e 100644 --- a/compiler/rustc_mir/src/borrow_check/places_conflict.rs +++ b/compiler/rustc_mir/src/borrow_check/places_conflict.rs @@ -5,6 +5,7 @@ use rustc_hir as hir; use rustc_middle::mir::{Body, BorrowKind, Local, Place, PlaceElem, PlaceRef, ProjectionElem}; use rustc_middle::ty::{self, TyCtxt}; use std::cmp::max; +use std::iter; /// When checking if a place conflicts with another place, this enum is used to influence decisions /// where a place might be equal or disjoint with another place, such as if `a[i] == a[j]`. @@ -139,7 +140,7 @@ fn place_components_conflict<'tcx>( // loop invariant: borrow_c is always either equal to access_c or disjoint from it. for (i, (borrow_c, &access_c)) in - borrow_place.projection.iter().zip(access_place.projection.iter()).enumerate() + iter::zip(borrow_place.projection, access_place.projection).enumerate() { debug!("borrow_conflicts_with_place: borrow_c = {:?}", borrow_c); let borrow_proj_base = &borrow_place.projection[..i]; diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs index aaa2bf4ff1b..fddd1401868 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -1770,7 +1770,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) { span_mirbug!(self, term, "call to {:?} with wrong # of args", sig); } - for (n, (fn_arg, op_arg)) in sig.inputs().iter().zip(args).enumerate() { + for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() { let op_arg_ty = op_arg.ty(body, self.tcx()); let op_arg_ty = self.normalize(op_arg_ty, term_location); let category = if from_hir_call { diff --git a/compiler/rustc_mir/src/borrow_check/universal_regions.rs b/compiler/rustc_mir/src/borrow_check/universal_regions.rs index 4b1acc1cd10..68fa9d8bf98 100644 --- a/compiler/rustc_mir/src/borrow_check/universal_regions.rs +++ b/compiler/rustc_mir/src/borrow_check/universal_regions.rs @@ -580,7 +580,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static)); let subst_mapping = - identity_substs.regions().zip(fr_substs.regions().map(|r| r.to_region_vid())); + iter::zip(identity_substs.regions(), fr_substs.regions().map(|r| r.to_region_vid())); UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect() } } diff --git a/compiler/rustc_mir/src/dataflow/framework/lattice.rs b/compiler/rustc_mir/src/dataflow/framework/lattice.rs index e7ef9267db5..f937b31f4cf 100644 --- a/compiler/rustc_mir/src/dataflow/framework/lattice.rs +++ b/compiler/rustc_mir/src/dataflow/framework/lattice.rs @@ -40,6 +40,7 @@ use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; +use std::iter; /// A [partially ordered set][poset] that has a [least upper bound][lub] for any pair of elements /// in the set. @@ -110,7 +111,7 @@ impl JoinSemiLattice for IndexVec { assert_eq!(self.len(), other.len()); let mut changed = false; - for (a, b) in self.iter_mut().zip(other.iter()) { + for (a, b) in iter::zip(self, other) { changed |= a.join(b); } changed @@ -122,7 +123,7 @@ impl MeetSemiLattice for IndexVec { assert_eq!(self.len(), other.len()); let mut changed = false; - for (a, b) in self.iter_mut().zip(other.iter()) { + for (a, b) in iter::zip(self, other) { changed |= a.meet(b); } changed diff --git a/compiler/rustc_mir/src/dataflow/impls/borrows.rs b/compiler/rustc_mir/src/dataflow/impls/borrows.rs index f24d0f0266d..c92cff1433f 100644 --- a/compiler/rustc_mir/src/dataflow/impls/borrows.rs +++ b/compiler/rustc_mir/src/dataflow/impls/borrows.rs @@ -11,6 +11,7 @@ use crate::borrow_check::{ use crate::dataflow::{self, fmt::DebugWithContext, GenKill}; use std::fmt; +use std::iter; rustc_index::newtype_index! { pub struct BorrowIndex { @@ -292,7 +293,7 @@ impl<'tcx> dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { } mir::StatementKind::LlvmInlineAsm(ref asm) => { - for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) { + for (output, kind) in iter::zip(&*asm.outputs, &asm.asm.outputs) { if !kind.is_indirect && !kind.is_rw { self.kill_borrows_on_place(trans, *output); } diff --git a/compiler/rustc_mir/src/dataflow/move_paths/builder.rs b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs index 1ddd81e779b..52b6e9f3753 100644 --- a/compiler/rustc_mir/src/dataflow/move_paths/builder.rs +++ b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs @@ -4,6 +4,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; use smallvec::{smallvec, SmallVec}; +use std::iter; use std::mem; use super::abs_domain::Lift; @@ -296,7 +297,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { self.create_move_path(**place); } StatementKind::LlvmInlineAsm(ref asm) => { - for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) { + for (output, kind) in iter::zip(&*asm.outputs, &asm.asm.outputs) { if !kind.is_indirect { self.gather_init(output.as_ref(), InitKind::Deep); } diff --git a/compiler/rustc_mir/src/lib.rs b/compiler/rustc_mir/src/lib.rs index 32354641412..b0db4f9e649 100644 --- a/compiler/rustc_mir/src/lib.rs +++ b/compiler/rustc_mir/src/lib.rs @@ -18,6 +18,7 @@ Rust MIR: a lowered representation of Rust. #![feature(decl_macro)] #![feature(exact_size_is_empty)] #![feature(exhaustive_patterns)] +#![feature(iter_zip)] #![feature(never_type)] #![feature(map_try_insert)] #![feature(min_specialization)] diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs index aabfee53acb..0e9728df73c 100644 --- a/compiler/rustc_mir/src/transform/coverage/debug.rs +++ b/compiler/rustc_mir/src/transform/coverage/debug.rs @@ -121,6 +121,7 @@ use rustc_middle::mir::coverage::*; use rustc_middle::mir::{self, BasicBlock, TerminatorKind}; use rustc_middle::ty::TyCtxt; +use std::iter; use std::lazy::SyncOnceCell; pub const NESTED_INDENT: &str = " "; @@ -703,9 +704,7 @@ pub(super) fn dump_coverage_graphviz( let edge_counters = from_terminator .successors() .map(|&successor_bb| graphviz_data.get_edge_counter(from_bcb, successor_bb)); - edge_labels - .iter() - .zip(edge_counters) + iter::zip(&edge_labels, edge_counters) .map(|(label, some_counter)| { if let Some(counter) = some_counter { format!("{}\n{}", label, debug_counters.format_counter(counter)) diff --git a/compiler/rustc_mir/src/transform/deduplicate_blocks.rs b/compiler/rustc_mir/src/transform/deduplicate_blocks.rs index e102512e1f3..c41e71e09a4 100644 --- a/compiler/rustc_mir/src/transform/deduplicate_blocks.rs +++ b/compiler/rustc_mir/src/transform/deduplicate_blocks.rs @@ -1,7 +1,7 @@ //! This pass finds basic blocks that are completely equal, //! and replaces all uses with just one of them. -use std::{collections::hash_map::Entry, hash::Hash, hash::Hasher}; +use std::{collections::hash_map::Entry, hash::Hash, hash::Hasher, iter}; use crate::transform::MirPass; @@ -115,11 +115,7 @@ impl<'tcx, 'a> PartialEq for BasicBlockHashable<'tcx, 'a> { fn eq(&self, other: &Self) -> bool { self.basic_block_data.statements.len() == other.basic_block_data.statements.len() && &self.basic_block_data.terminator().kind == &other.basic_block_data.terminator().kind - && self - .basic_block_data - .statements - .iter() - .zip(&other.basic_block_data.statements) + && iter::zip(&self.basic_block_data.statements, &other.basic_block_data.statements) .all(|(x, y)| statement_eq(&x.kind, &y.kind)) } } diff --git a/compiler/rustc_mir/src/transform/match_branches.rs b/compiler/rustc_mir/src/transform/match_branches.rs index d04a7011ab0..f7a9835353e 100644 --- a/compiler/rustc_mir/src/transform/match_branches.rs +++ b/compiler/rustc_mir/src/transform/match_branches.rs @@ -1,6 +1,7 @@ use crate::transform::MirPass; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; +use std::iter; use super::simplify::simplify_cfg; @@ -83,7 +84,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { if first_stmts.len() != scnd_stmts.len() { continue; } - for (f, s) in first_stmts.iter().zip(scnd_stmts.iter()) { + for (f, s) in iter::zip(first_stmts, scnd_stmts) { match (&f.kind, &s.kind) { // If two statements are exactly the same, we can optimize. (f_s, s_s) if f_s == s_s => {} @@ -113,7 +114,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { // and bb_idx has a different terminator from both of them. let (from, first, second) = bbs.pick3_mut(bb_idx, first, second); - let new_stmts = first.statements.iter().zip(second.statements.iter()).map(|(f, s)| { + let new_stmts = iter::zip(&first.statements, &second.statements).map(|(f, s)| { match (&f.kind, &s.kind) { (f_s, s_s) if f_s == s_s => (*f).clone(), 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 fbc9c30fe53..589a4467dca 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -17,6 +17,8 @@ use rustc_target::abi::VariantIdx; use rustc_index::vec::Idx; +use std::iter; + /// The "outermost" place that holds this value. #[derive(Copy, Clone, Debug, PartialEq)] crate enum PlaceBase { @@ -140,7 +142,7 @@ fn is_ancestor_or_same_capture( return false; } - proj_possible_ancestor.iter().zip(proj_capture).all(|(a, b)| a == b) + iter::zip(proj_possible_ancestor, proj_capture).all(|(a, b)| a == b) } /// Computes the index of a capture within the desugared closure provided the closure's diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index fc92e8019c2..2097f38c25d 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_hir as hir; use rustc_index::vec::Idx; use rustc_middle::mir::*; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation}; +use std::iter; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, storing the result into `destination`, which @@ -286,9 +287,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // MIR does not natively support FRU, so for each // base-supplied field, generate an operand that // reads it from the base. - field_names - .into_iter() - .zip(field_types.into_iter()) + iter::zip(field_names, *field_types) .map(|(n, ty)| match fields_map.get(&n) { Some(v) => v.clone(), None => { diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 9aca005ae91..23bc1da09b5 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -9,6 +9,7 @@ #![feature(control_flow_enum)] #![feature(crate_visibility_modifier)] #![feature(bool_to_option)] +#![feature(iter_zip)] #![feature(once_cell)] #![cfg_attr(bootstrap, feature(or_patterns))] #![recursion_limit = "256"] diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 7ad6bd2bb36..933e8ad1d72 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -9,6 +9,7 @@ #![feature(const_panic)] #![feature(crate_visibility_modifier)] #![feature(in_band_lifetimes)] +#![feature(iter_zip)] #![feature(nll)] #![cfg_attr(bootstrap, feature(or_patterns))] #![recursion_limit = "256"] diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 9aef49df7b4..f24309fa950 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -103,6 +103,7 @@ use rustc_span::Span; use std::collections::VecDeque; use std::io; use std::io::prelude::*; +use std::iter; use std::rc::Rc; mod rwu_table; @@ -1093,7 +1094,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { let ia = &asm.inner; let outputs = asm.outputs_exprs; let inputs = asm.inputs_exprs; - let succ = ia.outputs.iter().zip(outputs).rev().fold(succ, |succ, (o, output)| { + let succ = iter::zip(&ia.outputs, outputs).rev().fold(succ, |succ, (o, output)| { // see comment on places // in propagate_through_place_components() if o.is_indirect { @@ -1344,7 +1345,7 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) { } // Output operands must be places - for (o, output) in asm.inner.outputs.iter().zip(asm.outputs_exprs) { + for (o, output) in iter::zip(&asm.inner.outputs, asm.outputs_exprs) { if !o.is_indirect { this.check_place(output); } diff --git a/compiler/rustc_passes/src/liveness/rwu_table.rs b/compiler/rustc_passes/src/liveness/rwu_table.rs index a1a6f27398e..6d5983f53dc 100644 --- a/compiler/rustc_passes/src/liveness/rwu_table.rs +++ b/compiler/rustc_passes/src/liveness/rwu_table.rs @@ -1,4 +1,5 @@ use crate::liveness::{LiveNode, Variable}; +use std::iter; #[derive(Clone, Copy)] pub(super) struct RWU { @@ -91,7 +92,7 @@ impl RWUTable { let mut changed = false; let (dst_row, src_row) = self.pick2_rows_mut(dst, src); - for (dst_word, src_word) in dst_row.iter_mut().zip(src_row.iter()) { + for (dst_word, src_word) in iter::zip(dst_row, &*src_row) { let old = *dst_word; let new = *dst_word | src_word; *dst_word = new; diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 8a6ac843534..e54b1796aaa 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -22,6 +22,7 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use std::cmp::Ordering; +use std::iter; use std::mem::replace; use std::num::NonZeroU32; @@ -214,7 +215,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { { // Explicit version of iter::order::lt to handle parse errors properly for (dep_v, stab_v) in - dep_since.as_str().split('.').zip(stab_since.as_str().split('.')) + iter::zip(dep_since.as_str().split('.'), stab_since.as_str().split('.')) { match stab_v.parse::() { Err(_) => { diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index 26b76a9c006..3db57c0ab3a 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -3,6 +3,7 @@ #![feature(const_panic)] #![feature(core_intrinsics)] #![feature(hash_raw_entry)] +#![feature(iter_zip)] #![feature(min_specialization)] #![feature(stmt_expr_attributes)] diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 35a2ac865f2..21f580db04f 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -22,7 +22,7 @@ use { rustc_data_structures::{jobserver, OnDrop}, rustc_rayon_core as rayon_core, rustc_span::DUMMY_SP, - std::iter::FromIterator, + std::iter::{self, FromIterator}, std::{mem, process}, }; @@ -463,7 +463,7 @@ fn remove_cycle( spans.rotate_right(1); // Zip them back together - let mut stack: Vec<_> = spans.into_iter().zip(queries).collect(); + let mut stack: Vec<_> = iter::zip(spans, queries).collect(); // Remove the queries in our cycle from the list of jobs to look at for r in &stack { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index e85d78db22c..e659ce2c48e 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -22,6 +22,8 @@ use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP}; +use std::iter; + use tracing::debug; type Res = def::Res; @@ -1004,9 +1006,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { if let Some(spans) = field_spans.filter(|spans| spans.len() > 0 && fields.len() == spans.len()) { - let non_visible_spans: Vec = fields - .iter() - .zip(spans.iter()) + let non_visible_spans: Vec = iter::zip(&fields, &spans) .filter(|(vis, _)| { !self.r.is_accessible_from(**vis, self.parent_scope.module) }) diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 14e3d8498b0..8210da7b6ce 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -14,6 +14,7 @@ #![feature(control_flow_enum)] #![feature(crate_visibility_modifier)] #![feature(format_args_capture)] +#![feature(iter_zip)] #![feature(nll)] #![cfg_attr(bootstrap, feature(or_patterns))] #![recursion_limit = "256"] diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index eb5b7c4a74a..daecbe92250 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -413,7 +413,7 @@ pub fn update_dollar_crate_names(mut get_name: impl FnMut(SyntaxContext) -> Symb let names: Vec<_> = range_to_update.clone().map(|idx| get_name(SyntaxContext::from_u32(idx as u32))).collect(); HygieneData::with(|data| { - range_to_update.zip(names.into_iter()).for_each(|(idx, name)| { + range_to_update.zip(names).for_each(|(idx, name)| { data.syntax_context_data[idx].dollar_crate_name = name; }) }) diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index aeb7b149786..4097e1577e1 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -15,6 +15,7 @@ #![feature(box_patterns)] #![feature(drain_filter)] #![feature(in_band_lifetimes)] +#![feature(iter_zip)] #![feature(never_type)] #![feature(crate_visibility_modifier)] #![cfg_attr(bootstrap, feature(or_patterns))] diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 0d71fc57e39..b38e3fbaab4 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -12,6 +12,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use std::collections::hash_map::Entry; use std::collections::VecDeque; +use std::iter; // FIXME(twk): this is obviously not nice to duplicate like that #[derive(Eq, PartialEq, Hash, Copy, Clone, Debug)] @@ -428,7 +429,9 @@ impl AutoTraitFinder<'tcx> { return true; } - for (new_region, old_region) in new_substs.regions().zip(old_substs.regions()) { + for (new_region, old_region) in + iter::zip(new_substs.regions(), old_substs.regions()) + { match (new_region, old_region) { // If both predicates have an `ReLateBound` (a HRTB) in the // same spot, we do nothing. diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index e8ae1f44a36..38cb4ee66ca 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -74,23 +74,22 @@ where let impl2_ref = tcx.impl_trait_ref(impl2_def_id); // Check if any of the input types definitely do not unify. - if impl1_ref - .iter() - .flat_map(|tref| tref.substs.types()) - .zip(impl2_ref.iter().flat_map(|tref| tref.substs.types())) - .any(|(ty1, ty2)| { - let t1 = fast_reject::simplify_type(tcx, ty1, false); - let t2 = fast_reject::simplify_type(tcx, ty2, false); - if let (Some(t1), Some(t2)) = (t1, t2) { - // Simplified successfully - // Types cannot unify if they differ in their reference mutability or simplify to different types - t1 != t2 || ty1.ref_mutability() != ty2.ref_mutability() - } else { - // Types might unify - false - } - }) - { + if iter::zip( + impl1_ref.iter().flat_map(|tref| tref.substs.types()), + impl2_ref.iter().flat_map(|tref| tref.substs.types()), + ) + .any(|(ty1, ty2)| { + let t1 = fast_reject::simplify_type(tcx, ty1, false); + let t2 = fast_reject::simplify_type(tcx, ty2, false); + if let (Some(t1), Some(t2)) = (t1, t2) { + // Simplified successfully + // Types cannot unify if they differ in their reference mutability or simplify to different types + t1 != t2 || ty1.ref_mutability() != ty2.ref_mutability() + } else { + // Types might unify + false + } + }) { // Some types involved are definitely different, so the impls couldn't possibly overlap. debug!("overlapping_impls: fast_reject early-exit"); return no_overlap(); diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index ac987a9f7b3..8961cdaebf3 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -23,6 +23,7 @@ use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::Span; use std::cmp; +use std::iter; use std::ops::ControlFlow; /// Check if a given constant can be evaluated. @@ -672,9 +673,7 @@ pub(super) fn try_unify<'tcx>( if a_args.len() == b_args.len() => { try_unify(tcx, a.subtree(a_f), b.subtree(b_f)) - && a_args - .iter() - .zip(b_args) + && iter::zip(a_args, b_args) .all(|(&an, &bn)| try_unify(tcx, a.subtree(an), b.subtree(bn))) } _ => false, 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 060e4e36dfe..93a37bd4090 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -28,6 +28,7 @@ use rustc_session::DiagnosticMessageId; use rustc_span::symbol::{kw, sym}; use rustc_span::{ExpnKind, MultiSpan, Span, DUMMY_SP}; use std::fmt; +use std::iter; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use crate::traits::query::normalize::AtExt as _; @@ -161,7 +162,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } } - for (error, suppressed) in errors.iter().zip(is_suppressed) { + for (error, suppressed) in iter::zip(errors, is_suppressed) { if !suppressed { self.report_fulfillment_error(error, body_id, fallback_has_occurred); } 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 cecdcc97896..979c56004ee 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 @@ -7,6 +7,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, GenericParamDefKind}; use rustc_span::symbol::sym; +use std::iter; use super::InferCtxtPrivExt; @@ -51,12 +52,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) { self_match_impls.push(def_id); - if trait_ref - .substs - .types() - .skip(1) - .zip(impl_trait_ref.substs.types().skip(1)) - .all(|(u, v)| self.fuzzy_match_tys(u, v)) + if iter::zip( + trait_ref.substs.types().skip(1), + impl_trait_ref.substs.types().skip(1), + ) + .all(|(u, v)| self.fuzzy_match_tys(u, v)) { fuzzy_match_impls.push(def_id); } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index bc8a0eae0e0..45680c90cdc 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1887,7 +1887,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // substitution if we find that any of the input types, when // simplified, do not match. - obligation.predicate.skip_binder().trait_ref.substs.iter().zip(impl_trait_ref.substs).any( + iter::zip(obligation.predicate.skip_binder().trait_ref.substs, impl_trait_ref.substs).any( |(obligation_arg, impl_arg)| { match (obligation_arg.unpack(), impl_arg.unpack()) { (GenericArgKind::Type(obligation_ty), GenericArgKind::Type(impl_ty)) => { diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index aee128dec7d..3d5f8d128dc 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -692,11 +692,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { let predicates = predicates.instantiate(self.infcx.tcx, substs); debug_assert_eq!(predicates.predicates.len(), origins.len()); - predicates - .predicates - .into_iter() - .zip(predicates.spans.into_iter()) - .zip(origins.into_iter().rev()) + iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev()) .map(|((pred, span), origin_def_id)| { let cause = self.cause(traits::BindingObligation(origin_def_id, span)); traits::Obligation::with_depth(cause, self.recursion_depth, self.param_env, pred) diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs index b5404c3a15c..695132281c6 100644 --- a/compiler/rustc_typeck/src/astconv/errors.rs +++ b/compiler/rustc_typeck/src/astconv/errors.rs @@ -10,6 +10,7 @@ use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, DUMMY_SP}; use std::collections::BTreeSet; +use std::iter; impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// On missing type parameters, emit an E0393 error and provide a structured suggestion using @@ -309,7 +310,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // that the user forgot to give the associtated type's name. The canonical // example would be trying to use `Iterator` instead of // `Iterator`. - for (potential, item) in potential_assoc_types.iter().zip(assoc_items.iter()) { + for (potential, item) in iter::zip(&potential_assoc_types, assoc_items) { if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(*potential) { suggestions.push((*potential, format!("{} = {}", item.ident, snippet))); } diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index a29f5518009..b48102e0fc9 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -17,6 +17,7 @@ use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use rustc_target::spec::abi; use rustc_trait_selection::autoderef::Autoderef; +use std::iter; /// Checks that it is legal to call methods of the trait corresponding /// to `trait_id` (this only cares about the trait, not the specific @@ -539,7 +540,7 @@ impl<'a, 'tcx> DeferredCallResolution<'tcx> { debug!("attempt_resolution: method_callee={:?}", method_callee); for (method_arg_ty, self_arg_ty) in - method_sig.inputs().iter().skip(1).zip(self.fn_sig.inputs()) + iter::zip(method_sig.inputs().iter().skip(1), self.fn_sig.inputs()) { fcx.demand_eqtype(self.call_expr.span, &self_arg_ty, &method_arg_ty); } diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index e2fc1da5c78..892abb5a344 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -26,6 +26,7 @@ use rustc_trait_selection::opaque_types::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; use rustc_trait_selection::traits::{self, ObligationCauseCode}; +use std::iter; use std::ops::ControlFlow; pub fn check_wf_new(tcx: TyCtxt<'_>) { @@ -1472,7 +1473,7 @@ fn check_enum<'tcx>( } let mut disr_vals: Vec> = Vec::with_capacity(vs.len()); - for ((_, discr), v) in def.discriminants(tcx).zip(vs) { + for ((_, discr), v) in iter::zip(def.discriminants(tcx), vs) { // Check for duplicate discriminant values if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) { let variant_did = def.variants[VariantIdx::new(i)].def_id; diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs index 431e6d70ff3..4099ecd435d 100644 --- a/compiler/rustc_typeck/src/check/closure.rs +++ b/compiler/rustc_typeck/src/check/closure.rs @@ -492,13 +492,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // The liberated version of this signature should be a subtype // of the liberated form of the expectation. - for ((hir_ty, &supplied_ty), expected_ty) in decl - .inputs - .iter() - .zip(supplied_sig.inputs().skip_binder()) // binder moved to (*) below - .zip(expected_sigs.liberated_sig.inputs()) - // `liberated_sig` is E'. - { + for ((hir_ty, &supplied_ty), expected_ty) in iter::zip( + iter::zip( + decl.inputs, + supplied_sig.inputs().skip_binder(), // binder moved to (*) below + ), + expected_sigs.liberated_sig.inputs(), // `liberated_sig` is E'. + ) { // Instantiate (this part of..) S to S', i.e., with fresh variables. let (supplied_ty, _) = self.infcx.replace_bound_vars_with_fresh_vars( hir_ty.span, diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index ddb11b9f3b1..70f850084a8 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -14,6 +14,7 @@ use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt}; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::InferCtxtExt; use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, Reveal}; +use std::iter; use super::{potentially_plural_count, FnCtxt, Inherited}; @@ -410,8 +411,7 @@ fn extract_spans_for_error_reporting<'a, 'tcx>( _ => bug!("{:?} is not a TraitItemKind::Fn", trait_m), }; - impl_m_iter - .zip(trait_m_iter) + iter::zip(impl_m_iter, trait_m_iter) .find(|&(ref impl_arg, ref trait_arg)| { match (&impl_arg.kind, &trait_arg.kind) { ( @@ -443,11 +443,8 @@ fn extract_spans_for_error_reporting<'a, 'tcx>( let impl_iter = impl_sig.inputs().iter(); let trait_iter = trait_sig.inputs().iter(); - impl_iter - .zip(trait_iter) - .zip(impl_m_iter) - .zip(trait_m_iter) - .find_map(|(((&impl_arg_ty, &trait_arg_ty), impl_arg), trait_arg)| match infcx + iter::zip(iter::zip(impl_iter, trait_iter), iter::zip(impl_m_iter, trait_m_iter)) + .find_map(|((&impl_arg_ty, &trait_arg_ty), (impl_arg, trait_arg))| match infcx .at(&cause, param_env) .sub(trait_arg_ty, impl_arg_ty) { @@ -799,7 +796,7 @@ fn compare_synthetic_generics<'tcx>( GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => None, }); for ((impl_def_id, impl_synthetic), (trait_def_id, trait_synthetic)) in - impl_m_type_params.zip(trait_m_type_params) + iter::zip(impl_m_type_params, trait_m_type_params) { if impl_synthetic != trait_synthetic { let impl_hir_id = tcx.hir().local_def_id_to_hir_id(impl_def_id.expect_local()); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 56ff9293dd8..e64d8367676 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -42,6 +42,7 @@ use rustc_trait_selection::traits::{ }; use std::collections::hash_map::Entry; +use std::iter; use std::slice; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -1146,7 +1147,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ( hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }), hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }), - ) if last_bounds.iter().zip(exp_bounds.iter()).all(|(left, right)| { + ) if iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| { match (left, right) { ( hir::GenericBound::Trait(tl, ml), diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index c92c7f7ad0b..80b5a9d4e62 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -23,6 +23,7 @@ use rustc_span::{self, MultiSpan, Span}; use rustc_trait_selection::traits::{self, ObligationCauseCode, StatementAsExpression}; use crate::structured_errors::StructuredDiagnostic; +use std::iter; use std::slice; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -108,7 +109,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // All the input types from the fn signature must outlive the call // so as to validate implied bounds. - for (&fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) { + for (&fn_input_ty, arg_expr) in iter::zip(fn_inputs, args) { self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation); } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index f90159efb5c..bd89c7274e7 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -218,8 +218,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span); let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id); if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) { - let mut suggestions = iter::repeat(&expr_text) - .zip(methods.iter()) + let mut suggestions = iter::zip(iter::repeat(&expr_text), &methods) .filter_map(|(receiver, method)| { let method_call = format!(".{}()", method.ident); if receiver.ends_with(&method_call) { diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index 731a72ff024..fff659a91ad 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -15,6 +15,7 @@ use rustc_middle::ty::{self, GenericParamDefKind, Ty}; use rustc_span::Span; use rustc_trait_selection::traits; +use std::iter; use std::ops::Deref; struct ConfirmContext<'a, 'tcx> { @@ -496,10 +497,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // We don't care about regions here. .filter_map(|obligation| match obligation.predicate.kind().skip_binder() { ty::PredicateKind::Trait(trait_pred, _) if trait_pred.def_id() == sized_def_id => { - let span = predicates - .predicates - .iter() - .zip(predicates.spans.iter()) + let span = iter::zip(&predicates.predicates, &predicates.spans) .find_map( |(p, span)| { if *p == obligation.predicate { Some(*span) } else { None } diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 5a939cc24f5..91021b3f6f5 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -49,6 +49,8 @@ use rustc_span::{MultiSpan, Span, Symbol}; use rustc_index::vec::Idx; use rustc_target::abi::VariantIdx; +use std::iter; + /// Describe the relationship between the paths of two places /// eg: /// - `foo` is ancestor of `foo.bar.baz` @@ -1631,7 +1633,7 @@ fn determine_place_ancestry_relation( let projections_b = &place_b.projections; let same_initial_projections = - projections_a.iter().zip(projections_b.iter()).all(|(proj_a, proj_b)| proj_a == proj_b); + iter::zip(projections_a, projections_b).all(|(proj_a, proj_b)| proj_a == proj_b); if same_initial_projections { // First min(n, m) projections are the same diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 5f302f7d0a9..e7e603c8bd5 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -24,6 +24,7 @@ use rustc_trait_selection::opaque_types::may_define_opaque_type; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode}; +use std::iter; use std::ops::ControlFlow; /// Helper type of a temporary returned by `.for_item(...)`. @@ -863,7 +864,7 @@ fn check_where_clauses<'tcx, 'fcx>( debug!("check_where_clauses: predicates={:?}", predicates.predicates); assert_eq!(predicates.predicates.len(), predicates.spans.len()); let wf_obligations = - predicates.predicates.iter().zip(predicates.spans.iter()).flat_map(|(&p, &sp)| { + iter::zip(&predicates.predicates, &predicates.spans).flat_map(|(&p, &sp)| { traits::wf::predicate_obligations(fcx, fcx.param_env, fcx.body_id, p, sp) }); @@ -885,8 +886,8 @@ fn check_fn_or_method<'fcx, 'tcx>( let sig = fcx.normalize_associated_types_in(span, sig); let sig = fcx.tcx.liberate_late_bound_regions(def_id, sig); - for (&input_ty, span) in sig.inputs().iter().zip(hir_decl.inputs.iter().map(|t| t.span)) { - fcx.register_wf_obligation(input_ty.into(), span, ObligationCauseCode::MiscObligation); + for (&input_ty, ty) in iter::zip(sig.inputs(), hir_decl.inputs) { + fcx.register_wf_obligation(input_ty.into(), ty.span, ObligationCauseCode::MiscObligation); } implied_bounds.extend(sig.inputs()); diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 631f2c7a69a..9b3a933beb1 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -50,6 +50,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::abi; use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName; +use std::iter; mod item_bounds; mod type_of; @@ -2439,7 +2440,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( .emit(); } }; - for (input, ty) in decl.inputs.iter().zip(fty.inputs().skip_binder()) { + for (input, ty) in iter::zip(decl.inputs, fty.inputs().skip_binder()) { check(&input, ty) } if let hir::FnRetTy::Return(ref ty) = decl.output { diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index b172cb9c44b..ab286bacd81 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -18,6 +18,7 @@ use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, adjustment, TyCtxt}; use rustc_target::abi::VariantIdx; +use std::iter; use crate::mem_categorization as mc; @@ -333,7 +334,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } hir::ExprKind::LlvmInlineAsm(ref ia) => { - for (o, output) in ia.inner.outputs.iter().zip(ia.outputs_exprs) { + for (o, output) in iter::zip(&ia.inner.outputs, ia.outputs_exprs) { if o.is_indirect { self.consume_expr(output); } else { diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index c270a236811..cb442344fa2 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -63,6 +63,7 @@ This API is completely unstable and subject to change. #![feature(format_args_capture)] #![feature(in_band_lifetimes)] #![feature(is_sorted)] +#![feature(iter_zip)] #![feature(nll)] #![cfg_attr(bootstrap, feature(or_patterns))] #![feature(try_blocks)] From e82e8129e728e9202cfae89daa22987cf49c32af Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 8 Mar 2021 15:57:44 -0800 Subject: [PATCH 120/370] Use iter::zip in src/tools/clippy/ --- .../src/default_numeric_fallback.rs | 5 +-- src/tools/clippy/clippy_lints/src/lib.rs | 1 + .../src/literal_representation.rs | 3 +- .../src/loops/needless_range_loop.rs | 4 +-- src/tools/clippy/clippy_lints/src/matches.rs | 3 +- src/tools/clippy/clippy_lints/src/mut_key.rs | 3 +- .../clippy/clippy_lints/src/mut_reference.rs | 3 +- .../clippy_lints/src/pass_by_ref_or_value.rs | 3 +- .../clippy_lints/src/pattern_type_mismatch.rs | 3 +- .../clippy_lints/src/unnecessary_sort_by.rs | 31 ++++++++----------- src/tools/clippy/clippy_utils/src/consts.rs | 13 ++++---- src/tools/clippy/clippy_utils/src/lib.rs | 1 + .../clippy_utils/src/numeric_literal.rs | 3 +- 13 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs index d136db9373c..73f71d88b05 100644 --- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs +++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs @@ -13,6 +13,7 @@ use rustc_middle::{ ty::{self, FloatTy, IntTy, PolyFnSig, Ty}, }; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use std::iter; declare_clippy_lint! { /// **What it does:** Checks for usage of unconstrained numeric literals which may cause default numeric fallback in type @@ -107,7 +108,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> { match &expr.kind { ExprKind::Call(func, args) => { if let Some(fn_sig) = fn_sig_opt(self.cx, func.hir_id) { - for (expr, bound) in args.iter().zip(fn_sig.skip_binder().inputs().iter()) { + for (expr, bound) in iter::zip(*args, fn_sig.skip_binder().inputs()) { // Push found arg type, then visit arg. self.ty_bounds.push(TyBound::Ty(bound)); self.visit_expr(expr); @@ -120,7 +121,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> { ExprKind::MethodCall(_, _, args, _) => { if let Some(def_id) = self.cx.typeck_results().type_dependent_def_id(expr.hir_id) { let fn_sig = self.cx.tcx.fn_sig(def_id).skip_binder(); - for (expr, bound) in args.iter().zip(fn_sig.inputs().iter()) { + for (expr, bound) in iter::zip(*args, fn_sig.inputs()) { self.ty_bounds.push(TyBound::Ty(bound)); self.visit_expr(expr); self.ty_bounds.pop(); diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index 1c3841f8efd..a99ed7656bf 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -4,6 +4,7 @@ #![feature(box_syntax)] #![feature(drain_filter)] #![feature(in_band_lifetimes)] +#![feature(iter_zip)] #![feature(once_cell)] #![cfg_attr(bootstrap, feature(or_patterns))] #![feature(rustc_private)] diff --git a/src/tools/clippy/clippy_lints/src/literal_representation.rs b/src/tools/clippy/clippy_lints/src/literal_representation.rs index 7fd55151226..54470519260 100644 --- a/src/tools/clippy/clippy_lints/src/literal_representation.rs +++ b/src/tools/clippy/clippy_lints/src/literal_representation.rs @@ -13,6 +13,7 @@ use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_tool_lint, impl_lint_pass}; +use std::iter; declare_clippy_lint! { /// **What it does:** Warns if a long integral or floating-point constant does @@ -349,7 +350,7 @@ impl LiteralDigitGrouping { let group_sizes: Vec = num_lit.integer.split('_').map(str::len).collect(); if UUID_GROUP_LENS.len() == group_sizes.len() { - UUID_GROUP_LENS.iter().zip(&group_sizes).all(|(&a, &b)| a == b) + iter::zip(&UUID_GROUP_LENS, &group_sizes).all(|(&a, &b)| a == b) } else { false } diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs index 3c40d54cb42..64ab3b6bfec 100644 --- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs @@ -17,7 +17,7 @@ use rustc_middle::hir::map::Map; use rustc_middle::middle::region; use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::{sym, Symbol}; -use std::iter::Iterator; +use std::iter::{self, Iterator}; use std::mem; /// Checks for looping over a range and then indexing a sequence with it. @@ -369,7 +369,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> { }, ExprKind::MethodCall(_, _, args, _) => { let def_id = self.cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap(); - for (ty, expr) in self.cx.tcx.fn_sig(def_id).inputs().skip_binder().iter().zip(args) { + for (ty, expr) in iter::zip(self.cx.tcx.fn_sig(def_id).inputs().skip_binder(), args) { self.prefer_mutable = false; if let ty::Ref(_, _, mutbl) = *ty.kind() { if mutbl == Mutability::Mut { diff --git a/src/tools/clippy/clippy_lints/src/matches.rs b/src/tools/clippy/clippy_lints/src/matches.rs index 3680429fed7..2f2dc4cfc6b 100644 --- a/src/tools/clippy/clippy_lints/src/matches.rs +++ b/src/tools/clippy/clippy_lints/src/matches.rs @@ -29,6 +29,7 @@ use rustc_span::source_map::{Span, Spanned}; use rustc_span::sym; use std::cmp::Ordering; use std::collections::hash_map::Entry; +use std::iter; use std::ops::Bound; declare_clippy_lint! { @@ -1668,7 +1669,7 @@ where values.sort(); - for (a, b) in values.iter().zip(values.iter().skip(1)) { + for (a, b) in iter::zip(&values, &values[1..]) { match (a, b) { (&Kind::Start(_, ra), &Kind::End(_, rb)) => { if ra.node != rb.node { diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs index 41bd07bcf1e..4d3dff36a20 100644 --- a/src/tools/clippy/clippy_lints/src/mut_key.rs +++ b/src/tools/clippy/clippy_lints/src/mut_key.rs @@ -6,6 +6,7 @@ use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::{Adt, Array, RawPtr, Ref, Slice, Tuple, Ty, TypeAndMut}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; +use std::iter; declare_clippy_lint! { /// **What it does:** Checks for sets/maps with mutable key types. @@ -87,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableKeyType { fn check_sig<'tcx>(cx: &LateContext<'tcx>, item_hir_id: hir::HirId, decl: &hir::FnDecl<'_>) { let fn_def_id = cx.tcx.hir().local_def_id(item_hir_id); let fn_sig = cx.tcx.fn_sig(fn_def_id); - for (hir_ty, ty) in decl.inputs.iter().zip(fn_sig.inputs().skip_binder().iter()) { + for (hir_ty, ty) in iter::zip(decl.inputs, fn_sig.inputs().skip_binder()) { check_ty(cx, hir_ty.span, ty); } check_ty(cx, decl.output.span(), cx.tcx.erase_late_bound_regions(fn_sig.output())); diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs index 0c09ddb8073..05457e80d52 100644 --- a/src/tools/clippy/clippy_lints/src/mut_reference.rs +++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs @@ -4,6 +4,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use std::iter; declare_clippy_lint! { /// **What it does:** Detects passing a mutable reference to a function that only @@ -64,7 +65,7 @@ fn check_arguments<'tcx>( match type_definition.kind() { ty::FnDef(..) | ty::FnPtr(_) => { let parameters = type_definition.fn_sig(cx.tcx).skip_binder().inputs(); - for (argument, parameter) in arguments.iter().zip(parameters.iter()) { + for (argument, parameter) in iter::zip(arguments, parameters) { match parameter.kind() { ty::Ref(_, _, Mutability::Not) | ty::RawPtr(ty::TypeAndMut { diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index 9a5b1c3b944..e151f85a391 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -1,4 +1,5 @@ use std::cmp; +use std::iter; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::is_self_ty; @@ -122,7 +123,7 @@ impl<'tcx> PassByRefOrValue { let fn_body = cx.enclosing_body.map(|id| cx.tcx.hir().body(id)); - for (index, (input, &ty)) in decl.inputs.iter().zip(fn_sig.inputs()).enumerate() { + for (index, (input, &ty)) in iter::zip(decl.inputs, fn_sig.inputs()).enumerate() { // All spans generated from a proc-macro invocation are the same... match span { Some(s) if s == input.span => return, diff --git a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs index 4550b367da4..c0c2ab67e38 100644 --- a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs +++ b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs @@ -10,6 +10,7 @@ use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{AdtDef, FieldDef, Ty, TyKind, VariantDef}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; +use std::iter; declare_clippy_lint! { /// **What it does:** Checks for patterns that aren't exact representations of the types @@ -134,7 +135,7 @@ impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch { hir_id: HirId, ) { if let Some(fn_sig) = cx.typeck_results().liberated_fn_sigs().get(hir_id) { - for (param, ty) in body.params.iter().zip(fn_sig.inputs().iter()) { + for (param, ty) in iter::zip(body.params, fn_sig.inputs()) { apply_lint(cx, ¶m.pat, ty, DerefPossible::Impossible); } } diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs index e23bab5eba0..6becff9662a 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs @@ -9,6 +9,7 @@ use rustc_middle::ty::{self, subst::GenericArgKind}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; use rustc_span::symbol::Ident; +use std::iter; declare_clippy_lint! { /// **What it does:** @@ -79,17 +80,15 @@ fn mirrored_exprs( mirrored_exprs(cx, left_expr, a_ident, right_expr, b_ident) }, // Two arrays with mirrored contents - (ExprKind::Array(left_exprs), ExprKind::Array(right_exprs)) => left_exprs - .iter() - .zip(right_exprs.iter()) - .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident)), + (ExprKind::Array(left_exprs), ExprKind::Array(right_exprs)) => { + iter::zip(*left_exprs, *right_exprs) + .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident)) + } // The two exprs are function calls. // Check to see that the function itself and its arguments are mirrored (ExprKind::Call(left_expr, left_args), ExprKind::Call(right_expr, right_args)) => { mirrored_exprs(cx, left_expr, a_ident, right_expr, b_ident) - && left_args - .iter() - .zip(right_args.iter()) + && iter::zip(*left_args, *right_args) .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident)) }, // The two exprs are method calls. @@ -100,16 +99,14 @@ fn mirrored_exprs( ExprKind::MethodCall(right_segment, _, right_args, _), ) => { left_segment.ident == right_segment.ident - && left_args - .iter() - .zip(right_args.iter()) + && iter::zip(*left_args, *right_args) .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident)) - }, + } // Two tuples with mirrored contents - (ExprKind::Tup(left_exprs), ExprKind::Tup(right_exprs)) => left_exprs - .iter() - .zip(right_exprs.iter()) - .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident)), + (ExprKind::Tup(left_exprs), ExprKind::Tup(right_exprs)) => { + iter::zip(*left_exprs, *right_exprs) + .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident)) + } // Two binary ops, which are the same operation and which have mirrored arguments (ExprKind::Binary(left_op, left_left, left_right), ExprKind::Binary(right_op, right_left, right_right)) => { left_op.node == right_op.node @@ -146,9 +143,7 @@ fn mirrored_exprs( }, )), ) => { - (left_segments - .iter() - .zip(right_segments.iter()) + (iter::zip(*left_segments, *right_segments) .all(|(left, right)| left.ident == right.ident) && left_segments .iter() diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index ebe896b7ae8..8af10ebe777 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -15,6 +15,7 @@ use rustc_span::symbol::Symbol; use std::cmp::Ordering::{self, Equal}; use std::convert::TryInto; use std::hash::{Hash, Hasher}; +use std::iter; /// A `LitKind`-like enum to fold constant `Expr`s into. #[derive(Debug, Clone)] @@ -139,12 +140,12 @@ impl Constant { (&Self::F64(l), &Self::F64(r)) => l.partial_cmp(&r), (&Self::F32(l), &Self::F32(r)) => l.partial_cmp(&r), (&Self::Bool(ref l), &Self::Bool(ref r)) => Some(l.cmp(r)), - (&Self::Tuple(ref l), &Self::Tuple(ref r)) | (&Self::Vec(ref l), &Self::Vec(ref r)) => l - .iter() - .zip(r.iter()) - .map(|(li, ri)| Self::partial_cmp(tcx, cmp_type, li, ri)) - .find(|r| r.map_or(true, |o| o != Ordering::Equal)) - .unwrap_or_else(|| Some(l.len().cmp(&r.len()))), + (&Self::Tuple(ref l), &Self::Tuple(ref r)) | (&Self::Vec(ref l), &Self::Vec(ref r)) => { + iter::zip(l, r) + .map(|(li, ri)| Self::partial_cmp(tcx, cmp_type, li, ri)) + .find(|r| r.map_or(true, |o| o != Ordering::Equal)) + .unwrap_or_else(|| Some(l.len().cmp(&r.len()))) + } (&Self::Repeat(ref lv, ref ls), &Self::Repeat(ref rv, ref rs)) => { match Self::partial_cmp(tcx, cmp_type, lv, rv) { Some(Equal) => Some(ls.cmp(rs)), diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index b613ae9b918..b2655f8d797 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1,5 +1,6 @@ #![feature(box_patterns)] #![feature(in_band_lifetimes)] +#![feature(iter_zip)] #![cfg_attr(bootstrap, feature(or_patterns))] #![feature(rustc_private)] #![recursion_limit = "512"] diff --git a/src/tools/clippy/clippy_utils/src/numeric_literal.rs b/src/tools/clippy/clippy_utils/src/numeric_literal.rs index d02603d7702..268bc5b3205 100644 --- a/src/tools/clippy/clippy_utils/src/numeric_literal.rs +++ b/src/tools/clippy/clippy_utils/src/numeric_literal.rs @@ -1,4 +1,5 @@ use rustc_ast::ast::{Lit, LitFloatType, LitIntType, LitKind}; +use std::iter; #[derive(Debug, PartialEq, Copy, Clone)] pub enum Radix { @@ -192,7 +193,7 @@ impl<'a> NumericLiteral<'a> { } } - for (c, i) in digits.zip((0..group_size).cycle()) { + for (c, i) in iter::zip(digits, (0..group_size).cycle()) { if i == 0 { output.push('_'); } From 147316a09449b35737d2d1af8987a1da375efe22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Fri, 26 Mar 2021 19:44:06 +0100 Subject: [PATCH 121/370] Document that the SocketAddr memory representation is not stable --- library/std/src/net/addr.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/library/std/src/net/addr.rs b/library/std/src/net/addr.rs index 63de8712834..55546a5b037 100644 --- a/library/std/src/net/addr.rs +++ b/library/std/src/net/addr.rs @@ -57,7 +57,8 @@ pub enum SocketAddr { /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// /// The size of a `SocketAddrV4` struct may vary depending on the target operating -/// system. +/// system. Do not assume that this type has the same memory layout as the underlying +/// system representation. /// /// [IETF RFC 793]: https://tools.ietf.org/html/rfc793 /// [`IPv4` address]: Ipv4Addr @@ -76,6 +77,8 @@ pub enum SocketAddr { #[derive(Copy)] #[stable(feature = "rust1", since = "1.0.0")] pub struct SocketAddrV4 { + // Do not assume that this struct is implemented as the underlying system representation. + // The memory layout is not part of the stable interface that std exposes. inner: c::sockaddr_in, } @@ -88,7 +91,8 @@ pub struct SocketAddrV4 { /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// /// The size of a `SocketAddrV6` struct may vary depending on the target operating -/// system. +/// system. Do not assume that this type has the same memory layout as the underlying +/// system representation. /// /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3 /// [`IPv6` address]: Ipv6Addr @@ -107,6 +111,8 @@ pub struct SocketAddrV4 { #[derive(Copy)] #[stable(feature = "rust1", since = "1.0.0")] pub struct SocketAddrV6 { + // Do not assume that this struct is implemented as the underlying system representation. + // The memory layout is not part of the stable interface that std exposes. inner: c::sockaddr_in6, } From 7ca2c981b28676a8411e0b2c96db001b9633c1d2 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 26 Mar 2021 19:52:09 +0100 Subject: [PATCH 122/370] fix doc comment for `ty::Dynamic --- compiler/rustc_middle/src/ty/sty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 2cd969d7a16..e78e928398f 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -160,7 +160,7 @@ pub enum TyKind<'tcx> { /// ``` FnPtr(PolyFnSig<'tcx>), - /// A trait, defined with `trait`. + /// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`. Dynamic(&'tcx List>>, ty::Region<'tcx>), /// The anonymous type of a closure. Used to represent the type of From ea194b8b33dc63da3c094e987f41c661c4227014 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 26 Mar 2021 12:29:08 -0700 Subject: [PATCH 123/370] Update cargo --- Cargo.lock | 47 +++++++++++++++++++++++++++++++++-------------- src/tools/cargo | 2 +- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33cbcb4a627..af76991d49a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "addr2line" version = "0.14.0" @@ -287,11 +289,10 @@ dependencies = [ "cargo-platform", "cargo-test-macro", "cargo-test-support", + "cargo-util", "clap", - "core-foundation", "crates-io", "crossbeam-utils 0.8.0", - "crypto-hash", "curl", "curl-sys", "env_logger 0.8.1", @@ -313,7 +314,6 @@ dependencies = [ "libgit2-sys", "log", "memchr", - "miow 0.3.6", "num_cpus", "opener", "openssl", @@ -322,12 +322,10 @@ dependencies = [ "rand 0.8.3", "rustc-workspace-hack", "rustfix", - "same-file", "semver 0.10.0", "serde", "serde_ignored", "serde_json", - "shell-escape", "strip-ansi-escapes", "tar", "tempfile", @@ -396,8 +394,9 @@ version = "0.1.0" name = "cargo-test-support" version = "0.1.0" dependencies = [ - "cargo", + "anyhow", "cargo-test-macro", + "cargo-util", "filetime", "flate2", "git2", @@ -410,6 +409,26 @@ dependencies = [ "url 2.1.1", ] +[[package]] +name = "cargo-util" +version = "0.1.0" +dependencies = [ + "anyhow", + "core-foundation", + "crypto-hash", + "filetime", + "hex 0.4.2", + "jobserver", + "libc", + "log", + "miow 0.3.6", + "same-file", + "shell-escape", + "tempfile", + "walkdir", + "winapi 0.3.9", +] + [[package]] name = "cargo_metadata" version = "0.8.2" @@ -2769,9 +2788,9 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] name = "proc-macro2" -version = "1.0.19" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ "unicode-xid", ] @@ -4797,18 +4816,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.118" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" +checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.118" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" dependencies = [ "proc-macro2", "quote", @@ -5104,9 +5123,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.38" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4" +checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663" dependencies = [ "proc-macro2", "quote", diff --git a/src/tools/cargo b/src/tools/cargo index 90691f2bfe9..1e8703890f2 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 90691f2bfe9a50291a98983b1ed2feab51d5ca55 +Subproject commit 1e8703890f285befb5e32627ad4e0a0454dde1fb From addc51a85f264e208385a8a1d10b6accb737ea8d Mon Sep 17 00:00:00 2001 From: lcnr Date: Sun, 28 Feb 2021 12:42:56 +0100 Subject: [PATCH 124/370] update array missing `IntoIterator` msg --- library/core/src/iter/traits/iterator.rs | 4 ++-- src/test/ui/iterators/array-of-ranges.stderr | 24 ++++++++++---------- src/test/ui/iterators/array.stderr | 12 +++++----- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 46e1a3a4aa2..e75a3647718 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -81,8 +81,8 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} ), on( _Self = "[]", - label = "borrow the array with `&` or call `.iter()` on it to iterate over it", - note = "arrays are not iterators, but slices like the following are: `&[1, 2, 3]`" + label = "arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`", + note = "see for more details" ), on( _Self = "{integral}", diff --git a/src/test/ui/iterators/array-of-ranges.stderr b/src/test/ui/iterators/array-of-ranges.stderr index 601983a6153..e76b6c5cdcf 100644 --- a/src/test/ui/iterators/array-of-ranges.stderr +++ b/src/test/ui/iterators/array-of-ranges.stderr @@ -13,10 +13,10 @@ error[E0277]: `[RangeInclusive<{integer}>; 1]` is not an iterator --> $DIR/array-of-ranges.rs:4:14 | LL | for _ in [0..=1] {} - | ^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it + | ^^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` | = help: the trait `Iterator` is not implemented for `[RangeInclusive<{integer}>; 1]` - = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]` + = note: see for more details = note: required because of the requirements on the impl of `IntoIterator` for `[RangeInclusive<{integer}>; 1]` = note: required by `into_iter` @@ -24,10 +24,10 @@ error[E0277]: `[RangeFrom<{integer}>; 1]` is not an iterator --> $DIR/array-of-ranges.rs:6:14 | LL | for _ in [0..] {} - | ^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it + | ^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` | = help: the trait `Iterator` is not implemented for `[RangeFrom<{integer}>; 1]` - = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]` + = note: see for more details = note: required because of the requirements on the impl of `IntoIterator` for `[RangeFrom<{integer}>; 1]` = note: required by `into_iter` @@ -35,10 +35,10 @@ error[E0277]: `[RangeTo<{integer}>; 1]` is not an iterator --> $DIR/array-of-ranges.rs:8:14 | LL | for _ in [..1] {} - | ^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it + | ^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` | = help: the trait `Iterator` is not implemented for `[RangeTo<{integer}>; 1]` - = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]` + = note: see for more details = note: required because of the requirements on the impl of `IntoIterator` for `[RangeTo<{integer}>; 1]` = note: required by `into_iter` @@ -46,10 +46,10 @@ error[E0277]: `[RangeToInclusive<{integer}>; 1]` is not an iterator --> $DIR/array-of-ranges.rs:10:14 | LL | for _ in [..=1] {} - | ^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it + | ^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` | = help: the trait `Iterator` is not implemented for `[RangeToInclusive<{integer}>; 1]` - = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]` + = note: see for more details = note: required because of the requirements on the impl of `IntoIterator` for `[RangeToInclusive<{integer}>; 1]` = note: required by `into_iter` @@ -79,10 +79,10 @@ error[E0277]: `[std::ops::Range<{integer}>; 2]` is not an iterator --> $DIR/array-of-ranges.rs:19:14 | LL | for _ in [0..1, 2..3] {} - | ^^^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it + | ^^^^^^^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` | = help: the trait `Iterator` is not implemented for `[std::ops::Range<{integer}>; 2]` - = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]` + = note: see for more details = note: required because of the requirements on the impl of `IntoIterator` for `[std::ops::Range<{integer}>; 2]` = note: required by `into_iter` @@ -90,10 +90,10 @@ error[E0277]: `[RangeInclusive<{integer}>; 1]` is not an iterator --> $DIR/array-of-ranges.rs:21:14 | LL | for _ in [0..=1] {} - | ^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it + | ^^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` | = help: the trait `Iterator` is not implemented for `[RangeInclusive<{integer}>; 1]` - = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]` + = note: see for more details = note: required because of the requirements on the impl of `IntoIterator` for `[RangeInclusive<{integer}>; 1]` = note: required by `into_iter` diff --git a/src/test/ui/iterators/array.stderr b/src/test/ui/iterators/array.stderr index 68c6de5493f..7e2b600fb7a 100644 --- a/src/test/ui/iterators/array.stderr +++ b/src/test/ui/iterators/array.stderr @@ -2,10 +2,10 @@ error[E0277]: `[{integer}; 2]` is not an iterator --> $DIR/array.rs:2:14 | LL | for _ in [1, 2] {} - | ^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it + | ^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` | = help: the trait `Iterator` is not implemented for `[{integer}; 2]` - = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]` + = note: see for more details = note: required because of the requirements on the impl of `IntoIterator` for `[{integer}; 2]` = note: required by `into_iter` @@ -13,10 +13,10 @@ error[E0277]: `[{integer}; 2]` is not an iterator --> $DIR/array.rs:5:14 | LL | for _ in x {} - | ^ borrow the array with `&` or call `.iter()` on it to iterate over it + | ^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` | = help: the trait `Iterator` is not implemented for `[{integer}; 2]` - = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]` + = note: see for more details = note: required because of the requirements on the impl of `IntoIterator` for `[{integer}; 2]` = note: required by `into_iter` @@ -24,10 +24,10 @@ error[E0277]: `[{float}; 2]` is not an iterator --> $DIR/array.rs:7:14 | LL | for _ in [1.0, 2.0] {} - | ^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it + | ^^^^^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` | = help: the trait `Iterator` is not implemented for `[{float}; 2]` - = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]` + = note: see for more details = note: required because of the requirements on the impl of `IntoIterator` for `[{float}; 2]` = note: required by `into_iter` From 3d6bd87b24a2fbccb6c1e81863874789eb046c17 Mon Sep 17 00:00:00 2001 From: Reyk Floeter Date: Mon, 22 Mar 2021 12:07:44 +0100 Subject: [PATCH 125/370] unix: Fix feature(unix_socket_ancillary_data) on macos and other BSDs This adds support for CMSG handling on macOS and fixes it on OpenBSD and other BSDs. When traversing the CMSG list, the previous code had an exception for Android where the next element after the last pointer could point to the first pointer instead of NULL. This is actually not specific to Android: the `libc::CMSG_NXTHDR` implementation for Linux and emscripten have a special case to return NULL when the length of the previous element is zero; most other implementations simply return the previous element plus a zero offset in this case. This MR additionally adds `SocketAncillary::is_empty` because clippy is right that it should be added. --- library/std/src/sys/unix/ext/net/ancillary.rs | 57 +++++++++++-------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/library/std/src/sys/unix/ext/net/ancillary.rs b/library/std/src/sys/unix/ext/net/ancillary.rs index 33d6a39af07..011ae643f87 100644 --- a/library/std/src/sys/unix/ext/net/ancillary.rs +++ b/library/std/src/sys/unix/ext/net/ancillary.rs @@ -5,9 +5,7 @@ use crate::marker::PhantomData; use crate::mem::{size_of, zeroed}; use crate::os::unix::io::RawFd; use crate::path::Path; -#[cfg(target_os = "android")] -use crate::ptr::eq; -use crate::ptr::read_unaligned; +use crate::ptr::{eq, read_unaligned}; use crate::slice::from_raw_parts; use crate::sys::net::Socket; @@ -30,12 +28,10 @@ pub(super) fn recv_vectored_with_ancillary_from( ) -> io::Result<(usize, bool, io::Result)> { unsafe { let mut msg_name: libc::sockaddr_un = zeroed(); - let mut msg: libc::msghdr = zeroed(); msg.msg_name = &mut msg_name as *mut _ as *mut _; msg.msg_namelen = size_of::() as libc::socklen_t; msg.msg_iov = bufs.as_mut_ptr().cast(); - msg.msg_control = ancillary.buffer.as_mut_ptr().cast(); cfg_if::cfg_if! { if #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] { msg.msg_iovlen = bufs.len() as libc::size_t; @@ -45,6 +41,7 @@ pub(super) fn recv_vectored_with_ancillary_from( target_os = "emscripten", target_os = "freebsd", all(target_os = "linux", target_env = "musl",), + target_os = "macos", target_os = "netbsd", target_os = "openbsd", ))] { @@ -52,6 +49,10 @@ pub(super) fn recv_vectored_with_ancillary_from( msg.msg_controllen = ancillary.buffer.len() as libc::socklen_t; } } + // macos requires that the control pointer is NULL when the len is 0. + if msg.msg_controllen > 0 { + msg.msg_control = ancillary.buffer.as_mut_ptr().cast(); + } let count = socket.recv_msg(&mut msg)?; @@ -79,7 +80,6 @@ pub(super) fn send_vectored_with_ancillary_to( msg.msg_name = &mut msg_name as *mut _ as *mut _; msg.msg_namelen = msg_namelen; msg.msg_iov = bufs.as_ptr() as *mut _; - msg.msg_control = ancillary.buffer.as_mut_ptr().cast(); cfg_if::cfg_if! { if #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] { msg.msg_iovlen = bufs.len() as libc::size_t; @@ -89,6 +89,7 @@ pub(super) fn send_vectored_with_ancillary_to( target_os = "emscripten", target_os = "freebsd", all(target_os = "linux", target_env = "musl",), + target_os = "macos", target_os = "netbsd", target_os = "openbsd", ))] { @@ -96,6 +97,10 @@ pub(super) fn send_vectored_with_ancillary_to( msg.msg_controllen = ancillary.length as libc::socklen_t; } } + // macos requires that the control pointer is NULL when the len is 0. + if msg.msg_controllen > 0 { + msg.msg_control = ancillary.buffer.as_mut_ptr().cast(); + } ancillary.truncated = false; @@ -147,6 +152,7 @@ fn add_to_ancillary_data( target_os = "emscripten", target_os = "freebsd", all(target_os = "linux", target_env = "musl",), + target_os = "macos", target_os = "netbsd", target_os = "openbsd", ))] { @@ -159,14 +165,12 @@ fn add_to_ancillary_data( while !cmsg.is_null() { previous_cmsg = cmsg; cmsg = libc::CMSG_NXTHDR(&msg, cmsg); - cfg_if::cfg_if! { - // Android return the same pointer if it is the last cmsg. - // Therefore, check it if the previous pointer is the same as the current one. - if #[cfg(target_os = "android")] { - if cmsg == previous_cmsg { - break; - } - } + + // Most operating systems, but not Linux or emscripten, return the previous pointer + // when its length is zero. Therefore, check if the previous pointer is the same as + // the current one. + if eq(cmsg, previous_cmsg) { + break; } } @@ -184,6 +188,7 @@ fn add_to_ancillary_data( target_os = "emscripten", target_os = "freebsd", all(target_os = "linux", target_env = "musl",), + target_os = "macos", target_os = "netbsd", target_os = "openbsd", ))] { @@ -371,6 +376,7 @@ impl<'a> AncillaryData<'a> { target_os = "emscripten", target_os = "freebsd", all(target_os = "linux", target_env = "musl",), + target_os = "macos", target_os = "netbsd", target_os = "openbsd", ))] { @@ -421,6 +427,7 @@ impl<'a> Iterator for Messages<'a> { target_os = "emscripten", target_os = "freebsd", all(target_os = "linux", target_env = "musl",), + target_os = "macos", target_os = "netbsd", target_os = "openbsd", ))] { @@ -435,15 +442,13 @@ impl<'a> Iterator for Messages<'a> { }; let cmsg = cmsg.as_ref()?; - cfg_if::cfg_if! { - // Android return the same pointer if it is the last cmsg. - // Therefore, check it if the previous pointer is the same as the current one. - if #[cfg(target_os = "android")] { - if let Some(current) = self.current { - if eq(current, cmsg) { - return None; - } - } + + // Most operating systems, but not Linux or emscripten, return the previous pointer + // when its length is zero. Therefore, check if the previous pointer is the same as + // the current one. + if let Some(current) = self.current { + if eq(current, cmsg) { + return None; } } @@ -514,6 +519,12 @@ impl<'a> SocketAncillary<'a> { self.buffer.len() } + /// Returns `true` if the ancillary data is empty. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn is_empty(&self) -> bool { + self.length == 0 + } + /// Returns the number of used bytes. #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub fn len(&self) -> usize { From 5ac917dbb224de8445d1526c62b75941db5e5254 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 12 Mar 2021 11:48:05 +0100 Subject: [PATCH 126/370] fix rustc_on_implemented `_Self` paths --- .../error_reporting/on_unimplemented.rs | 104 +++++++++--------- src/test/ui/iterators/array-of-ranges.stderr | 20 ++-- src/test/ui/iterators/ranges.stderr | 6 +- src/test/ui/iterators/string.stderr | 2 +- .../expected-boxed-future-isnt-pinned.stderr | 2 + src/test/ui/suggestions/into-str.stderr | 1 + src/test/ui/suggestions/path-display.stderr | 4 +- 7 files changed, 74 insertions(+), 65 deletions(-) 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 cecdcc97896..49ebca0502c 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 @@ -163,61 +163,65 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { flags.push((sym::from_desugaring, None)); flags.push((sym::from_desugaring, Some(format!("{:?}", k)))); } - let generics = self.tcx.generics_of(def_id); - let self_ty = trait_ref.self_ty(); - // This is also included through the generics list as `Self`, - // but the parser won't allow you to use it - flags.push((sym::_Self, Some(self_ty.to_string()))); - if let Some(def) = self_ty.ty_adt_def() { - // We also want to be able to select self's original - // signature with no type arguments resolved - flags.push((sym::_Self, Some(self.tcx.type_of(def.did).to_string()))); - } - for param in generics.params.iter() { - let value = match param.kind { - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { - trait_ref.substs[param.index as usize].to_string() - } - GenericParamDefKind::Lifetime => continue, - }; - let name = param.name; - flags.push((name, Some(value))); - } - - if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) { - flags.push((sym::crate_local, None)); - } - - // Allow targeting all integers using `{integral}`, even if the exact type was resolved - if self_ty.is_integral() { - flags.push((sym::_Self, Some("{integral}".to_owned()))); - } - - if let ty::Array(aty, len) = self_ty.kind() { - flags.push((sym::_Self, Some("[]".to_owned()))); - flags.push((sym::_Self, Some(format!("[{}]", aty)))); - if let Some(def) = aty.ty_adt_def() { - // We also want to be able to select the array's type's original + // Add all types without trimmed paths. + ty::print::with_no_trimmed_paths(|| { + let generics = self.tcx.generics_of(def_id); + let self_ty = trait_ref.self_ty(); + // This is also included through the generics list as `Self`, + // but the parser won't allow you to use it + flags.push((sym::_Self, Some(self_ty.to_string()))); + if let Some(def) = self_ty.ty_adt_def() { + // We also want to be able to select self's original // signature with no type arguments resolved - let type_string = self.tcx.type_of(def.did).to_string(); - flags.push((sym::_Self, Some(format!("[{}]", type_string)))); - - let len = len.val.try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx)); - let string = match len { - Some(n) => format!("[{}; {}]", type_string, n), - None => format!("[{}; _]", type_string), - }; - flags.push((sym::_Self, Some(string))); + flags.push((sym::_Self, Some(self.tcx.type_of(def.did).to_string()))); } - } - if let ty::Dynamic(traits, _) = self_ty.kind() { - for t in traits.iter() { - if let ty::ExistentialPredicate::Trait(trait_ref) = t.skip_binder() { - flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id)))) + + for param in generics.params.iter() { + let value = match param.kind { + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { + trait_ref.substs[param.index as usize].to_string() + } + GenericParamDefKind::Lifetime => continue, + }; + let name = param.name; + flags.push((name, Some(value))); + } + + if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) { + flags.push((sym::crate_local, None)); + } + + // Allow targeting all integers using `{integral}`, even if the exact type was resolved + if self_ty.is_integral() { + flags.push((sym::_Self, Some("{integral}".to_owned()))); + } + + if let ty::Array(aty, len) = self_ty.kind() { + flags.push((sym::_Self, Some("[]".to_owned()))); + flags.push((sym::_Self, Some(format!("[{}]", aty)))); + if let Some(def) = aty.ty_adt_def() { + // We also want to be able to select the array's type's original + // signature with no type arguments resolved + let type_string = self.tcx.type_of(def.did).to_string(); + flags.push((sym::_Self, Some(format!("[{}]", type_string)))); + + let len = len.val.try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx)); + let string = match len { + Some(n) => format!("[{}; {}]", type_string, n), + None => format!("[{}; _]", type_string), + }; + flags.push((sym::_Self, Some(string))); } } - } + if let ty::Dynamic(traits, _) = self_ty.kind() { + for t in traits.iter() { + if let ty::ExistentialPredicate::Trait(trait_ref) = t.skip_binder() { + flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id)))) + } + } + } + }); if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, trait_ref.def_id, def_id) diff --git a/src/test/ui/iterators/array-of-ranges.stderr b/src/test/ui/iterators/array-of-ranges.stderr index e76b6c5cdcf..7d58eb948ea 100644 --- a/src/test/ui/iterators/array-of-ranges.stderr +++ b/src/test/ui/iterators/array-of-ranges.stderr @@ -13,10 +13,10 @@ error[E0277]: `[RangeInclusive<{integer}>; 1]` is not an iterator --> $DIR/array-of-ranges.rs:4:14 | LL | for _ in [0..=1] {} - | ^^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` + | ^^^^^^^ if you meant to iterate between two values, remove the square brackets | = help: the trait `Iterator` is not implemented for `[RangeInclusive<{integer}>; 1]` - = note: see for more details + = note: `[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a `RangeInclusive` without the brackets: `start..=end` = note: required because of the requirements on the impl of `IntoIterator` for `[RangeInclusive<{integer}>; 1]` = note: required by `into_iter` @@ -24,10 +24,10 @@ error[E0277]: `[RangeFrom<{integer}>; 1]` is not an iterator --> $DIR/array-of-ranges.rs:6:14 | LL | for _ in [0..] {} - | ^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` + | ^^^^^ if you meant to iterate from a value onwards, remove the square brackets | = help: the trait `Iterator` is not implemented for `[RangeFrom<{integer}>; 1]` - = note: see for more details + = note: `[start..]` is an array of one `RangeFrom`; you might have meant to have a `RangeFrom` without the brackets: `start..`, keeping in mind that iterating over an unbounded iterator will run forever unless you `break` or `return` from within the loop = note: required because of the requirements on the impl of `IntoIterator` for `[RangeFrom<{integer}>; 1]` = note: required by `into_iter` @@ -35,10 +35,10 @@ error[E0277]: `[RangeTo<{integer}>; 1]` is not an iterator --> $DIR/array-of-ranges.rs:8:14 | LL | for _ in [..1] {} - | ^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` + | ^^^^^ if you meant to iterate until a value, remove the square brackets and add a starting value | = help: the trait `Iterator` is not implemented for `[RangeTo<{integer}>; 1]` - = note: see for more details + = note: `[..end]` is an array of one `RangeTo`; you might have meant to have a bounded `Range` without the brackets: `0..end` = note: required because of the requirements on the impl of `IntoIterator` for `[RangeTo<{integer}>; 1]` = note: required by `into_iter` @@ -46,10 +46,10 @@ error[E0277]: `[RangeToInclusive<{integer}>; 1]` is not an iterator --> $DIR/array-of-ranges.rs:10:14 | LL | for _ in [..=1] {} - | ^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` + | ^^^^^^ if you meant to iterate until a value (including it), remove the square brackets and add a starting value | = help: the trait `Iterator` is not implemented for `[RangeToInclusive<{integer}>; 1]` - = note: see for more details + = note: `[..=end]` is an array of one `RangeToInclusive`; you might have meant to have a bounded `RangeInclusive` without the brackets: `0..=end` = note: required because of the requirements on the impl of `IntoIterator` for `[RangeToInclusive<{integer}>; 1]` = note: required by `into_iter` @@ -90,10 +90,10 @@ error[E0277]: `[RangeInclusive<{integer}>; 1]` is not an iterator --> $DIR/array-of-ranges.rs:21:14 | LL | for _ in [0..=1] {} - | ^^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)` + | ^^^^^^^ if you meant to iterate between two values, remove the square brackets | = help: the trait `Iterator` is not implemented for `[RangeInclusive<{integer}>; 1]` - = note: see for more details + = note: `[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a `RangeInclusive` without the brackets: `start..=end` = note: required because of the requirements on the impl of `IntoIterator` for `[RangeInclusive<{integer}>; 1]` = note: required by `into_iter` diff --git a/src/test/ui/iterators/ranges.stderr b/src/test/ui/iterators/ranges.stderr index 4678bafd196..73844329e36 100644 --- a/src/test/ui/iterators/ranges.stderr +++ b/src/test/ui/iterators/ranges.stderr @@ -2,9 +2,10 @@ error[E0277]: `RangeTo<{integer}>` is not an iterator --> $DIR/ranges.rs:2:14 | LL | for _ in ..10 {} - | ^^^^ `RangeTo<{integer}>` is not an iterator + | ^^^^ if you meant to iterate until a value, add a starting value | = help: the trait `Iterator` is not implemented for `RangeTo<{integer}>` + = note: `..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a bounded `Range`: `0..end` = note: required because of the requirements on the impl of `IntoIterator` for `RangeTo<{integer}>` = note: required by `into_iter` @@ -12,9 +13,10 @@ error[E0277]: `RangeToInclusive<{integer}>` is not an iterator --> $DIR/ranges.rs:4:14 | LL | for _ in ..=10 {} - | ^^^^^ `RangeToInclusive<{integer}>` is not an iterator + | ^^^^^ if you meant to iterate until a value (including it), add a starting value | = help: the trait `Iterator` is not implemented for `RangeToInclusive<{integer}>` + = note: `..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant to have a bounded `RangeInclusive`: `0..=end` = note: required because of the requirements on the impl of `IntoIterator` for `RangeToInclusive<{integer}>` = note: required by `into_iter` diff --git a/src/test/ui/iterators/string.stderr b/src/test/ui/iterators/string.stderr index 16530066824..1d77bcb7536 100644 --- a/src/test/ui/iterators/string.stderr +++ b/src/test/ui/iterators/string.stderr @@ -2,7 +2,7 @@ error[E0277]: `String` is not an iterator --> $DIR/string.rs:2:14 | LL | for _ in "".to_owned() {} - | ^^^^^^^^^^^^^ `String` is not an iterator + | ^^^^^^^^^^^^^ `String` is not an iterator; try calling `.chars()` or `.bytes()` | = help: the trait `Iterator` is not implemented for `String` = note: required because of the requirements on the impl of `IntoIterator` for `String` diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr index 32961b7f87b..3786457fb1a 100644 --- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr +++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr @@ -46,6 +46,7 @@ error[E0277]: `dyn Future + Send` cannot be unpinned LL | Pin::new(x) | ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future + Send` | + = note: consider using `Box::pin` = note: required by `Pin::

::new` error[E0277]: `dyn Future + Send` cannot be unpinned @@ -54,6 +55,7 @@ error[E0277]: `dyn Future + Send` cannot be unpinned LL | Pin::new(Box::new(x)) | ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future + Send` | + = note: consider using `Box::pin` = note: required by `Pin::

::new` error[E0308]: mismatched types diff --git a/src/test/ui/suggestions/into-str.stderr b/src/test/ui/suggestions/into-str.stderr index 2854b830ba8..26efd50bb8f 100644 --- a/src/test/ui/suggestions/into-str.stderr +++ b/src/test/ui/suggestions/into-str.stderr @@ -7,6 +7,7 @@ LL | fn foo<'a, T>(_t: T) where T: Into<&'a str> {} LL | foo(String::new()); | ^^^ the trait `From` is not implemented for `&str` | + = note: to coerce a `String` into a `&str`, use `&*` as a prefix = note: required because of the requirements on the impl of `Into<&str>` for `String` error: aborting due to previous error diff --git a/src/test/ui/suggestions/path-display.stderr b/src/test/ui/suggestions/path-display.stderr index b08e22eaab7..3ee2860b4ff 100644 --- a/src/test/ui/suggestions/path-display.stderr +++ b/src/test/ui/suggestions/path-display.stderr @@ -2,10 +2,10 @@ error[E0277]: `Path` doesn't implement `std::fmt::Display` --> $DIR/path-display.rs:5:20 | LL | println!("{}", path); - | ^^^^ `Path` cannot be formatted with the default formatter + | ^^^^ `Path` cannot be formatted with the default formatter; call `.display()` on it | = help: the trait `std::fmt::Display` is not implemented for `Path` - = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = note: call `.display()` or `.to_string_lossy()` to safely print paths, as they may contain non-Unicode data = note: required because of the requirements on the impl of `std::fmt::Display` for `&Path` = note: required by `std::fmt::Display::fmt` = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) From 4f73d2153c4a8c71e5fa9c03b6b9f3af39491319 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Fri, 26 Mar 2021 15:25:48 -0600 Subject: [PATCH 127/370] Fix compiletest on FreeBSD Recent FreeBSD gdb packages have a different format for the version string. --- src/tools/compiletest/src/main.rs | 3 ++- src/tools/compiletest/src/tests.rs | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 1d4b5e1247d..48091601861 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -909,7 +909,8 @@ fn extract_gdb_version(full_version_line: &str) -> Option { // This particular form is documented in the GNU coding standards: // https://www.gnu.org/prep/standards/html_node/_002d_002dversion.html#g_t_002d_002dversion - let mut splits = full_version_line.rsplit(' '); + let unbracketed_part = full_version_line.split('[').next().unwrap(); + let mut splits = unbracketed_part.trim_end().rsplit(' '); let version_string = splits.next().unwrap(); let mut splits = version_string.split('.'); diff --git a/src/tools/compiletest/src/tests.rs b/src/tools/compiletest/src/tests.rs index ea9bc1c1a5b..ce75cb2878b 100644 --- a/src/tools/compiletest/src/tests.rs +++ b/src/tools/compiletest/src/tests.rs @@ -39,6 +39,9 @@ fn test_extract_gdb_version() { 7012000: "GNU gdb (GDB) 7.12", 7012000: "GNU gdb (GDB) 7.12.20161027-git", 7012050: "GNU gdb (GDB) 7.12.50.20161027-git", + + 9002000: "GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2", + 10001000: "GNU gdb (GDB) 10.1 [GDB v10.1 for FreeBSD]", } } From 5676bd51aeaa6b05735dc888a2e41770a4d7b162 Mon Sep 17 00:00:00 2001 From: Midas Lambrichts Date: Fri, 26 Mar 2021 23:16:22 +0100 Subject: [PATCH 128/370] Break when there is a mismatch in the type count When other errors are generated, there can be a mismatch between the amount of input types in MIR, and the amount in the function itself. Break from the comparative loop if this is the case to prevent out-of-bounds. --- .../rustc_mir/src/borrow_check/type_check/input_output.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs b/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs index 77d91366224..1bb447d1057 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs @@ -70,6 +70,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // Equate expected input tys with those in the MIR. for (argument_index, &normalized_input_ty) in normalized_input_tys.iter().enumerate() { + if argument_index + 1 >= body.local_decls.len() { + self.tcx() + .sess + .delay_span_bug(body.span, "found more normalized_input_ty than local_decls"); + break; + } // In MIR, argument N is stored in local N+1. let local = Local::new(argument_index + 1); From 4572e7f903a3d6bd5b401e886c9e7e2ef97998f0 Mon Sep 17 00:00:00 2001 From: Camelid Date: Fri, 26 Mar 2021 18:14:47 -0700 Subject: [PATCH 129/370] Lint on unknown intra-doc link disambiguators --- .../passes/collect_intra_doc_links.rs | 45 ++++++++++++++----- .../intra-doc/unknown-disambiguator.rs | 10 +++++ .../intra-doc/unknown-disambiguator.stderr | 40 +++++++++++++++++ 3 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs create mode 100644 src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 499931f7e96..f5c5c9ca4aa 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -973,10 +973,13 @@ impl LinkCollector<'_, '_> { }; // Parse and strip the disambiguator from the link, if present. - let (mut path_str, disambiguator) = if let Ok((d, path)) = Disambiguator::from_str(&link) { - (path.trim(), Some(d)) - } else { - (link.trim(), None) + let (mut path_str, disambiguator) = match Disambiguator::from_str(&link) { + Ok(Some((d, path))) => (path.trim(), Some(d)), + Ok(None) => (link.trim(), None), + Err(err_msg) => { + disambiguator_error(self.cx, &item, dox, ori_link.range, &err_msg); + return None; + } }; if path_str.contains(|ch: char| !(ch.is_alphanumeric() || ":_<>, !*&;".contains(ch))) { @@ -1514,8 +1517,12 @@ impl Disambiguator { } } - /// Given a link, parse and return `(disambiguator, path_str)` - fn from_str(link: &str) -> Result<(Self, &str), ()> { + /// Given a link, parse and return `(disambiguator, path_str)`. + /// + /// This returns `Ok(Some(...))` if a disambiguator was found, + /// `Ok(None)` if no disambiguator was found, or `Err(...)` + /// if there was a problem with the disambiguator. + fn from_str(link: &str) -> Result, String> { use Disambiguator::{Kind, Namespace as NS, Primitive}; let find_suffix = || { @@ -1528,11 +1535,11 @@ impl Disambiguator { if let Some(link) = link.strip_suffix(suffix) { // Avoid turning `!` or `()` into an empty string if !link.is_empty() { - return Ok((Kind(kind), link)); + return Some((Kind(kind), link)); } } } - Err(()) + None }; if let Some(idx) = link.find('@') { @@ -1551,11 +1558,11 @@ impl Disambiguator { "value" => NS(Namespace::ValueNS), "macro" => NS(Namespace::MacroNS), "prim" | "primitive" => Primitive, - _ => return find_suffix(), + _ => return Err(format!("unknown disambiguator `{}`", prefix)), }; - Ok((d, &rest[1..])) + Ok(Some((d, &rest[1..]))) } else { - find_suffix() + Ok(find_suffix()) } } @@ -1979,6 +1986,22 @@ fn anchor_failure( }); } +/// Report an error in the link disambiguator. +fn disambiguator_error( + cx: &DocContext<'_>, + item: &Item, + dox: &str, + link_range: Range, + msg: &str, +) { + report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, item, dox, &link_range, |diag, _sp| { + diag.note( + "the disambiguator is the part of the link before the `@` sign, \ + or a suffix such as `()` for functions", + ); + }); +} + /// Report an ambiguity error, where there were multiple possible resolutions. fn ambiguity_error( cx: &DocContext<'_>, diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs new file mode 100644 index 00000000000..9222025367d --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs @@ -0,0 +1,10 @@ +//! Linking to [foo@banana] and [`bar@banana!()`]. +//~^ ERROR unknown disambiguator `foo` +//~| ERROR unknown disambiguator `bar` +//! And to [no disambiguator](@nectarine) and [another](@apricot!()). +//~^ ERROR unknown disambiguator `` +//~| ERROR unknown disambiguator `` + +#![deny(warnings)] + +fn main() {} diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr new file mode 100644 index 00000000000..9e7699eea9a --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr @@ -0,0 +1,40 @@ +error: unknown disambiguator `foo` + --> $DIR/unknown-disambiguator.rs:1:17 + | +LL | //! Linking to [foo@banana] and [`bar@banana!()`]. + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unknown-disambiguator.rs:8:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]` + = note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions + +error: unknown disambiguator `bar` + --> $DIR/unknown-disambiguator.rs:1:34 + | +LL | //! Linking to [foo@banana] and [`bar@banana!()`]. + | ^^^^^^^^^^^^^^^ + | + = note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions + +error: unknown disambiguator `` + --> $DIR/unknown-disambiguator.rs:4:31 + | +LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). + | ^^^^^^^^^^ + | + = note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions + +error: unknown disambiguator `` + --> $DIR/unknown-disambiguator.rs:4:57 + | +LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). + | ^^^^^^^^^^^ + | + = note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions + +error: aborting due to 4 previous errors + From f94360fd83b49554b6c26999a0030e9cfe800f32 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 26 Mar 2021 23:23:20 -0400 Subject: [PATCH 130/370] Always preserve `None`-delimited groups in a captured `TokenStream` Previously, we would silently remove any `None`-delimiters when capturing a `TokenStream`, 'flattenting' them to their inner tokens. This was not normally visible, since we usually have `TokenKind::Interpolated` (which gets converted to a `None`-delimited group during macro invocation) instead of an actual `None`-delimited group. However, there are a couple of cases where this becomes visible to proc-macros: 1. A cross-crate `macro_rules!` macro has a `None`-delimited group stored in its body (as a result of being produced by another `macro_rules!` macro). The cross-crate `macro_rules!` invocation can then expand to an attribute macro invocation, which needs to be able to see the `None`-delimited group. 2. A proc-macro can invoke an attribute proc-macro with its re-collected input. If there are any nonterminals present in the input, they will get re-collected to `None`-delimited groups, which will then get captured as part of the attribute macro invocation. Both of these cases are incredibly obscure, so there hopefully won't be any breakage. This change will allow more agressive 'flattenting' of nonterminals in #82608 without losing `None`-delimited groups. --- .../rustc_parse/src/parser/attr_wrapper.rs | 45 ++++++++++++---- compiler/rustc_parse/src/parser/mod.rs | 25 +++++++-- .../auxiliary/nested-macro-rules.rs | 9 ++-- src/test/ui/proc-macro/nested-macro-rules.rs | 10 ++-- .../ui/proc-macro/nested-macro-rules.stdout | 52 +++++++++++++++++-- 5 files changed, 113 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 7512f46988c..36a0fda6458 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -98,21 +98,46 @@ impl<'a> Parser<'a> { } impl CreateTokenStream for LazyTokenStreamImpl { fn create_token_stream(&self) -> TokenStream { - // The token produced by the final call to `next` or `next_desugared` - // was not actually consumed by the callback. The combination - // of chaining the initial token and using `take` produces the desired - // result - we produce an empty `TokenStream` if no calls were made, - // and omit the final token otherwise. + if self.num_calls == 0 { + return TokenStream::new(vec![]); + } + let mut cursor_snapshot = self.cursor_snapshot.clone(); - let tokens = std::iter::once(self.start_token.clone()) - .chain((0..self.num_calls).map(|_| { - if self.desugar_doc_comments { + // Don't skip `None` delimiters, since we want to pass them to + // proc macros. Normally, we'll end up capturing `TokenKind::Interpolated`, + // which gets converted to a `None`-delimited group when we invoke + // a proc-macro. However, it's possible to already have a `None`-delimited + // group in the stream (such as when parsing the output of a proc-macro, + // or in certain unusual cases with cross-crate `macro_rules!` macros). + cursor_snapshot.skip_none_delims = false; + + // The token produced by the final call to `next` or `next_desugared` + // was not actually consumed by the callback. + let num_calls = self.num_calls - 1; + let mut i = 0; + let tokens = + std::iter::once(self.start_token.clone()).chain(std::iter::from_fn(|| { + if i >= num_calls { + return None; + } + + let token = if self.desugar_doc_comments { cursor_snapshot.next_desugared() } else { cursor_snapshot.next() + }; + + // When the `LazyTokenStreamImpl` was original produced, we did *not* + // include `NoDelim` tokens in `num_calls`, since they are normally ignored + // by the parser. Therefore, we only increment our counter for other types of tokens. + if !matches!( + token.0.kind, + token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) + ) { + i += 1; } - })) - .take(self.num_calls); + Some(token) + })); make_token_stream(tokens, self.append_unglued_token.clone()) } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index f0ee76d328c..748a8e2bb49 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -172,6 +172,13 @@ struct TokenCursor { // appended to the captured stream when // we evaluate a `LazyTokenStream` append_unglued_token: Option, + // If `true`, skip the delimiters for `None`-delimited groups, + // and just yield the inner tokens. This is `true` during + // normal parsing, since the parser code is not currently prepared + // to handle `None` delimiters. When capturing a `TokenStream`, + // however, we want to handle `None`-delimiters, since + // proc-macros always see `None`-delimited groups. + skip_none_delims: bool, } #[derive(Clone)] @@ -184,13 +191,13 @@ struct TokenCursorFrame { } impl TokenCursorFrame { - fn new(span: DelimSpan, delim: DelimToken, tts: TokenStream) -> Self { + fn new(span: DelimSpan, delim: DelimToken, tts: TokenStream, skip_none_delims: bool) -> Self { TokenCursorFrame { delim, span, - open_delim: delim == token::NoDelim, + open_delim: delim == token::NoDelim && skip_none_delims, tree_cursor: tts.into_trees(), - close_delim: delim == token::NoDelim, + close_delim: delim == token::NoDelim && skip_none_delims, } } } @@ -218,7 +225,7 @@ impl TokenCursor { return (token, spacing); } TokenTree::Delimited(sp, delim, tts) => { - let frame = TokenCursorFrame::new(sp, delim, tts); + let frame = TokenCursorFrame::new(sp, delim, tts, self.skip_none_delims); self.stack.push(mem::replace(&mut self.frame, frame)); } } @@ -276,6 +283,7 @@ impl TokenCursor { .cloned() .collect::() }, + self.skip_none_delims, ), )); @@ -371,12 +379,19 @@ impl<'a> Parser<'a> { prev_token: Token::dummy(), restrictions: Restrictions::empty(), expected_tokens: Vec::new(), + // Skip over the delimiters for `None`-delimited groups token_cursor: TokenCursor { - frame: TokenCursorFrame::new(DelimSpan::dummy(), token::NoDelim, tokens), + frame: TokenCursorFrame::new( + DelimSpan::dummy(), + token::NoDelim, + tokens, + /* skip_none_delims */ true, + ), stack: Vec::new(), num_next_calls: 0, desugar_doc_comments, append_unglued_token: None, + skip_none_delims: true, }, desugar_doc_comments, unmatched_angle_bracket_count: 0, diff --git a/src/test/ui/proc-macro/auxiliary/nested-macro-rules.rs b/src/test/ui/proc-macro/auxiliary/nested-macro-rules.rs index 52ebe8e7fb2..27676a5cb81 100644 --- a/src/test/ui/proc-macro/auxiliary/nested-macro-rules.rs +++ b/src/test/ui/proc-macro/auxiliary/nested-macro-rules.rs @@ -2,14 +2,15 @@ pub struct FirstStruct; #[macro_export] macro_rules! outer_macro { - ($name:ident) => { + ($name:ident, $attr_struct_name:ident) => { #[macro_export] macro_rules! inner_macro { - ($wrapper:ident) => { - $wrapper!($name) + ($bang_macro:ident, $attr_macro:ident) => { + $bang_macro!($name); + #[$attr_macro] struct $attr_struct_name {} } } } } -outer_macro!(FirstStruct); +outer_macro!(FirstStruct, FirstAttrStruct); diff --git a/src/test/ui/proc-macro/nested-macro-rules.rs b/src/test/ui/proc-macro/nested-macro-rules.rs index 2fef0e5fad0..25ffcfad7c7 100644 --- a/src/test/ui/proc-macro/nested-macro-rules.rs +++ b/src/test/ui/proc-macro/nested-macro-rules.rs @@ -1,7 +1,7 @@ // run-pass // aux-build:nested-macro-rules.rs // aux-build:test-macros.rs -// compile-flags: -Z span-debug +// compile-flags: -Z span-debug -Z macro-backtrace // edition:2018 #![no_std] // Don't load unnecessary hygiene information from std @@ -10,14 +10,14 @@ extern crate std; extern crate nested_macro_rules; extern crate test_macros; -use test_macros::print_bang; +use test_macros::{print_bang, print_attr}; use nested_macro_rules::FirstStruct; struct SecondStruct; fn main() { - nested_macro_rules::inner_macro!(print_bang); + nested_macro_rules::inner_macro!(print_bang, print_attr); - nested_macro_rules::outer_macro!(SecondStruct); - inner_macro!(print_bang); + nested_macro_rules::outer_macro!(SecondStruct, SecondAttrStruct); + inner_macro!(print_bang, print_attr); } diff --git a/src/test/ui/proc-macro/nested-macro-rules.stdout b/src/test/ui/proc-macro/nested-macro-rules.stdout index dcafe3b4bda..8292617fc16 100644 --- a/src/test/ui/proc-macro/nested-macro-rules.stdout +++ b/src/test/ui/proc-macro/nested-macro-rules.stdout @@ -5,10 +5,32 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "FirstStruct", - span: $DIR/auxiliary/nested-macro-rules.rs:15:14: 15:25 (#7), + span: $DIR/auxiliary/nested-macro-rules.rs:16:14: 16:25 (#7), }, ], - span: $DIR/auxiliary/nested-macro-rules.rs:9:27: 9:32 (#6), + span: $DIR/auxiliary/nested-macro-rules.rs:9:30: 9:35 (#6), + }, +] +PRINT-ATTR INPUT (DISPLAY): struct FirstAttrStruct { } +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Ident { + ident: "struct", + span: $DIR/auxiliary/nested-macro-rules.rs:10:32: 10:38 (#6), + }, + Group { + delimiter: None, + stream: TokenStream [ + Ident { + ident: "FirstAttrStruct", + span: $DIR/auxiliary/nested-macro-rules.rs:16:27: 16:42 (#7), + }, + ], + span: $DIR/auxiliary/nested-macro-rules.rs:10:39: 10:56 (#6), + }, + Group { + delimiter: Brace, + stream: TokenStream [], + span: $DIR/auxiliary/nested-macro-rules.rs:10:57: 10:59 (#6), }, ] PRINT-BANG INPUT (DISPLAY): SecondStruct @@ -18,9 +40,31 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "SecondStruct", - span: $DIR/nested-macro-rules.rs:21:38: 21:50 (#13), + span: $DIR/nested-macro-rules.rs:21:38: 21:50 (#16), }, ], - span: $DIR/auxiliary/nested-macro-rules.rs:9:27: 9:32 (#12), + span: $DIR/auxiliary/nested-macro-rules.rs:9:30: 9:35 (#15), + }, +] +PRINT-ATTR INPUT (DISPLAY): struct SecondAttrStruct { } +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Ident { + ident: "struct", + span: $DIR/auxiliary/nested-macro-rules.rs:10:32: 10:38 (#15), + }, + Group { + delimiter: None, + stream: TokenStream [ + Ident { + ident: "SecondAttrStruct", + span: $DIR/nested-macro-rules.rs:21:52: 21:68 (#16), + }, + ], + span: $DIR/auxiliary/nested-macro-rules.rs:10:39: 10:56 (#15), + }, + Group { + delimiter: Brace, + stream: TokenStream [], + span: $DIR/auxiliary/nested-macro-rules.rs:10:57: 10:59 (#15), }, ] From 229d1999944624abdfa96ab77686175c6d685a1c Mon Sep 17 00:00:00 2001 From: klensy Date: Fri, 26 Mar 2021 22:32:37 +0300 Subject: [PATCH 131/370] lazily calls some fns --- compiler/rustc_errors/src/json.rs | 2 +- compiler/rustc_middle/src/ty/instance.rs | 7 ++++--- compiler/rustc_middle/src/ty/query/on_disk_cache.rs | 2 +- .../borrow_check/diagnostics/outlives_suggestion.rs | 2 +- compiler/rustc_resolve/src/late.rs | 2 +- compiler/rustc_resolve/src/late/diagnostics.rs | 10 +++++----- library/test/src/helpers/exit_code.rs | 2 +- 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index c27b39a9d62..2bce1ac3c0a 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -493,7 +493,7 @@ impl DiagnosticSpanLine { h_end: usize, ) -> DiagnosticSpanLine { DiagnosticSpanLine { - text: sf.get_line(index).map_or(String::new(), |l| l.into_owned()), + text: sf.get_line(index).map_or_else(String::new, |l| l.into_owned()), highlight_start: h_start, highlight_end: h_end, } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index f61b6946985..a753c4ab6ce 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -216,9 +216,10 @@ impl<'tcx> InstanceDef<'tcx> { // drops of `Option::None` before LTO. We also respect the intent of // `#[inline]` on `Drop::drop` implementations. return ty.ty_adt_def().map_or(true, |adt_def| { - adt_def.destructor(tcx).map_or(adt_def.is_enum(), |dtor| { - tcx.codegen_fn_attrs(dtor.did).requests_inline() - }) + adt_def.destructor(tcx).map_or_else( + || adt_def.is_enum(), + |dtor| tcx.codegen_fn_attrs(dtor.did).requests_inline(), + ) }); } tcx.codegen_fn_attrs(self.def_id()).requests_inline() diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs index ff11314d2ff..416199b3840 100644 --- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs @@ -525,7 +525,7 @@ impl<'sess> OnDiskCache<'sess> { ) { let mut current_diagnostics = self.current_diagnostics.borrow_mut(); - let x = current_diagnostics.entry(dep_node_index).or_insert(Vec::new()); + let x = current_diagnostics.entry(dep_node_index).or_default(); x.extend(Into::>::into(diagnostics)); } diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/outlives_suggestion.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/outlives_suggestion.rs index 7505e6e2dd1..3629c813bc7 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/outlives_suggestion.rs @@ -157,7 +157,7 @@ impl OutlivesSuggestionBuilder { debug!("Collected {:?}: {:?}", fr, outlived_fr); // Add to set of constraints for final help note. - self.constraints_to_add.entry(fr).or_insert(Vec::new()).push(outlived_fr); + self.constraints_to_add.entry(fr).or_default().push(outlived_fr); } /// Emit an intermediate note on the given `Diagnostic` if the involved regions are diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f9f33492a1e..1377bb781d0 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2327,7 +2327,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ExprKind::Call(ref callee, ref arguments) => { self.resolve_expr(callee, Some(expr)); - let const_args = self.r.legacy_const_generic_args(callee).unwrap_or(Vec::new()); + let const_args = self.r.legacy_const_generic_args(callee).unwrap_or_default(); for (idx, argument) in arguments.iter().enumerate() { // Constant arguments need to be treated as AnonConst since // that is how they will be later lowered to HIR. diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index e85d78db22c..4c0df2701f5 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -184,7 +184,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { PathResult::Module(ModuleOrUniformRoot::Module(module)) => module.res(), _ => None, } - .map_or(String::new(), |res| format!("{} ", res.descr())); + .map_or_else(String::new, |res| format!("{} ", res.descr())); (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path))) }; ( @@ -1042,10 +1042,10 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { if let Some(span) = self.def_span(def_id) { err.span_label(span, &format!("`{}` defined here", path_str)); } - let fields = - self.r.field_names.get(&def_id).map_or("/* fields */".to_string(), |fields| { - vec!["_"; fields.len()].join(", ") - }); + let fields = self.r.field_names.get(&def_id).map_or_else( + || "/* fields */".to_string(), + |fields| vec!["_"; fields.len()].join(", "), + ); err.span_suggestion( span, "use the tuple variant pattern syntax instead", diff --git a/library/test/src/helpers/exit_code.rs b/library/test/src/helpers/exit_code.rs index 31e234d9818..50bb260762a 100644 --- a/library/test/src/helpers/exit_code.rs +++ b/library/test/src/helpers/exit_code.rs @@ -4,7 +4,7 @@ use std::process::ExitStatus; #[cfg(not(unix))] pub fn get_exit_code(status: ExitStatus) -> Result { - status.code().ok_or("received no exit code from child process".into()) + status.code().ok_or_else(|| "received no exit code from child process".into()) } #[cfg(unix)] From 5b9bac2ab62063229c419909f89a41890c57f78f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Sun, 21 Mar 2021 17:29:21 +0300 Subject: [PATCH 132/370] format macro argument parsing fix When the character next to `{}` is "shifted" (when mapping a byte index in the format string to span) we should avoid shifting the span end index, so first map the index of `}` to span, then bump the span, instead of first mapping the next byte index to a span (which causes bumping the end span too much). Regression test added. Fixes #83344 --- compiler/rustc_parse_format/src/lib.rs | 10 ++++++---- src/test/ui/macros/issue-83344.rs | 6 ++++++ src/test/ui/macros/issue-83344.stderr | 8 ++++++++ src/tools/clippy/tests/ui/write_literal_2.stderr | 5 +++-- 4 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/macros/issue-83344.rs create mode 100644 src/test/ui/macros/issue-83344.stderr diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index c2fc2bfcd33..bc180ff3060 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -213,11 +213,13 @@ impl<'a> Iterator for Parser<'a> { Some(String(self.string(pos + 1))) } else { let arg = self.argument(); - if let Some(end) = self.must_consume('}') { - let start = self.to_span_index(pos); - let end = self.to_span_index(end + 1); + if let Some(rbrace_byte_idx) = self.must_consume('}') { + let lbrace_inner_offset = self.to_span_index(pos); + let rbrace_inner_offset = self.to_span_index(rbrace_byte_idx); if self.is_literal { - self.arg_places.push(start.to(end)); + self.arg_places.push( + lbrace_inner_offset.to(InnerOffset(rbrace_inner_offset.0 + 1)), + ); } } Some(NextArgument(arg)) diff --git a/src/test/ui/macros/issue-83344.rs b/src/test/ui/macros/issue-83344.rs new file mode 100644 index 00000000000..c5f7f723587 --- /dev/null +++ b/src/test/ui/macros/issue-83344.rs @@ -0,0 +1,6 @@ +// check-fail + +fn main() { + println!("{}\ +"); //~^ ERROR: 1 positional argument in format string, but no arguments were given +} diff --git a/src/test/ui/macros/issue-83344.stderr b/src/test/ui/macros/issue-83344.stderr new file mode 100644 index 00000000000..1ef70f87a1f --- /dev/null +++ b/src/test/ui/macros/issue-83344.stderr @@ -0,0 +1,8 @@ +error: 1 positional argument in format string, but no arguments were given + --> $DIR/issue-83344.rs:4:15 + | +LL | println!("{}\ + | ^^ + +error: aborting due to previous error + diff --git a/src/tools/clippy/tests/ui/write_literal_2.stderr b/src/tools/clippy/tests/ui/write_literal_2.stderr index 5b488358011..0aa1b55e58c 100644 --- a/src/tools/clippy/tests/ui/write_literal_2.stderr +++ b/src/tools/clippy/tests/ui/write_literal_2.stderr @@ -75,8 +75,9 @@ LL | "1", "2", "3", | help: try this | -LL | "some 1{} / {}", "2", "3", - | ^ -- +LL | "some 1/ +LL | {} / {}", "2", "3", + | error: literal with an empty format string --> $DIR/write_literal_2.rs:25:14 From ee1b33c7acd250c4b06b09096f0bef9dfd44ba9d Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 27 Mar 2021 12:13:32 +0100 Subject: [PATCH 133/370] Add #[inline] to io::Error methods. --- library/std/src/io/error.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 2122aa755e1..97c92aa3506 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -269,6 +269,7 @@ impl Error { /// This function should maybe change to /// `new_const(kind: ErrorKind)` /// in the future, when const generics allow that. + #[inline] pub(crate) const fn new_const(kind: ErrorKind, message: &'static &'static str) -> Error { Self { repr: Repr::SimpleMessage(kind, message) } } @@ -287,6 +288,7 @@ impl Error { /// println!("last OS error: {:?}", Error::last_os_error()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn last_os_error() -> Error { Error::from_raw_os_error(sys::os::errno() as i32) } @@ -317,6 +319,7 @@ impl Error { /// # } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn from_raw_os_error(code: i32) -> Error { Error { repr: Repr::Os(code) } } @@ -351,6 +354,7 @@ impl Error { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn raw_os_error(&self) -> Option { match self.repr { Repr::Os(i) => Some(i), @@ -388,6 +392,7 @@ impl Error { /// } /// ``` #[stable(feature = "io_error_inner", since = "1.3.0")] + #[inline] pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> { match self.repr { Repr::Os(..) => None, @@ -460,6 +465,7 @@ impl Error { /// } /// ``` #[stable(feature = "io_error_inner", since = "1.3.0")] + #[inline] pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)> { match self.repr { Repr::Os(..) => None, @@ -497,6 +503,7 @@ impl Error { /// } /// ``` #[stable(feature = "io_error_inner", since = "1.3.0")] + #[inline] pub fn into_inner(self) -> Option> { match self.repr { Repr::Os(..) => None, @@ -525,6 +532,7 @@ impl Error { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn kind(&self) -> ErrorKind { match self.repr { Repr::Os(code) => sys::decode_error_kind(code), From 2afa4cc958d3d65957083f3ae0bded237cce9a87 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 27 Mar 2021 13:29:23 +0100 Subject: [PATCH 134/370] Use DebugStruct::finish_non_exhaustive() in std. --- library/std/src/collections/hash/map.rs | 15 +++++++++------ library/std/src/fs.rs | 2 +- library/std/src/io/buffered/linewriter.rs | 2 +- library/std/src/lazy.rs | 2 +- library/std/src/process.rs | 2 +- library/std/src/sync/mpsc/mod.rs | 6 +++--- library/std/src/sys/wasi/fs.rs | 2 +- library/std/src/thread/mod.rs | 5 ++++- 8 files changed, 21 insertions(+), 15 deletions(-) diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index ed32668456d..3dcc5cd2b59 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1793,7 +1793,7 @@ impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> { #[unstable(feature = "hash_raw_entry", issue = "56167")] impl Debug for RawEntryBuilderMut<'_, K, V, S> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("RawEntryBuilder").finish() + f.debug_struct("RawEntryBuilder").finish_non_exhaustive() } } @@ -1813,21 +1813,21 @@ impl Debug for RawOccupiedEntryMut<'_, K, V, S> { f.debug_struct("RawOccupiedEntryMut") .field("key", self.key()) .field("value", self.get()) - .finish() + .finish_non_exhaustive() } } #[unstable(feature = "hash_raw_entry", issue = "56167")] impl Debug for RawVacantEntryMut<'_, K, V, S> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("RawVacantEntryMut").finish() + f.debug_struct("RawVacantEntryMut").finish_non_exhaustive() } } #[unstable(feature = "hash_raw_entry", issue = "56167")] impl Debug for RawEntryBuilder<'_, K, V, S> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("RawEntryBuilder").finish() + f.debug_struct("RawEntryBuilder").finish_non_exhaustive() } } @@ -1867,7 +1867,10 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> { #[stable(feature = "debug_hash_map", since = "1.12.0")] impl Debug for OccupiedEntry<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("OccupiedEntry").field("key", self.key()).field("value", self.get()).finish() + f.debug_struct("OccupiedEntry") + .field("key", self.key()) + .field("value", self.get()) + .finish_non_exhaustive() } } @@ -1903,7 +1906,7 @@ impl Debug for OccupiedError<'_, K, V> { .field("key", self.entry.key()) .field("old_value", self.entry.get()) .field("new_value", &self.value) - .finish() + .finish_non_exhaustive() } } diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index ccbc69a975c..8da6ced03a8 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1154,7 +1154,7 @@ impl fmt::Debug for Metadata { .field("modified", &self.modified()) .field("accessed", &self.accessed()) .field("created", &self.created()) - .finish() + .finish_non_exhaustive() } } diff --git a/library/std/src/io/buffered/linewriter.rs b/library/std/src/io/buffered/linewriter.rs index 502c6e3c6c0..d7b620d6f91 100644 --- a/library/std/src/io/buffered/linewriter.rs +++ b/library/std/src/io/buffered/linewriter.rs @@ -227,6 +227,6 @@ where "buffer", &format_args!("{}/{}", self.inner.buffer().len(), self.inner.capacity()), ) - .finish() + .finish_non_exhaustive() } } diff --git a/library/std/src/lazy.rs b/library/std/src/lazy.rs index 974851a8bd6..ca86e569bc1 100644 --- a/library/std/src/lazy.rs +++ b/library/std/src/lazy.rs @@ -515,7 +515,7 @@ pub struct SyncLazy T> { #[unstable(feature = "once_cell", issue = "74465")] impl fmt::Debug for SyncLazy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish() + f.debug_struct("Lazy").field("cell", &self.cell).finish_non_exhaustive() } } diff --git a/library/std/src/process.rs b/library/std/src/process.rs index f9cfd11e906..5690de681ca 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -234,7 +234,7 @@ impl fmt::Debug for Child { .field("stdin", &self.stdin) .field("stdout", &self.stdout) .field("stderr", &self.stderr) - .finish() + .finish_non_exhaustive() } } diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc/mod.rs index b12e7eeb138..c8f0a6b99fe 100644 --- a/library/std/src/sync/mpsc/mod.rs +++ b/library/std/src/sync/mpsc/mod.rs @@ -864,7 +864,7 @@ impl Drop for Sender { #[stable(feature = "mpsc_debug", since = "1.8.0")] impl fmt::Debug for Sender { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Sender").finish() + f.debug_struct("Sender").finish_non_exhaustive() } } @@ -991,7 +991,7 @@ impl Drop for SyncSender { #[stable(feature = "mpsc_debug", since = "1.8.0")] impl fmt::Debug for SyncSender { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("SyncSender").finish() + f.debug_struct("SyncSender").finish_non_exhaustive() } } @@ -1470,7 +1470,7 @@ impl Drop for Receiver { #[stable(feature = "mpsc_debug", since = "1.8.0")] impl fmt::Debug for Receiver { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Receiver").finish() + f.debug_struct("Receiver").finish_non_exhaustive() } } diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs index 1ec3ff6a10f..ed0f03e4b71 100644 --- a/library/std/src/sys/wasi/fs.rs +++ b/library/std/src/sys/wasi/fs.rs @@ -130,7 +130,7 @@ impl FileType { impl fmt::Debug for ReadDir { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("ReadDir").finish() + f.debug_struct("ReadDir").finish_non_exhaustive() } } diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 0ef848ff0c4..ffdf4be1584 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1176,7 +1176,10 @@ impl Thread { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for Thread { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Thread").field("id", &self.id()).field("name", &self.name()).finish() + f.debug_struct("Thread") + .field("id", &self.id()) + .field("name", &self.name()) + .finish_non_exhaustive() } } From d73015397dc43eb8067644ab2bbb1c2203c795d4 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 27 Mar 2021 13:31:17 +0100 Subject: [PATCH 135/370] Fix Debug implementation for RwLock{Read,Write}Guard. This would attempt to print the Debug representation of the lock that the guard has locked, which will try to lock again, fail, and just print "" unhelpfully. After this change, this just prints the contents of the mutex, like the other smart pointers (and MutexGuard) do. --- library/std/src/sync/rwlock.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index 0298f59228c..c6c753b103f 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -473,7 +473,7 @@ impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> { #[stable(feature = "std_debug", since = "1.16.0")] impl fmt::Debug for RwLockReadGuard<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("RwLockReadGuard").field("lock", &self.lock).finish() + (**self).fmt(f) } } @@ -487,7 +487,7 @@ impl fmt::Display for RwLockReadGuard<'_, T> { #[stable(feature = "std_debug", since = "1.16.0")] impl fmt::Debug for RwLockWriteGuard<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("RwLockWriteGuard").field("lock", &self.lock).finish() + (**self).fmt(f) } } From 7c01e6c38a11a9814da121200c64df5a62a455b1 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 27 Mar 2021 13:36:07 +0100 Subject: [PATCH 136/370] Derive Debug for io::Chain instead of manually implementing it. The manual implementation has the same bounds, so I don't think there's any reason for a manual implementation. The names used in the derive implementation are even nicer (`first`/`second`) than the manual implementation (`t`/`u`), and include the `done_first` field too. --- library/std/src/io/mod.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 5316305a303..9953bcd556d 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -2114,6 +2114,7 @@ pub trait BufRead: Read { /// /// [`chain`]: Read::chain #[stable(feature = "rust1", since = "1.0.0")] +#[derive(Debug)] pub struct Chain { first: T, second: U, @@ -2195,13 +2196,6 @@ impl Chain { } } -#[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for Chain { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Chain").field("t", &self.first).field("u", &self.second).finish() - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl Read for Chain { fn read(&mut self, buf: &mut [u8]) -> Result { From 5402abc4937e77c69d8a94eaec86cbc764564cf7 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 27 Mar 2021 13:47:11 +0100 Subject: [PATCH 137/370] Improve Debug implementations of Mutex and RwLock. They now show the poison flag and use debug_non_exhaustive. --- library/std/src/sync/mutex.rs | 12 ++++++++---- library/std/src/sync/rwlock.rs | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index ab61618dc7d..98c34282e0c 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -441,10 +441,13 @@ impl Default for Mutex { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for Mutex { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut d = f.debug_struct("Mutex"); match self.try_lock() { - Ok(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(), + Ok(guard) => { + d.field("data", &&*guard); + } Err(TryLockError::Poisoned(err)) => { - f.debug_struct("Mutex").field("data", &&**err.get_ref()).finish() + d.field("data", &&**err.get_ref()); } Err(TryLockError::WouldBlock) => { struct LockedPlaceholder; @@ -453,10 +456,11 @@ impl fmt::Debug for Mutex { f.write_str("") } } - - f.debug_struct("Mutex").field("data", &LockedPlaceholder).finish() + d.field("data", &LockedPlaceholder); } } + d.field("poisoned", &self.poison.get()); + d.finish_non_exhaustive() } } diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index 0298f59228c..ee5fe06ac1e 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -422,10 +422,13 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for RwLock { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for RwLock { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut d = f.debug_struct("RwLock"); match self.try_read() { - Ok(guard) => f.debug_struct("RwLock").field("data", &&*guard).finish(), + Ok(guard) => { + d.field("data", &&*guard); + } Err(TryLockError::Poisoned(err)) => { - f.debug_struct("RwLock").field("data", &&**err.get_ref()).finish() + d.field("data", &&**err.get_ref()); } Err(TryLockError::WouldBlock) => { struct LockedPlaceholder; @@ -434,10 +437,11 @@ impl fmt::Debug for RwLock { f.write_str("") } } - - f.debug_struct("RwLock").field("data", &LockedPlaceholder).finish() + d.field("data", &LockedPlaceholder); } } + d.field("poisoned", &self.poison.get()); + d.finish_non_exhaustive() } } From 5495ce087438ec85ebd252cf3339c30cedad95d8 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Wed, 25 Nov 2020 11:22:19 +0800 Subject: [PATCH 138/370] Use detailed and shorter fs error explaination Includes suggestion from the8472 https://github.com/rust-lang/rust/issues/79390#issuecomment-733263336 More detail error explanation in fs doc --- library/std/src/fs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index e2d4f2e6a56..e2140ce7e60 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1676,9 +1676,9 @@ pub fn rename, Q: AsRef>(from: P, to: Q) -> io::Result<()> /// This function will return an error in the following situations, but is not /// limited to just these cases: /// -/// * The `from` path is not a file. -/// * The `from` file does not exist. -/// * The current process does not have the permission rights to access +/// * `from` is neither a regular file nor a symlink to a regular file. +/// * `from` does not exist. +/// * The current process does not have the permission rights to read /// `from` or write `to`. /// /// # Examples From 84e7ae284266cfb77487c580945dcc9f5f107e45 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 27 Mar 2021 14:03:31 +0100 Subject: [PATCH 139/370] Run Miri test suite with mir-opt-level=4 --- src/bootstrap/test.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 86d940cd733..b3cf30672c8 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -452,7 +452,14 @@ impl Step for Miri { cargo.add_rustc_lib_path(builder, compiler); - if !try_run(builder, &mut cargo.into()) { + let mut cargo = Command::from(cargo); + if !try_run(builder, &mut cargo) { + return; + } + + // # Run `cargo test` with `-Zmir-opt-level=4`. + cargo.env("MIRIFLAGS", "-O -Zmir-opt-level=4"); + if !try_run(builder, &mut cargo) { return; } From 6c6ef7317bf87321c5eaefb1322380c8f297ff1b Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sat, 27 Mar 2021 01:21:35 +0800 Subject: [PATCH 140/370] Improve fs error open_from unix Consistency for #79399 Suggested by JohnTitor Improve fs error invaild input for sys_common The text was duplicated from unix. --- library/std/src/sys/unix/fs.rs | 8 +++----- library/std/src/sys_common/fs.rs | 10 ++++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index f25a6280cd0..759565bab73 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -2,7 +2,7 @@ use crate::os::unix::prelude::*; use crate::ffi::{CStr, CString, OsStr, OsString}; use crate::fmt; -use crate::io::{self, Error, ErrorKind, IoSlice, IoSliceMut, SeekFrom}; +use crate::io::{self, Error, IoSlice, IoSliceMut, SeekFrom}; use crate::mem; use crate::path::{Path, PathBuf}; use crate::ptr; @@ -1152,14 +1152,12 @@ pub fn canonicalize(p: &Path) -> io::Result { fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)> { use crate::fs::File; + use crate::sys_common::fs::NOT_FILE_ERROR; let reader = File::open(from)?; let metadata = reader.metadata()?; if !metadata.is_file() { - return Err(Error::new_const( - ErrorKind::InvalidInput, - &"the source path is not an existing regular file", - )); + return Err(NOT_FILE_ERROR); } Ok((reader, metadata)) } diff --git a/library/std/src/sys_common/fs.rs b/library/std/src/sys_common/fs.rs index 92d0cc60850..30908824dd6 100644 --- a/library/std/src/sys_common/fs.rs +++ b/library/std/src/sys_common/fs.rs @@ -4,15 +4,17 @@ use crate::fs; use crate::io::{self, Error, ErrorKind}; use crate::path::Path; +pub(crate) const NOT_FILE_ERROR: Error = Error::new_const( + ErrorKind::InvalidInput, + &"the source path is neither a regular file nor a symlink to a regular file", +); + pub fn copy(from: &Path, to: &Path) -> io::Result { let mut reader = fs::File::open(from)?; let metadata = reader.metadata()?; if !metadata.is_file() { - return Err(Error::new_const( - ErrorKind::InvalidInput, - &"the source path is not an existing regular file", - )); + return Err(NOT_FILE_ERROR); } let mut writer = fs::File::create(to)?; From d5bcdd34e7e90e94812ae15b8081e6bf7b19f663 Mon Sep 17 00:00:00 2001 From: Jon Jensen Date: Sat, 27 Mar 2021 07:51:46 -0600 Subject: [PATCH 141/370] Update rustup cross-compilation docs link --- src/doc/rustc/src/targets/built-in.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/targets/built-in.md b/src/doc/rustc/src/targets/built-in.md index c33b506cdae..344048ee4a1 100644 --- a/src/doc/rustc/src/targets/built-in.md +++ b/src/doc/rustc/src/targets/built-in.md @@ -12,4 +12,4 @@ library built by the official Rust distributions. Most targets will need a system linker, and possibly other things. [rustup]: https://github.com/rust-lang/rustup -[rustup-cross]: https://github.com/rust-lang/rustup#cross-compilation +[rustup-cross]: https://rust-lang.github.io/rustup/cross-compilation.html From 5cfc98fb7fa1cf3ae361790fe7375c9a6b12b72e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 27 Mar 2021 14:58:23 +0100 Subject: [PATCH 142/370] update comment at MaybeUninit::uninit_array --- library/core/src/mem/maybe_uninit.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index cb072931232..337f0e847bb 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -319,9 +319,9 @@ impl MaybeUninit { /// Create a new array of `MaybeUninit` items, in an uninitialized state. /// /// Note: in a future Rust version this method may become unnecessary - /// when array literal syntax allows - /// [repeating const expressions](https://github.com/rust-lang/rust/issues/49147). - /// The example below could then use `let mut buf = [MaybeUninit::::uninit(); 32];`. + /// when Rust allows + /// [inline const expressions](https://github.com/rust-lang/rust/issues/76001). + /// The example below could then use `let mut buf = [const { MaybeUninit::::uninit() }; 32];`. /// /// # Examples /// From 09275802249824e54d8eac577147112d4752671a Mon Sep 17 00:00:00 2001 From: Simon Jakobi Date: Sat, 27 Mar 2021 04:22:22 +0100 Subject: [PATCH 143/370] Add regression tests for #56445 Closes #56445. --- ...56445.full.stderr => issue-56445-1.full.stderr} | 4 ++-- ...e-56445.min.stderr => issue-56445-1.min.stderr} | 2 +- .../issues/{issue-56445.rs => issue-56445-1.rs} | 0 src/test/ui/const-generics/issues/issue-56445-2.rs | 11 +++++++++++ .../ui/const-generics/issues/issue-56445-2.stderr | 14 ++++++++++++++ src/test/ui/const-generics/issues/issue-56445-3.rs | 12 ++++++++++++ .../ui/const-generics/issues/issue-56445-3.stderr | 8 ++++++++ 7 files changed, 48 insertions(+), 3 deletions(-) rename src/test/ui/const-generics/issues/{issue-56445.full.stderr => issue-56445-1.full.stderr} (92%) rename src/test/ui/const-generics/issues/{issue-56445.min.stderr => issue-56445-1.min.stderr} (91%) rename src/test/ui/const-generics/issues/{issue-56445.rs => issue-56445-1.rs} (100%) create mode 100644 src/test/ui/const-generics/issues/issue-56445-2.rs create mode 100644 src/test/ui/const-generics/issues/issue-56445-2.stderr create mode 100644 src/test/ui/const-generics/issues/issue-56445-3.rs create mode 100644 src/test/ui/const-generics/issues/issue-56445-3.stderr diff --git a/src/test/ui/const-generics/issues/issue-56445.full.stderr b/src/test/ui/const-generics/issues/issue-56445-1.full.stderr similarity index 92% rename from src/test/ui/const-generics/issues/issue-56445.full.stderr rename to src/test/ui/const-generics/issues/issue-56445-1.full.stderr index 61fba92c196..8416d64e1c2 100644 --- a/src/test/ui/const-generics/issues/issue-56445.full.stderr +++ b/src/test/ui/const-generics/issues/issue-56445-1.full.stderr @@ -1,5 +1,5 @@ warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-56445.rs:3:27 + --> $DIR/issue-56445-1.rs:3:27 | LL | #![cfg_attr(full, feature(const_generics))] | ^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #![cfg_attr(full, feature(const_generics))] = note: see issue #44580 for more information error[E0771]: use of non-static lifetime `'a` in const generic - --> $DIR/issue-56445.rs:8:26 + --> $DIR/issue-56445-1.rs:8:26 | LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); | ^^ diff --git a/src/test/ui/const-generics/issues/issue-56445.min.stderr b/src/test/ui/const-generics/issues/issue-56445-1.min.stderr similarity index 91% rename from src/test/ui/const-generics/issues/issue-56445.min.stderr rename to src/test/ui/const-generics/issues/issue-56445-1.min.stderr index 80702dd4bc3..f7056f27cb3 100644 --- a/src/test/ui/const-generics/issues/issue-56445.min.stderr +++ b/src/test/ui/const-generics/issues/issue-56445-1.min.stderr @@ -1,5 +1,5 @@ error[E0771]: use of non-static lifetime `'a` in const generic - --> $DIR/issue-56445.rs:8:26 + --> $DIR/issue-56445-1.rs:8:26 | LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); | ^^ diff --git a/src/test/ui/const-generics/issues/issue-56445.rs b/src/test/ui/const-generics/issues/issue-56445-1.rs similarity index 100% rename from src/test/ui/const-generics/issues/issue-56445.rs rename to src/test/ui/const-generics/issues/issue-56445-1.rs diff --git a/src/test/ui/const-generics/issues/issue-56445-2.rs b/src/test/ui/const-generics/issues/issue-56445-2.rs new file mode 100644 index 00000000000..e078c8487c7 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-56445-2.rs @@ -0,0 +1,11 @@ +// Regression test for https://github.com/rust-lang/rust/issues/56445#issuecomment-502095133 +struct OnDiskDirEntry<'a> { _s: &'a usize } + +impl<'a> OnDiskDirEntry<'a> { + const LFN_FRAGMENT_LEN: usize = 2; + + fn lfn_contents(&self) -> [char; Self::LFN_FRAGMENT_LEN] { loop { } } + //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants +} + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-56445-2.stderr b/src/test/ui/const-generics/issues/issue-56445-2.stderr new file mode 100644 index 00000000000..770c80cbbd3 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-56445-2.stderr @@ -0,0 +1,14 @@ +error: generic `Self` types are currently not permitted in anonymous constants + --> $DIR/issue-56445-2.rs:7:38 + | +LL | fn lfn_contents(&self) -> [char; Self::LFN_FRAGMENT_LEN] { loop { } } + | ^^^^ + | +note: not a concrete type + --> $DIR/issue-56445-2.rs:4:10 + | +LL | impl<'a> OnDiskDirEntry<'a> { + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-56445-3.rs b/src/test/ui/const-generics/issues/issue-56445-3.rs new file mode 100644 index 00000000000..c29df14586e --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-56445-3.rs @@ -0,0 +1,12 @@ +// Regression test for https://github.com/rust-lang/rust/issues/56445#issuecomment-524494170 +pub struct Memory<'rom> { + rom: &'rom [u8], + ram: [u8; Self::SIZE], + //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants +} + +impl<'rom> Memory<'rom> { + pub const SIZE: usize = 0x8000; +} + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-56445-3.stderr b/src/test/ui/const-generics/issues/issue-56445-3.stderr new file mode 100644 index 00000000000..f1c49eecfb5 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-56445-3.stderr @@ -0,0 +1,8 @@ +error: generic `Self` types are currently not permitted in anonymous constants + --> $DIR/issue-56445-3.rs:4:15 + | +LL | ram: [u8; Self::SIZE], + | ^^^^ + +error: aborting due to previous error + From 6327e46d8c21d54734eb5eb44604be487a8e6bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20du=20Garreau?= Date: Sat, 27 Mar 2021 15:21:10 +0100 Subject: [PATCH 144/370] Constantify some slice methods --- library/core/src/slice/mod.rs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 1e9e9c24a45..56d3ba0ff25 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -145,8 +145,9 @@ impl [T] { /// assert_eq!(None, w.first()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] #[inline] - pub fn first(&self) -> Option<&T> { + pub const fn first(&self) -> Option<&T> { if let [first, ..] = self { Some(first) } else { None } } @@ -163,8 +164,9 @@ impl [T] { /// assert_eq!(x, &[5, 1, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] #[inline] - pub fn first_mut(&mut self) -> Option<&mut T> { + pub const fn first_mut(&mut self) -> Option<&mut T> { if let [first, ..] = self { Some(first) } else { None } } @@ -181,8 +183,9 @@ impl [T] { /// } /// ``` #[stable(feature = "slice_splits", since = "1.5.0")] + #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] #[inline] - pub fn split_first(&self) -> Option<(&T, &[T])> { + pub const fn split_first(&self) -> Option<(&T, &[T])> { if let [first, tail @ ..] = self { Some((first, tail)) } else { None } } @@ -201,8 +204,9 @@ impl [T] { /// assert_eq!(x, &[3, 4, 5]); /// ``` #[stable(feature = "slice_splits", since = "1.5.0")] + #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] #[inline] - pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> { + pub const fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> { if let [first, tail @ ..] = self { Some((first, tail)) } else { None } } @@ -219,8 +223,9 @@ impl [T] { /// } /// ``` #[stable(feature = "slice_splits", since = "1.5.0")] + #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] #[inline] - pub fn split_last(&self) -> Option<(&T, &[T])> { + pub const fn split_last(&self) -> Option<(&T, &[T])> { if let [init @ .., last] = self { Some((last, init)) } else { None } } @@ -239,8 +244,9 @@ impl [T] { /// assert_eq!(x, &[4, 5, 3]); /// ``` #[stable(feature = "slice_splits", since = "1.5.0")] + #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] #[inline] - pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> { + pub const fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> { if let [init @ .., last] = self { Some((last, init)) } else { None } } @@ -256,8 +262,9 @@ impl [T] { /// assert_eq!(None, w.last()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] #[inline] - pub fn last(&self) -> Option<&T> { + pub const fn last(&self) -> Option<&T> { if let [.., last] = self { Some(last) } else { None } } @@ -274,8 +281,9 @@ impl [T] { /// assert_eq!(x, &[0, 1, 10]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] #[inline] - pub fn last_mut(&mut self) -> Option<&mut T> { + pub const fn last_mut(&mut self) -> Option<&mut T> { if let [.., last] = self { Some(last) } else { None } } From 42150fb8a12cae86ebee3a7734c2d14ed6b1d0a8 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sun, 24 Jan 2021 20:08:12 +0100 Subject: [PATCH 145/370] combine: stop eagerly evaluating consts --- compiler/rustc_infer/src/infer/combine.rs | 28 +++++++++++++------ compiler/rustc_middle/src/ty/relate.rs | 11 +------- .../issues/issue-69654-run-pass.rs | 2 +- .../issues/issue-69654-run-pass.stderr | 15 ++++++++++ .../ui/const-generics/issues/issue-69654.rs | 1 + .../const-generics/issues/issue-69654.stderr | 17 +++++++++-- .../occurs-check/unused-substs-1.rs | 3 +- .../occurs-check/unused-substs-1.stderr | 17 +++++++++++ .../occurs-check/unused-substs-2.rs | 3 +- .../occurs-check/unused-substs-2.stderr | 9 ++++++ .../occurs-check/unused-substs-3.rs | 3 +- .../occurs-check/unused-substs-3.stderr | 12 ++++++++ .../occurs-check/unused-substs-4.rs | 3 +- .../occurs-check/unused-substs-4.stderr | 9 ++++++ 14 files changed, 106 insertions(+), 27 deletions(-) create mode 100644 src/test/ui/const-generics/issues/issue-69654-run-pass.stderr create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-1.stderr create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-2.stderr create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-3.stderr create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-4.stderr diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 5e11932eafc..ffe947d209d 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -543,10 +543,6 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { true } - fn visit_ct_substs(&self) -> bool { - true - } - fn binders( &mut self, a: ty::Binder, @@ -737,6 +733,16 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { } } } + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + if self.tcx().lazy_normalization() => + { + assert_eq!(promoted, None); + let substs = self.relate_with_variance(ty::Variance::Invariant, substs, substs)?; + Ok(self.tcx().mk_const(ty::Const { + ty: c.ty, + val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }), + })) + } _ => relate::super_relate_consts(self, c, c), } } @@ -822,10 +828,6 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { true } - fn visit_ct_substs(&self) -> bool { - true - } - fn relate_with_variance>( &mut self, _variance: ty::Variance, @@ -959,6 +961,16 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { } } } + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + if self.tcx().lazy_normalization() => + { + assert_eq!(promoted, None); + let substs = self.relate_with_variance(ty::Variance::Invariant, substs, substs)?; + Ok(self.tcx().mk_const(ty::Const { + ty: c.ty, + val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }), + })) + } _ => relate::super_relate_consts(self, c, c), } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index c936c30f456..32a713beef8 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -33,15 +33,6 @@ pub trait TypeRelation<'tcx>: Sized { /// relation. Just affects error messages. fn a_is_expected(&self) -> bool; - /// Whether we should look into the substs of unevaluated constants - /// even if `feature(const_evaluatable_checked)` is active. - /// - /// This is needed in `combine` to prevent accidentially creating - /// infinite types as we abuse `TypeRelation` to walk a type there. - fn visit_ct_substs(&self) -> bool { - false - } - fn with_cause(&mut self, _cause: Cause, f: F) -> R where F: FnOnce(&mut Self) -> R, @@ -532,7 +523,7 @@ pub fn super_relate_consts>( } (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) - if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => + if tcx.features().const_evaluatable_checked => { tcx.try_unify_abstract_consts(((au.def, au.substs), (bu.def, bu.substs))) } diff --git a/src/test/ui/const-generics/issues/issue-69654-run-pass.rs b/src/test/ui/const-generics/issues/issue-69654-run-pass.rs index bbfd2183b06..8c0398e8a13 100644 --- a/src/test/ui/const-generics/issues/issue-69654-run-pass.rs +++ b/src/test/ui/const-generics/issues/issue-69654-run-pass.rs @@ -1,4 +1,3 @@ -// run-pass #![feature(const_generics)] #![allow(incomplete_features, unused_braces)] @@ -15,4 +14,5 @@ where fn main() { Foo::foo(); + //~^ ERROR no function or associated item } diff --git a/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr b/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr new file mode 100644 index 00000000000..a95cc0f2a1c --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr @@ -0,0 +1,15 @@ +error[E0599]: no function or associated item named `foo` found for struct `Foo<{_: usize}>` in the current scope + --> $DIR/issue-69654-run-pass.rs:16:10 + | +LL | struct Foo {} + | -------------------------- function or associated item `foo` not found for this +... +LL | Foo::foo(); + | ^^^ function or associated item not found in `Foo<{_: usize}>` + | + = note: the method `foo` exists but the following trait bounds were not satisfied: + `[u8; _]: Bar<[(); _]>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/const-generics/issues/issue-69654.rs b/src/test/ui/const-generics/issues/issue-69654.rs index 7e775999ebd..38fca98ad4f 100644 --- a/src/test/ui/const-generics/issues/issue-69654.rs +++ b/src/test/ui/const-generics/issues/issue-69654.rs @@ -15,4 +15,5 @@ where fn main() { Foo::foo(); + //~^ ERROR no function or associated item } diff --git a/src/test/ui/const-generics/issues/issue-69654.stderr b/src/test/ui/const-generics/issues/issue-69654.stderr index 70af7bf25d8..69cd0806fcd 100644 --- a/src/test/ui/const-generics/issues/issue-69654.stderr +++ b/src/test/ui/const-generics/issues/issue-69654.stderr @@ -4,6 +4,19 @@ error[E0423]: expected value, found type parameter `T` LL | impl Bar for [u8; T] {} | ^ not a value -error: aborting due to previous error +error[E0599]: no function or associated item named `foo` found for struct `Foo<{_: usize}>` in the current scope + --> $DIR/issue-69654.rs:17:10 + | +LL | struct Foo {} + | -------------------------- function or associated item `foo` not found for this +... +LL | Foo::foo(); + | ^^^ function or associated item not found in `Foo<{_: usize}>` + | + = note: the method `foo` exists but the following trait bounds were not satisfied: + `[u8; _]: Bar<[(); _]>` -For more information about this error, try `rustc --explain E0423`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0423, E0599. +For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-1.rs b/src/test/ui/const-generics/occurs-check/unused-substs-1.rs index f56687ecd93..6ded9f13bc4 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-1.rs +++ b/src/test/ui/const-generics/occurs-check/unused-substs-1.rs @@ -1,4 +1,3 @@ -// build-pass #![feature(const_generics)] #![allow(incomplete_features)] @@ -10,5 +9,5 @@ where A: Bar; fn main() { - let _ = A; + let _ = A; //~ERROR the trait bound } diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr new file mode 100644 index 00000000000..6830288acc0 --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `A<{_: usize}>: Bar<{_: usize}>` is not satisfied + --> $DIR/unused-substs-1.rs:12:13 + | +LL | / struct A +LL | | where +LL | | A: Bar; + | |_________________- required by `A` +... +LL | let _ = A; + | ^ the trait `Bar<{_: usize}>` is not implemented for `A<{_: usize}>` + | + = help: the following implementations were found: + as Bar> + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-2.rs b/src/test/ui/const-generics/occurs-check/unused-substs-2.rs index 12444ec5312..2d00141fbf7 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-2.rs +++ b/src/test/ui/const-generics/occurs-check/unused-substs-2.rs @@ -1,4 +1,3 @@ -// check-pass #![feature(const_generics)] #![allow(incomplete_features)] @@ -24,4 +23,6 @@ fn main() { // `t` is `ty::Infer(TyVar(_#1t))` // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs t = foo; + //~^ ERROR mismatched types + //~| NOTE cyclic type } diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-2.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-2.stderr new file mode 100644 index 00000000000..9532fc21a31 --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-2.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/unused-substs-2.rs:25:9 + | +LL | t = foo; + | ^^^ cyclic type of infinite size + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-3.rs b/src/test/ui/const-generics/occurs-check/unused-substs-3.rs index 187e27382fc..2e306f8c4c8 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-3.rs +++ b/src/test/ui/const-generics/occurs-check/unused-substs-3.rs @@ -1,4 +1,3 @@ -// check-pass #![feature(const_generics)] #![allow(incomplete_features)] @@ -15,4 +14,6 @@ fn main() { // `t` is `ty::Infer(TyVar(_#1t))` // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs t = foo; + //~^ ERROR mismatched types + //~| NOTE cyclic type } diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr new file mode 100644 index 00000000000..2551d68f974 --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/unused-substs-3.rs:16:9 + | +LL | t = foo; + | ^^^ + | | + | cyclic type of infinite size + | help: try using a conversion method: `foo.to_vec()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-4.rs b/src/test/ui/const-generics/occurs-check/unused-substs-4.rs index 8e42ceb6d70..9c7f5ab91ed 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-4.rs +++ b/src/test/ui/const-generics/occurs-check/unused-substs-4.rs @@ -1,4 +1,3 @@ -// build-pass #![feature(const_generics)] #![allow(incomplete_features)] @@ -8,5 +7,5 @@ fn bind(value: [u8; N]) -> [u8; 3 + 4] { fn main() { let mut arr = Default::default(); - arr = bind(arr); + arr = bind(arr); //~ ERROR mismatched type } diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-4.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-4.stderr new file mode 100644 index 00000000000..5685eedbdec --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-4.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/unused-substs-4.rs:10:11 + | +LL | arr = bind(arr); + | ^^^^^^^^^ encountered a self-referencing constant + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From e461dddf5828d729b872e27d1a7a7335437ce413 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 15 Mar 2021 23:10:24 +0100 Subject: [PATCH 146/370] update tests --- compiler/rustc_middle/src/ty/relate.rs | 6 +++--- src/test/ui/const-generics/issues/issue-69654-run-pass.rs | 2 +- .../ui/const-generics/issues/issue-69654-run-pass.stderr | 6 +++--- src/test/ui/const-generics/issues/issue-69654.rs | 2 +- src/test/ui/const-generics/issues/issue-69654.stderr | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 32a713beef8..bc979b885b4 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -423,9 +423,9 @@ pub fn super_relate_tys>( let sz_a = sz_a.try_eval_usize(tcx, relation.param_env()); let sz_b = sz_b.try_eval_usize(tcx, relation.param_env()); match (sz_a, sz_b) { - (Some(sz_a_val), Some(sz_b_val)) => Err(TypeError::FixedArraySize( - expected_found(relation, sz_a_val, sz_b_val), - )), + (Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => Err( + TypeError::FixedArraySize(expected_found(relation, sz_a_val, sz_b_val)), + ), _ => Err(err), } } diff --git a/src/test/ui/const-generics/issues/issue-69654-run-pass.rs b/src/test/ui/const-generics/issues/issue-69654-run-pass.rs index 8c0398e8a13..45318ca68fc 100644 --- a/src/test/ui/const-generics/issues/issue-69654-run-pass.rs +++ b/src/test/ui/const-generics/issues/issue-69654-run-pass.rs @@ -14,5 +14,5 @@ where fn main() { Foo::foo(); - //~^ ERROR no function or associated item + //~^ ERROR the function or associated item } diff --git a/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr b/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr index a95cc0f2a1c..a82a60696b3 100644 --- a/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr +++ b/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr @@ -1,13 +1,13 @@ -error[E0599]: no function or associated item named `foo` found for struct `Foo<{_: usize}>` in the current scope +error[E0599]: the function or associated item `foo` exists for struct `Foo<{_: usize}>`, but its trait bounds were not satisfied --> $DIR/issue-69654-run-pass.rs:16:10 | LL | struct Foo {} | -------------------------- function or associated item `foo` not found for this ... LL | Foo::foo(); - | ^^^ function or associated item not found in `Foo<{_: usize}>` + | ^^^ function or associated item cannot be called on `Foo<{_: usize}>` due to unsatisfied trait bounds | - = note: the method `foo` exists but the following trait bounds were not satisfied: + = note: the following trait bounds were not satisfied: `[u8; _]: Bar<[(); _]>` error: aborting due to previous error diff --git a/src/test/ui/const-generics/issues/issue-69654.rs b/src/test/ui/const-generics/issues/issue-69654.rs index 38fca98ad4f..b1214b12a14 100644 --- a/src/test/ui/const-generics/issues/issue-69654.rs +++ b/src/test/ui/const-generics/issues/issue-69654.rs @@ -15,5 +15,5 @@ where fn main() { Foo::foo(); - //~^ ERROR no function or associated item + //~^ ERROR the function or associated item } diff --git a/src/test/ui/const-generics/issues/issue-69654.stderr b/src/test/ui/const-generics/issues/issue-69654.stderr index 69cd0806fcd..0ce7640f685 100644 --- a/src/test/ui/const-generics/issues/issue-69654.stderr +++ b/src/test/ui/const-generics/issues/issue-69654.stderr @@ -4,16 +4,16 @@ error[E0423]: expected value, found type parameter `T` LL | impl Bar for [u8; T] {} | ^ not a value -error[E0599]: no function or associated item named `foo` found for struct `Foo<{_: usize}>` in the current scope +error[E0599]: the function or associated item `foo` exists for struct `Foo<{_: usize}>`, but its trait bounds were not satisfied --> $DIR/issue-69654.rs:17:10 | LL | struct Foo {} | -------------------------- function or associated item `foo` not found for this ... LL | Foo::foo(); - | ^^^ function or associated item not found in `Foo<{_: usize}>` + | ^^^ function or associated item cannot be called on `Foo<{_: usize}>` due to unsatisfied trait bounds | - = note: the method `foo` exists but the following trait bounds were not satisfied: + = note: the following trait bounds were not satisfied: `[u8; _]: Bar<[(); _]>` error: aborting due to 2 previous errors From fb4f48e0321fcc6b57e823434674ce41ceb23176 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 25 Feb 2021 19:38:53 +0100 Subject: [PATCH 147/370] make unaligned_refereces future-incompat lint warn-by-default, and remove the safe_packed_borrows lint that it replaces --- compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_lint_defs/src/builtin.rs | 65 ++------- compiler/rustc_middle/src/mir/query.rs | 6 - .../src/transform/check_packed_ref.rs | 89 +++++++++--- .../rustc_mir/src/transform/check_unsafety.rs | 130 +----------------- compiler/rustc_mir/src/transform/mod.rs | 1 + library/core/src/ptr/mod.rs | 2 + .../ui/binding/issue-53114-safety-checks.rs | 8 +- .../binding/issue-53114-safety-checks.stderr | 68 ++++----- .../diagnostics/repr_packed.rs | 2 +- .../diagnostics/repr_packed.stderr | 8 +- .../ui/derives/deriving-with-repr-packed.rs | 2 +- .../derives/deriving-with-repr-packed.stderr | 12 +- src/test/ui/issues/issue-27060-rpass.rs | 8 +- src/test/ui/issues/issue-27060.rs | 14 +- src/test/ui/issues/issue-27060.stderr | 40 ++++-- src/test/ui/lint/unaligned_references.rs | 6 + src/test/ui/lint/unaligned_references.stderr | 22 ++- .../unaligned_references_external_macro.rs | 3 +- ...unaligned_references_external_macro.stderr | 8 +- .../packed-struct-address-of-element.rs | 2 +- .../ui/packed/packed-struct-borrow-element.rs | 9 +- .../packed-struct-borrow-element.stderr | 33 +++++ ...c-2585-safe_packed_borrows-in-unsafe-fn.rs | 67 --------- ...85-safe_packed_borrows-in-unsafe-fn.stderr | 60 -------- 25 files changed, 251 insertions(+), 415 deletions(-) create mode 100644 src/test/ui/packed/packed-struct-borrow-element.stderr delete mode 100644 src/test/ui/unsafe/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs delete mode 100644 src/test/ui/unsafe/rfc-2585-safe_packed_borrows-in-unsafe-fn.stderr diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index cacdf260548..b547ee89387 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -325,6 +325,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { store.register_renamed("exceeding_bitshifts", "arithmetic_overflow"); store.register_renamed("redundant_semicolon", "redundant_semicolons"); store.register_renamed("overlapping_patterns", "overlapping_range_endpoints"); + store.register_renamed("safe_packed_borrows", "unaligned_references"); // These were moved to tool lints, but rustc still sees them when compiling normally, before // tool lints are registered, so `check_tool_name_for_backwards_compat` doesn't work. Use diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index cd4d01ddc05..3baafee4612 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1057,6 +1057,7 @@ declare_lint! { /// unsafe { /// let foo = Foo { field1: 0, field2: 0 }; /// let _ = &foo.field1; + /// println!("{}", foo.field1); // An implicit `&` is added here, triggering the lint. /// } /// } /// ``` @@ -1065,20 +1066,20 @@ declare_lint! { /// /// ### Explanation /// - /// Creating a reference to an insufficiently aligned packed field is - /// [undefined behavior] and should be disallowed. - /// - /// This lint is "allow" by default because there is no stable - /// alternative, and it is not yet certain how widespread existing code - /// will trigger this lint. - /// - /// See [issue #27060] for more discussion. + /// Creating a reference to an insufficiently aligned packed field is [undefined behavior] and + /// should be disallowed. Using an `unsafe` block does not change anything about this. Instead, + /// the code should do a copy of the data in the packed field or use raw pointers and unaligned + /// accesses. See [issue #82523] for more information. /// /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html - /// [issue #27060]: https://github.com/rust-lang/rust/issues/27060 + /// [issue #82523]: https://github.com/rust-lang/rust/issues/82523 pub UNALIGNED_REFERENCES, - Allow, + Warn, "detects unaligned references to fields of packed structs", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #82523 ", + edition: None, + }; report_in_external_macro } @@ -1150,49 +1151,6 @@ declare_lint! { "detects attempts to mutate a `const` item", } -declare_lint! { - /// The `safe_packed_borrows` lint detects borrowing a field in the - /// interior of a packed structure with alignment other than 1. - /// - /// ### Example - /// - /// ```rust - /// #[repr(packed)] - /// pub struct Unaligned(pub T); - /// - /// pub struct Foo { - /// start: u8, - /// data: Unaligned, - /// } - /// - /// fn main() { - /// let x = Foo { start: 0, data: Unaligned(1) }; - /// let y = &x.data.0; - /// } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// This type of borrow is unsafe and can cause errors on some platforms - /// and violates some assumptions made by the compiler. This was - /// previously allowed unintentionally. This is a [future-incompatible] - /// lint to transition this to a hard error in the future. See [issue - /// #46043] for more details, including guidance on how to solve the - /// problem. - /// - /// [issue #46043]: https://github.com/rust-lang/rust/issues/46043 - /// [future-incompatible]: ../index.md#future-incompatible-lints - pub SAFE_PACKED_BORROWS, - Warn, - "safe borrows of fields of packed structs were erroneously allowed", - @future_incompatible = FutureIncompatibleInfo { - reference: "issue #46043 ", - edition: None, - }; -} - declare_lint! { /// The `patterns_in_fns_without_body` lint detects `mut` identifier /// patterns as a parameter in functions without a body. @@ -2953,7 +2911,6 @@ declare_lint_pass! { RENAMED_AND_REMOVED_LINTS, UNALIGNED_REFERENCES, CONST_ITEM_MUTATION, - SAFE_PACKED_BORROWS, PATTERNS_IN_FNS_WITHOUT_BODY, MISSING_FRAGMENT_SPECIFIER, LATE_BOUND_LIFETIME_ARGUMENTS, diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index bde48018013..ad3baccf154 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -23,15 +23,9 @@ pub enum UnsafetyViolationKind { General, /// Permitted both in `const fn`s and regular `fn`s. GeneralAndConstFn, - /// Borrow of packed field. - /// Has to be handled as a lint for backwards compatibility. - BorrowPacked, /// Unsafe operation in an `unsafe fn` but outside an `unsafe` block. /// Has to be handled as a lint for backwards compatibility. UnsafeFn, - /// Borrow of packed field in an `unsafe fn` but outside an `unsafe` block. - /// Has to be handled as a lint for backwards compatibility. - UnsafeFnBorrowPacked, } #[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)] diff --git a/compiler/rustc_mir/src/transform/check_packed_ref.rs b/compiler/rustc_mir/src/transform/check_packed_ref.rs index ee88daa83e7..13b7221046b 100644 --- a/compiler/rustc_mir/src/transform/check_packed_ref.rs +++ b/compiler/rustc_mir/src/transform/check_packed_ref.rs @@ -1,11 +1,18 @@ +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::*; +use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::builtin::UNALIGNED_REFERENCES; +use rustc_span::symbol::sym; use crate::transform::MirPass; use crate::util; +pub(crate) fn provide(providers: &mut Providers) { + *providers = Providers { unsafe_derive_on_repr_packed, ..*providers }; +} + pub struct CheckPackedRef; impl<'tcx> MirPass<'tcx> for CheckPackedRef { @@ -24,6 +31,41 @@ struct PackedRefChecker<'a, 'tcx> { source_info: SourceInfo, } +fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) { + let lint_hir_id = tcx.hir().local_def_id_to_hir_id(def_id); + + tcx.struct_span_lint_hir(UNALIGNED_REFERENCES, lint_hir_id, tcx.def_span(def_id), |lint| { + // FIXME: when we make this a hard error, this should have its + // own error code. + let message = if tcx.generics_of(def_id).own_requires_monomorphization() { + "`#[derive]` can't be used on a `#[repr(packed)]` struct with \ + type or const parameters (error E0133)" + .to_string() + } else { + "`#[derive]` can't be used on a `#[repr(packed)]` struct that \ + does not derive Copy (error E0133)" + .to_string() + }; + lint.build(&message).emit() + }); +} + +fn builtin_derive_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option { + debug!("builtin_derive_def_id({:?})", def_id); + if let Some(impl_def_id) = tcx.impl_of_method(def_id) { + if tcx.has_attr(impl_def_id, sym::automatically_derived) { + debug!("builtin_derive_def_id({:?}) - is {:?}", def_id, impl_def_id); + Some(impl_def_id) + } else { + debug!("builtin_derive_def_id({:?}) - not automatically derived", def_id); + None + } + } else { + debug!("builtin_derive_def_id({:?}) - not a method", def_id); + None + } +} + impl<'a, 'tcx> Visitor<'tcx> for PackedRefChecker<'a, 'tcx> { fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { // Make sure we know where in the MIR we are. @@ -40,26 +82,33 @@ impl<'a, 'tcx> Visitor<'tcx> for PackedRefChecker<'a, 'tcx> { fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { if context.is_borrow() { if util::is_disaligned(self.tcx, self.body, self.param_env, *place) { - let source_info = self.source_info; - let lint_root = self.body.source_scopes[source_info.scope] - .local_data - .as_ref() - .assert_crate_local() - .lint_root; - self.tcx.struct_span_lint_hir( - UNALIGNED_REFERENCES, - lint_root, - source_info.span, - |lint| { - lint.build("reference to packed field is unaligned") - .note( - "fields of packed structs are not properly aligned, and creating \ - a misaligned reference is undefined behavior (even if that \ - reference is never dereferenced)", - ) - .emit() - }, - ); + let def_id = self.body.source.instance.def_id(); + if let Some(impl_def_id) = builtin_derive_def_id(self.tcx, def_id) { + // If a method is defined in the local crate, + // the impl containing that method should also be. + self.tcx.ensure().unsafe_derive_on_repr_packed(impl_def_id.expect_local()); + } else { + let source_info = self.source_info; + let lint_root = self.body.source_scopes[source_info.scope] + .local_data + .as_ref() + .assert_crate_local() + .lint_root; + self.tcx.struct_span_lint_hir( + UNALIGNED_REFERENCES, + lint_root, + source_info.span, + |lint| { + lint.build("reference to packed field is unaligned") + .note( + "fields of packed structs are not properly aligned, and creating \ + a misaligned reference is undefined behavior (even if that \ + reference is never dereferenced)", + ) + .emit() + }, + ); + } } } } diff --git a/compiler/rustc_mir/src/transform/check_unsafety.rs b/compiler/rustc_mir/src/transform/check_unsafety.rs index 532d201e056..09da9b2e4d6 100644 --- a/compiler/rustc_mir/src/transform/check_unsafety.rs +++ b/compiler/rustc_mir/src/transform/check_unsafety.rs @@ -10,14 +10,12 @@ use rustc_middle::mir::*; use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt}; -use rustc_session::lint::builtin::{SAFE_PACKED_BORROWS, UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE}; +use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE}; use rustc_session::lint::Level; -use rustc_span::symbol::sym; use std::ops::Bound; use crate::const_eval::is_min_const_fn; -use crate::util; pub struct UnsafetyChecker<'a, 'tcx> { body: &'a Body<'tcx>, @@ -182,18 +180,6 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { self.check_mut_borrowing_layout_constrained_field(*place, context.is_mutating_use()); } - // Check for borrows to packed fields. - // `is_disaligned` already traverses the place to consider all projections after the last - // `Deref`, so this only needs to be called once at the top level. - if context.is_borrow() { - if util::is_disaligned(self.tcx, self.body, self.param_env, *place) { - self.require_unsafe( - UnsafetyViolationKind::BorrowPacked, - UnsafetyViolationDetails::BorrowOfPackedField, - ); - } - } - // Some checks below need the extra metainfo of the local declaration. let decl = &self.body.local_decls[place.local]; @@ -317,25 +303,15 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { // `unsafe` blocks are required in safe code Safety::Safe => { for violation in violations { - let mut violation = *violation; match violation.kind { UnsafetyViolationKind::GeneralAndConstFn | UnsafetyViolationKind::General => {} - UnsafetyViolationKind::BorrowPacked => { - if self.min_const_fn { - // const fns don't need to be backwards compatible and can - // emit these violations as a hard error instead of a backwards - // compat lint - violation.kind = UnsafetyViolationKind::General; - } - } - UnsafetyViolationKind::UnsafeFn - | UnsafetyViolationKind::UnsafeFnBorrowPacked => { + UnsafetyViolationKind::UnsafeFn => { bug!("`UnsafetyViolationKind::UnsafeFn` in an `Safe` context") } } - if !self.violations.contains(&violation) { - self.violations.push(violation) + if !self.violations.contains(violation) { + self.violations.push(*violation) } } false @@ -345,11 +321,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { for violation in violations { let mut violation = *violation; - if violation.kind == UnsafetyViolationKind::BorrowPacked { - violation.kind = UnsafetyViolationKind::UnsafeFnBorrowPacked; - } else { - violation.kind = UnsafetyViolationKind::UnsafeFn; - } + violation.kind = UnsafetyViolationKind::UnsafeFn; if !self.violations.contains(&violation) { self.violations.push(violation) } @@ -369,8 +341,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { // these unsafe things are stable in const fn UnsafetyViolationKind::GeneralAndConstFn => {} // these things are forbidden in const fns - UnsafetyViolationKind::General - | UnsafetyViolationKind::BorrowPacked => { + UnsafetyViolationKind::General => { let mut violation = *violation; // const fns don't need to be backwards compatible and can // emit these violations as a hard error instead of a backwards @@ -380,8 +351,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { self.violations.push(violation) } } - UnsafetyViolationKind::UnsafeFn - | UnsafetyViolationKind::UnsafeFnBorrowPacked => bug!( + UnsafetyViolationKind::UnsafeFn => bug!( "`UnsafetyViolationKind::UnsafeFn` in an `ExplicitUnsafe` context" ), } @@ -464,7 +434,6 @@ pub(crate) fn provide(providers: &mut Providers) { ty::WithOptConstParam { did, const_param_did: Some(param_did) }, ) }, - unsafe_derive_on_repr_packed, ..*providers }; } @@ -544,25 +513,6 @@ fn unsafety_check_result<'tcx>( }) } -fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) { - let lint_hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - - tcx.struct_span_lint_hir(SAFE_PACKED_BORROWS, lint_hir_id, tcx.def_span(def_id), |lint| { - // FIXME: when we make this a hard error, this should have its - // own error code. - let message = if tcx.generics_of(def_id).own_requires_monomorphization() { - "`#[derive]` can't be used on a `#[repr(packed)]` struct with \ - type or const parameters (error E0133)" - .to_string() - } else { - "`#[derive]` can't be used on a `#[repr(packed)]` struct that \ - does not derive Copy (error E0133)" - .to_string() - }; - lint.build(&message).emit() - }); -} - /// Returns the `HirId` for an enclosing scope that is also `unsafe`. fn is_enclosed( tcx: TyCtxt<'_>, @@ -609,22 +559,6 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, used_unsafe: &FxHashSet, id }); } -fn builtin_derive_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option { - debug!("builtin_derive_def_id({:?})", def_id); - if let Some(impl_def_id) = tcx.impl_of_method(def_id) { - if tcx.has_attr(impl_def_id, sym::automatically_derived) { - debug!("builtin_derive_def_id({:?}) - is {:?}", def_id, impl_def_id); - Some(impl_def_id) - } else { - debug!("builtin_derive_def_id({:?}) - not automatically derived", def_id); - None - } - } else { - debug!("builtin_derive_def_id({:?}) - not a method", def_id); - None - } -} - pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { debug!("check_unsafety({:?})", def_id); @@ -657,27 +591,6 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { .note(note) .emit(); } - UnsafetyViolationKind::BorrowPacked => { - if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id.to_def_id()) { - // If a method is defined in the local crate, - // the impl containing that method should also be. - tcx.ensure().unsafe_derive_on_repr_packed(impl_def_id.expect_local()); - } else { - tcx.struct_span_lint_hir( - SAFE_PACKED_BORROWS, - lint_root, - source_info.span, - |lint| { - lint.build(&format!( - "{} is unsafe and requires unsafe{} block (error E0133)", - description, unsafe_fn_msg, - )) - .note(note) - .emit() - }, - ) - } - } UnsafetyViolationKind::UnsafeFn => tcx.struct_span_lint_hir( UNSAFE_OP_IN_UNSAFE_FN, lint_root, @@ -692,35 +605,6 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { .emit(); }, ), - UnsafetyViolationKind::UnsafeFnBorrowPacked => { - // When `unsafe_op_in_unsafe_fn` is disallowed, the behavior of safe and unsafe functions - // should be the same in terms of warnings and errors. Therefore, with `#[warn(safe_packed_borrows)]`, - // a safe packed borrow should emit a warning *but not an error* in an unsafe function, - // just like in a safe function, even if `unsafe_op_in_unsafe_fn` is `deny`. - // - // Also, `#[warn(unsafe_op_in_unsafe_fn)]` can't cause any new errors. Therefore, with - // `#[deny(safe_packed_borrows)]` and `#[warn(unsafe_op_in_unsafe_fn)]`, a packed borrow - // should only issue a warning for the sake of backwards compatibility. - // - // The solution those 2 expectations is to always take the minimum of both lints. - // This prevent any new errors (unless both lints are explicitly set to `deny`). - let lint = if tcx.lint_level_at_node(SAFE_PACKED_BORROWS, lint_root).0 - <= tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, lint_root).0 - { - SAFE_PACKED_BORROWS - } else { - UNSAFE_OP_IN_UNSAFE_FN - }; - tcx.struct_span_lint_hir(&lint, lint_root, source_info.span, |lint| { - lint.build(&format!( - "{} is unsafe and requires unsafe block (error E0133)", - description, - )) - .span_label(source_info.span, description) - .note(note) - .emit(); - }) - } } } diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index 66d2ab8a3f1..5c49ee69edc 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -59,6 +59,7 @@ pub use rustc_middle::mir::MirSource; pub(crate) fn provide(providers: &mut Providers) { self::check_unsafety::provide(providers); + self::check_packed_ref::provide(providers); *providers = Providers { mir_keys, mir_const, diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 7e4f8d570a7..2392f0174b6 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -767,6 +767,7 @@ pub const unsafe fn read(src: *const T) -> T { /// unaligned: 0x01020304, /// }; /// +/// #[allow(unaligned_references)] /// let v = unsafe { /// // Here we attempt to take the address of a 32-bit integer which is not aligned. /// let unaligned = @@ -960,6 +961,7 @@ pub const unsafe fn write(dst: *mut T, src: T) { /// let v = 0x01020304; /// let mut packed: Packed = unsafe { std::mem::zeroed() }; /// +/// #[allow(unaligned_references)] /// let v = unsafe { /// // Here we attempt to take the address of a 32-bit integer which is not aligned. /// let unaligned = diff --git a/src/test/ui/binding/issue-53114-safety-checks.rs b/src/test/ui/binding/issue-53114-safety-checks.rs index 28adb7571a9..ca4f0efd239 100644 --- a/src/test/ui/binding/issue-53114-safety-checks.rs +++ b/src/test/ui/binding/issue-53114-safety-checks.rs @@ -20,13 +20,13 @@ fn let_wild_gets_unsafe_field() { let u1 = U { a: I(0) }; let u2 = U { a: I(1) }; let p = P { a: &2, b: &3 }; - let _ = &p.b; //~ WARN E0133 + let _ = &p.b; //~ WARN reference to packed field //~^ WARN will become a hard error let _ = u1.a; // #53114: should eventually signal error as well let _ = &u2.a; //~ ERROR [E0133] // variation on above with `_` in substructure - let (_,) = (&p.b,); //~ WARN E0133 + let (_,) = (&p.b,); //~ WARN reference to packed field //~^ WARN will become a hard error let (_,) = (u1.a,); //~ ERROR [E0133] let (_,) = (&u2.a,); //~ ERROR [E0133] @@ -36,13 +36,13 @@ fn match_unsafe_field_to_wild() { let u1 = U { a: I(0) }; let u2 = U { a: I(1) }; let p = P { a: &2, b: &3 }; - match &p.b { _ => { } } //~ WARN E0133 + match &p.b { _ => { } } //~ WARN reference to packed field //~^ WARN will become a hard error match u1.a { _ => { } } //~ ERROR [E0133] match &u2.a { _ => { } } //~ ERROR [E0133] // variation on above with `_` in substructure - match (&p.b,) { (_,) => { } } //~ WARN E0133 + match (&p.b,) { (_,) => { } } //~ WARN reference to packed field //~^ WARN will become a hard error match (u1.a,) { (_,) => { } } //~ ERROR [E0133] match (&u2.a,) { (_,) => { } } //~ ERROR [E0133] diff --git a/src/test/ui/binding/issue-53114-safety-checks.stderr b/src/test/ui/binding/issue-53114-safety-checks.stderr index d4b8dfbade5..9e7deea4524 100644 --- a/src/test/ui/binding/issue-53114-safety-checks.stderr +++ b/src/test/ui/binding/issue-53114-safety-checks.stderr @@ -1,13 +1,43 @@ -warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133) +warning: reference to packed field is unaligned --> $DIR/issue-53114-safety-checks.rs:23:13 | LL | let _ = &p.b; | ^^^^ | - = note: `#[warn(safe_packed_borrows)]` on by default + = note: `#[warn(unaligned_references)]` on by default = 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 #46043 - = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior + = note: for more information, see issue #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +warning: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:29:17 + | +LL | let (_,) = (&p.b,); + | ^^^^ + | + = 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 #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +warning: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:39:11 + | +LL | match &p.b { _ => { } } + | ^^^^ + | + = 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 #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +warning: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:45:12 + | +LL | match (&p.b,) { (_,) => { } } + | ^^^^ + | + = 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 #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) error[E0133]: access to union field is unsafe and requires unsafe function or block --> $DIR/issue-53114-safety-checks.rs:26:13 @@ -17,16 +47,6 @@ LL | let _ = &u2.a; | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133) - --> $DIR/issue-53114-safety-checks.rs:29:17 - | -LL | let (_,) = (&p.b,); - | ^^^^ - | - = 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 #46043 - = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior - error[E0133]: access to union field is unsafe and requires unsafe function or block --> $DIR/issue-53114-safety-checks.rs:31:17 | @@ -43,16 +63,6 @@ LL | let (_,) = (&u2.a,); | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133) - --> $DIR/issue-53114-safety-checks.rs:39:11 - | -LL | match &p.b { _ => { } } - | ^^^^ - | - = 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 #46043 - = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior - error[E0133]: access to union field is unsafe and requires unsafe function or block --> $DIR/issue-53114-safety-checks.rs:41:11 | @@ -69,16 +79,6 @@ LL | match &u2.a { _ => { } } | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133) - --> $DIR/issue-53114-safety-checks.rs:45:12 - | -LL | match (&p.b,) { (_,) => { } } - | ^^^^ - | - = 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 #46043 - = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior - error[E0133]: access to union field is unsafe and requires unsafe function or block --> $DIR/issue-53114-safety-checks.rs:47:12 | diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs index 6fce2951505..82ec60a2e79 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs @@ -23,7 +23,7 @@ fn test_missing_unsafe_warning_on_repr_packed() { let c = || { println!("{}", foo.x); - //~^ WARNING: borrow of packed field is unsafe and requires unsafe function or block + //~^ WARNING: reference to packed field is unaligned //~| WARNING: this was previously accepted by the compiler but is being phased out let _z = foo.x; }; diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr index 440b2c54c0a..e8cc164be87 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr @@ -7,16 +7,16 @@ LL | #![feature(capture_disjoint_fields)] = note: `#[warn(incomplete_features)]` on by default = note: see issue #53488 for more information -warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133) +warning: reference to packed field is unaligned --> $DIR/repr_packed.rs:25:24 | LL | println!("{}", foo.x); | ^^^^^ | - = note: `#[warn(safe_packed_borrows)]` on by default + = note: `#[warn(unaligned_references)]` on by default = 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 #46043 - = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior + = note: for more information, see issue #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) warning: 2 warnings emitted diff --git a/src/test/ui/derives/deriving-with-repr-packed.rs b/src/test/ui/derives/deriving-with-repr-packed.rs index d354cef66bc..b78eeaa9055 100644 --- a/src/test/ui/derives/deriving-with-repr-packed.rs +++ b/src/test/ui/derives/deriving-with-repr-packed.rs @@ -1,4 +1,4 @@ -#![deny(safe_packed_borrows)] +#![deny(unaligned_references)] // check that derive on a packed struct with non-Copy fields // correctly. This can't be made to work perfectly because diff --git a/src/test/ui/derives/deriving-with-repr-packed.stderr b/src/test/ui/derives/deriving-with-repr-packed.stderr index d739257c8de..3caa563a085 100644 --- a/src/test/ui/derives/deriving-with-repr-packed.stderr +++ b/src/test/ui/derives/deriving-with-repr-packed.stderr @@ -7,10 +7,10 @@ LL | #[derive(Copy, Clone, PartialEq, Eq)] note: the lint level is defined here --> $DIR/deriving-with-repr-packed.rs:1:9 | -LL | #![deny(safe_packed_borrows)] - | ^^^^^^^^^^^^^^^^^^^ +LL | #![deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ = 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 #46043 + = note: for more information, see issue #82523 = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133) @@ -20,7 +20,7 @@ LL | #[derive(Copy, Clone, PartialEq, Eq)] | ^^^^^^^^^ | = 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 #46043 + = note: for more information, see issue #82523 = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133) @@ -30,7 +30,7 @@ LL | #[derive(PartialEq, Eq)] | ^^^^^^^^^ | = 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 #46043 + = note: for more information, see issue #82523 = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133) @@ -40,7 +40,7 @@ LL | #[derive(PartialEq)] | ^^^^^^^^^ | = 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 #46043 + = note: for more information, see issue #82523 = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-27060-rpass.rs b/src/test/ui/issues/issue-27060-rpass.rs index b20d614b303..d9159f6669d 100644 --- a/src/test/ui/issues/issue-27060-rpass.rs +++ b/src/test/ui/issues/issue-27060-rpass.rs @@ -8,14 +8,12 @@ pub struct Good { } // kill this test when that turns to a hard error -#[allow(safe_packed_borrows)] +#[allow(unaligned_references)] fn main() { let good = Good { data: &0, data2: [&0, &0], aligned: [0; 32] }; - unsafe { - let _ = &good.data; // ok - let _ = &good.data2[0]; // ok - } + let _ = &good.data; // ok + let _ = &good.data2[0]; // ok let _ = &good.data; let _ = &good.data2[0]; diff --git a/src/test/ui/issues/issue-27060.rs b/src/test/ui/issues/issue-27060.rs index 78f2022ed38..5317a616719 100644 --- a/src/test/ui/issues/issue-27060.rs +++ b/src/test/ui/issues/issue-27060.rs @@ -5,7 +5,7 @@ pub struct Good { aligned: [u8; 32], } -#[deny(safe_packed_borrows)] +#[deny(unaligned_references)] fn main() { let good = Good { data: &0, @@ -13,14 +13,14 @@ fn main() { aligned: [0; 32] }; - unsafe { - let _ = &good.data; // ok - let _ = &good.data2[0]; // ok - } + let _ = &good.data; //~ ERROR reference to packed field + //~| hard error + let _ = &good.data2[0]; //~ ERROR reference to packed field + //~| hard error - let _ = &good.data; //~ ERROR borrow of packed field is unsafe + let _ = &good.data; //~ ERROR reference to packed field //~| hard error - let _ = &good.data2[0]; //~ ERROR borrow of packed field is unsafe + let _ = &good.data2[0]; //~ ERROR reference to packed field //~| hard error let _ = &*good.data; // ok, behind a pointer let _ = &good.aligned; // ok, has align 1 diff --git a/src/test/ui/issues/issue-27060.stderr b/src/test/ui/issues/issue-27060.stderr index d14ae4d41d5..09297884ed3 100644 --- a/src/test/ui/issues/issue-27060.stderr +++ b/src/test/ui/issues/issue-27060.stderr @@ -1,5 +1,5 @@ -error: borrow of packed field is unsafe and requires unsafe function or block (error E0133) - --> $DIR/issue-27060.rs:21:13 +error: reference to packed field is unaligned + --> $DIR/issue-27060.rs:16:13 | LL | let _ = &good.data; | ^^^^^^^^^^ @@ -7,21 +7,41 @@ LL | let _ = &good.data; note: the lint level is defined here --> $DIR/issue-27060.rs:8:8 | -LL | #[deny(safe_packed_borrows)] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ = 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 #46043 - = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior + = note: for more information, see issue #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) -error: borrow of packed field is unsafe and requires unsafe function or block (error E0133) +error: reference to packed field is unaligned + --> $DIR/issue-27060.rs:18:13 + | +LL | let _ = &good.data2[0]; + | ^^^^^^^^^^^^^^ + | + = 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 #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +error: reference to packed field is unaligned + --> $DIR/issue-27060.rs:21:13 + | +LL | let _ = &good.data; + | ^^^^^^^^^^ + | + = 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 #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +error: reference to packed field is unaligned --> $DIR/issue-27060.rs:23:13 | LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ | = 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 #46043 - = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior + = note: for more information, see issue #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors diff --git a/src/test/ui/lint/unaligned_references.rs b/src/test/ui/lint/unaligned_references.rs index c4e5d065643..ad38c21d96c 100644 --- a/src/test/ui/lint/unaligned_references.rs +++ b/src/test/ui/lint/unaligned_references.rs @@ -13,14 +13,20 @@ fn main() { let good = Good { data: 0, ptr: &0, data2: [0, 0], aligned: [0; 32] }; let _ = &good.ptr; //~ ERROR reference to packed field + //~^ previously accepted let _ = &good.data; //~ ERROR reference to packed field + //~^ previously accepted // Error even when turned into raw pointer immediately. let _ = &good.data as *const _; //~ ERROR reference to packed field + //~^ previously accepted let _: *const _ = &good.data; //~ ERROR reference to packed field + //~^ previously accepted // Error on method call. let _ = good.data.clone(); //~ ERROR reference to packed field + //~^ previously accepted // Error for nested fields. let _ = &good.data2[0]; //~ ERROR reference to packed field + //~^ previously accepted let _ = &*good.ptr; // ok, behind a pointer let _ = &good.aligned; // ok, has align 1 diff --git a/src/test/ui/lint/unaligned_references.stderr b/src/test/ui/lint/unaligned_references.stderr index 8786b9c05db..9ae25f5b59e 100644 --- a/src/test/ui/lint/unaligned_references.stderr +++ b/src/test/ui/lint/unaligned_references.stderr @@ -9,46 +9,58 @@ note: the lint level is defined here | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ + = 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 #82523 = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) error: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:16:17 + --> $DIR/unaligned_references.rs:17:17 | LL | let _ = &good.data; | ^^^^^^^^^^ | + = 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 #82523 = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) error: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:18:17 + --> $DIR/unaligned_references.rs:20:17 | LL | let _ = &good.data as *const _; | ^^^^^^^^^^ | + = 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 #82523 = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) error: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:19:27 + --> $DIR/unaligned_references.rs:22:27 | LL | let _: *const _ = &good.data; | ^^^^^^^^^^ | + = 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 #82523 = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) error: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:21:17 + --> $DIR/unaligned_references.rs:25:17 | LL | let _ = good.data.clone(); | ^^^^^^^^^ | + = 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 #82523 = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) error: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:23:17 + --> $DIR/unaligned_references.rs:28:17 | LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ | + = 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 #82523 = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) error: aborting due to 6 previous errors diff --git a/src/test/ui/lint/unaligned_references_external_macro.rs b/src/test/ui/lint/unaligned_references_external_macro.rs index 6ac501fb0e0..cb597c38e77 100644 --- a/src/test/ui/lint/unaligned_references_external_macro.rs +++ b/src/test/ui/lint/unaligned_references_external_macro.rs @@ -1,10 +1,9 @@ // aux-build:unaligned_references_external_crate.rs -#![allow(safe_packed_borrows)] - extern crate unaligned_references_external_crate; unaligned_references_external_crate::mac! { //~ERROR reference to packed field is unaligned + //~^ previously accepted #[repr(packed)] pub struct X { pub field: u16 diff --git a/src/test/ui/lint/unaligned_references_external_macro.stderr b/src/test/ui/lint/unaligned_references_external_macro.stderr index 140294b65cc..4e7c6bfc98d 100644 --- a/src/test/ui/lint/unaligned_references_external_macro.stderr +++ b/src/test/ui/lint/unaligned_references_external_macro.stderr @@ -1,7 +1,8 @@ error: reference to packed field is unaligned - --> $DIR/unaligned_references_external_macro.rs:7:1 + --> $DIR/unaligned_references_external_macro.rs:5:1 | LL | / unaligned_references_external_crate::mac! { +LL | | LL | | #[repr(packed)] LL | | pub struct X { LL | | pub field: u16 @@ -10,15 +11,18 @@ LL | | } | |_^ | note: the lint level is defined here - --> $DIR/unaligned_references_external_macro.rs:7:1 + --> $DIR/unaligned_references_external_macro.rs:5:1 | LL | / unaligned_references_external_crate::mac! { +LL | | LL | | #[repr(packed)] LL | | pub struct X { LL | | pub field: u16 LL | | } LL | | } | |_^ + = 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 #82523 = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/packed/packed-struct-address-of-element.rs b/src/test/ui/packed/packed-struct-address-of-element.rs index 812d23fb580..fb3875e6804 100644 --- a/src/test/ui/packed/packed-struct-address-of-element.rs +++ b/src/test/ui/packed/packed-struct-address-of-element.rs @@ -1,6 +1,6 @@ // run-pass #![allow(dead_code)] -#![deny(safe_packed_borrows)] +#![deny(unaligned_references)] #![feature(raw_ref_op)] // ignore-emscripten weird assertion? diff --git a/src/test/ui/packed/packed-struct-borrow-element.rs b/src/test/ui/packed/packed-struct-borrow-element.rs index 0072b6191eb..5dad084eecf 100644 --- a/src/test/ui/packed/packed-struct-borrow-element.rs +++ b/src/test/ui/packed/packed-struct-borrow-element.rs @@ -22,14 +22,17 @@ struct Foo4C { pub fn main() { let foo = Foo1 { bar: 1, baz: 2 }; - let brw = unsafe { &foo.baz }; + let brw = &foo.baz; //~WARN reference to packed field is unaligned + //~^ previously accepted assert_eq!(*brw, 2); let foo = Foo2 { bar: 1, baz: 2 }; - let brw = unsafe { &foo.baz }; + let brw = &foo.baz; //~WARN reference to packed field is unaligned + //~^ previously accepted assert_eq!(*brw, 2); let foo = Foo4C { bar: 1, baz: 2 }; - let brw = unsafe { &foo.baz }; + let brw = &foo.baz; //~WARN reference to packed field is unaligned + //~^ previously accepted assert_eq!(*brw, 2); } diff --git a/src/test/ui/packed/packed-struct-borrow-element.stderr b/src/test/ui/packed/packed-struct-borrow-element.stderr new file mode 100644 index 00000000000..d9d9a71ff58 --- /dev/null +++ b/src/test/ui/packed/packed-struct-borrow-element.stderr @@ -0,0 +1,33 @@ +warning: reference to packed field is unaligned + --> $DIR/packed-struct-borrow-element.rs:25:15 + | +LL | let brw = &foo.baz; + | ^^^^^^^^ + | + = note: `#[warn(unaligned_references)]` on by default + = 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 #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +warning: reference to packed field is unaligned + --> $DIR/packed-struct-borrow-element.rs:30:15 + | +LL | let brw = &foo.baz; + | ^^^^^^^^ + | + = 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 #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +warning: reference to packed field is unaligned + --> $DIR/packed-struct-borrow-element.rs:35:15 + | +LL | let brw = &foo.baz; + | ^^^^^^^^ + | + = 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 #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +warning: 3 warnings emitted + diff --git a/src/test/ui/unsafe/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs b/src/test/ui/unsafe/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs deleted file mode 100644 index 540612a7dce..00000000000 --- a/src/test/ui/unsafe/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs +++ /dev/null @@ -1,67 +0,0 @@ -#![feature(unsafe_block_in_unsafe_fn)] - -#[repr(packed)] -pub struct Packed { - data: &'static u32, -} - -const PACKED: Packed = Packed { data: &0 }; - -#[allow(safe_packed_borrows)] -#[allow(unsafe_op_in_unsafe_fn)] -unsafe fn allow_allow() { - &PACKED.data; // allowed -} - -#[allow(safe_packed_borrows)] -#[warn(unsafe_op_in_unsafe_fn)] -unsafe fn allow_warn() { - &PACKED.data; // allowed -} - -#[allow(safe_packed_borrows)] -#[deny(unsafe_op_in_unsafe_fn)] -unsafe fn allow_deny() { - &PACKED.data; // allowed -} - -#[warn(safe_packed_borrows)] -#[allow(unsafe_op_in_unsafe_fn)] -unsafe fn warn_allow() { - &PACKED.data; // allowed -} - -#[warn(safe_packed_borrows)] -#[warn(unsafe_op_in_unsafe_fn)] -unsafe fn warn_warn() { - &PACKED.data; //~ WARN - //~| WARNING this was previously accepted by the compiler but is being phased out -} - -#[warn(safe_packed_borrows)] -#[deny(unsafe_op_in_unsafe_fn)] -unsafe fn warn_deny() { - &PACKED.data; //~ WARN - //~| WARNING this was previously accepted by the compiler but is being phased out -} - -#[deny(safe_packed_borrows)] -#[allow(unsafe_op_in_unsafe_fn)] -unsafe fn deny_allow() { - &PACKED.data; // allowed -} - -#[deny(safe_packed_borrows)] -#[warn(unsafe_op_in_unsafe_fn)] -unsafe fn deny_warn() { - &PACKED.data; //~ WARN -} - -#[deny(safe_packed_borrows)] -#[deny(unsafe_op_in_unsafe_fn)] -unsafe fn deny_deny() { - &PACKED.data; //~ ERROR - //~| WARNING this was previously accepted by the compiler but is being phased out -} - -fn main() {} diff --git a/src/test/ui/unsafe/rfc-2585-safe_packed_borrows-in-unsafe-fn.stderr b/src/test/ui/unsafe/rfc-2585-safe_packed_borrows-in-unsafe-fn.stderr deleted file mode 100644 index fda15159643..00000000000 --- a/src/test/ui/unsafe/rfc-2585-safe_packed_borrows-in-unsafe-fn.stderr +++ /dev/null @@ -1,60 +0,0 @@ -warning: borrow of packed field is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:37:5 - | -LL | &PACKED.data; - | ^^^^^^^^^^^^ borrow of packed field - | -note: the lint level is defined here - --> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:34:8 - | -LL | #[warn(safe_packed_borrows)] - | ^^^^^^^^^^^^^^^^^^^ - = 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 #46043 - = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior - -warning: borrow of packed field is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:44:5 - | -LL | &PACKED.data; - | ^^^^^^^^^^^^ borrow of packed field - | -note: the lint level is defined here - --> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:41:8 - | -LL | #[warn(safe_packed_borrows)] - | ^^^^^^^^^^^^^^^^^^^ - = 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 #46043 - = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior - -warning: borrow of packed field is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:57:5 - | -LL | &PACKED.data; - | ^^^^^^^^^^^^ borrow of packed field - | -note: the lint level is defined here - --> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:55:8 - | -LL | #[warn(unsafe_op_in_unsafe_fn)] - | ^^^^^^^^^^^^^^^^^^^^^^ - = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior - -error: borrow of packed field is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:63:5 - | -LL | &PACKED.data; - | ^^^^^^^^^^^^ borrow of packed field - | -note: the lint level is defined here - --> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:60:8 - | -LL | #[deny(safe_packed_borrows)] - | ^^^^^^^^^^^^^^^^^^^ - = 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 #46043 - = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior - -error: aborting due to previous error; 3 warnings emitted - From 94b51d14e6770f6e8cfec4bf4c0d5805caa58143 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 27 Mar 2021 17:32:41 +0100 Subject: [PATCH 148/370] Make all compiler-builtins symbols hidden This matches cg_llvm Fixes #1152 --- src/base.rs | 8 ++------ src/compiler_builtins.rs | 41 ++++++++++++++++++++++++++++++++++++++++ src/driver/aot.rs | 5 ++--- src/driver/jit.rs | 11 ++++------- src/driver/mod.rs | 8 +++++++- src/lib.rs | 1 + src/linkage.rs | 2 ++ 7 files changed, 59 insertions(+), 17 deletions(-) create mode 100644 src/compiler_builtins.rs diff --git a/src/base.rs b/src/base.rs index 7cd7bb1de41..b34a29c25b9 100644 --- a/src/base.rs +++ b/src/base.rs @@ -8,11 +8,7 @@ use rustc_target::abi::call::FnAbi; use crate::prelude::*; -pub(crate) fn codegen_fn<'tcx>( - cx: &mut crate::CodegenCx<'_, 'tcx>, - instance: Instance<'tcx>, - linkage: Linkage, -) { +pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: Instance<'tcx>) { let tcx = cx.tcx; let _inst_guard = @@ -24,7 +20,7 @@ pub(crate) fn codegen_fn<'tcx>( // Declare function let name = tcx.symbol_name(instance).name.to_string(); let sig = get_function_sig(tcx, cx.module.isa().triple(), instance); - let func_id = cx.module.declare_function(&name, linkage, &sig).unwrap(); + let func_id = cx.module.declare_function(&name, Linkage::Local, &sig).unwrap(); cx.cached_context.clear(); diff --git a/src/compiler_builtins.rs b/src/compiler_builtins.rs new file mode 100644 index 00000000000..177f850afb3 --- /dev/null +++ b/src/compiler_builtins.rs @@ -0,0 +1,41 @@ +macro builtin_functions($register:ident; $(fn $name:ident($($arg_name:ident: $arg_ty:ty),*) -> $ret_ty:ty;)*) { + #[cfg(feature = "jit")] + #[allow(improper_ctypes)] + extern "C" { + $(fn $name($($arg_name: $arg_ty),*) -> $ret_ty;)* + } + + #[cfg(feature = "jit")] + pub(crate) fn $register(builder: &mut cranelift_jit::JITBuilder) { + for &(name, val) in &[$((stringify!($name), $name as *const u8)),*] { + builder.symbol(name, val); + } + } +} + +builtin_functions! { + register_functions_for_jit; + + // integers + fn __multi3(a: i128, b: i128) -> i128; + fn __udivti3(n: u128, d: u128) -> u128; + fn __divti3(n: i128, d: i128) -> i128; + fn __umodti3(n: u128, d: u128) -> u128; + fn __modti3(n: i128, d: i128) -> i128; + fn __rust_u128_addo(a: u128, b: u128) -> (u128, bool); + fn __rust_i128_addo(a: i128, b: i128) -> (i128, bool); + fn __rust_u128_subo(a: u128, b: u128) -> (u128, bool); + fn __rust_i128_subo(a: i128, b: i128) -> (i128, bool); + fn __rust_u128_mulo(a: u128, b: u128) -> (u128, bool); + fn __rust_i128_mulo(a: i128, b: i128) -> (i128, bool); + + // floats + fn __floattisf(i: i128) -> f32; + fn __floattidf(i: i128) -> f64; + fn __floatuntisf(i: u128) -> f32; + fn __floatuntidf(i: u128) -> f64; + fn __fixsfti(f: f32) -> i128; + fn __fixdfti(f: f64) -> i128; + fn __fixunssfti(f: f32) -> u128; + fn __fixunsdfti(f: f64) -> u128; +} diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 3f3cdab058b..ed3bdedddce 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -119,11 +119,10 @@ fn module_codegen( tcx.sess.opts.debuginfo != DebugInfo::None, ); super::predefine_mono_items(&mut cx, &mono_items); - for (mono_item, (linkage, visibility)) in mono_items { - let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility); + for (mono_item, _) in mono_items { match mono_item { MonoItem::Fn(inst) => { - cx.tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, inst, linkage)); + cx.tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, inst)); } MonoItem::Static(def_id) => { crate::constant::codegen_static(&mut cx.constants_cx, def_id) diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 1b08b416913..dbe1ff083f0 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -30,6 +30,7 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { let mut jit_builder = JITBuilder::with_isa(crate::build_isa(tcx.sess), cranelift_module::default_libcall_names()); jit_builder.hotswap(matches!(backend_config.codegen_mode, CodegenMode::JitLazy)); + crate::compiler_builtins::register_functions_for_jit(&mut jit_builder); jit_builder.symbols(imported_symbols); let mut jit_module = JITModule::new(jit_builder); assert_eq!(pointer_ty(tcx), jit_module.target_config().pointer_type()); @@ -47,15 +48,12 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { super::time(tcx, "codegen mono items", || { super::predefine_mono_items(&mut cx, &mono_items); - for (mono_item, (linkage, visibility)) in mono_items { - let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility); + for (mono_item, _) in mono_items { match mono_item { MonoItem::Fn(inst) => match backend_config.codegen_mode { CodegenMode::Aot => unreachable!(), CodegenMode::Jit => { - cx.tcx - .sess - .time("codegen fn", || crate::base::codegen_fn(&mut cx, inst, linkage)); + cx.tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, inst)); } CodegenMode::JitLazy => codegen_shim(&mut cx, inst), }, @@ -175,8 +173,7 @@ extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>) -> *const u8 jit_module.prepare_for_function_redefine(func_id).unwrap(); let mut cx = crate::CodegenCx::new(tcx, backend_config, jit_module, false); - tcx.sess - .time("codegen fn", || crate::base::codegen_fn(&mut cx, instance, Linkage::Export)); + tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, instance)); let (global_asm, _debug_context, unwind_context) = cx.finalize(); assert!(global_asm.is_empty()); diff --git a/src/driver/mod.rs b/src/driver/mod.rs index b994f28ffef..d49182a07b7 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -44,13 +44,19 @@ fn predefine_mono_items<'tcx>( mono_items: &[(MonoItem<'tcx>, (RLinkage, Visibility))], ) { cx.tcx.sess.time("predefine functions", || { + let is_compiler_builtins = cx.tcx.is_compiler_builtins(LOCAL_CRATE); for &(mono_item, (linkage, visibility)) in mono_items { match mono_item { MonoItem::Fn(instance) => { let name = cx.tcx.symbol_name(instance).name.to_string(); let _inst_guard = crate::PrintOnPanic(|| format!("{:?} {}", instance, name)); let sig = get_function_sig(cx.tcx, cx.module.isa().triple(), instance); - let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility); + let linkage = crate::linkage::get_clif_linkage( + mono_item, + linkage, + visibility, + is_compiler_builtins, + ); cx.module.declare_function(&name, linkage, &sig).unwrap(); } MonoItem::Static(_) | MonoItem::GlobalAsm(_) => {} diff --git a/src/lib.rs b/src/lib.rs index 2d18f585dc8..720d2a12534 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,6 +48,7 @@ mod base; mod cast; mod codegen_i128; mod common; +mod compiler_builtins; mod constant; mod debuginfo; mod discriminant; diff --git a/src/linkage.rs b/src/linkage.rs index dc1e2107ce7..a564a59f725 100644 --- a/src/linkage.rs +++ b/src/linkage.rs @@ -6,8 +6,10 @@ pub(crate) fn get_clif_linkage( mono_item: MonoItem<'_>, linkage: RLinkage, visibility: Visibility, + is_compiler_builtins: bool, ) -> Linkage { match (linkage, visibility) { + (RLinkage::External, Visibility::Default) if is_compiler_builtins => Linkage::Hidden, (RLinkage::External, Visibility::Default) => Linkage::Export, (RLinkage::Internal, Visibility::Default) => Linkage::Local, (RLinkage::External, Visibility::Hidden) => Linkage::Hidden, From f0a6052d62251075bdc55c9d639df459a213612e Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sat, 27 Mar 2021 10:14:54 -0700 Subject: [PATCH 149/370] Add the tracking issue for `#![feature(iter_zip)]` --- library/core/src/iter/adapters/mod.rs | 2 +- library/core/src/iter/adapters/zip.rs | 2 +- library/core/src/iter/mod.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index 3859d76ad5e..ba4050757cb 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -51,7 +51,7 @@ pub use self::map_while::MapWhile; #[unstable(feature = "trusted_random_access", issue = "none")] pub use self::zip::TrustedRandomAccess; -#[unstable(feature = "iter_zip", issue = "none")] +#[unstable(feature = "iter_zip", issue = "83574")] pub use self::zip::zip; /// This trait provides transitive access to source-stage in an interator-adapter pipeline diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs index ad630ba95b8..2f8f504d8fc 100644 --- a/library/core/src/iter/adapters/zip.rs +++ b/library/core/src/iter/adapters/zip.rs @@ -55,7 +55,7 @@ impl Zip { /// println!("x:{}, y:{}, z:{}", x, y, z); /// } /// ``` -#[unstable(feature = "iter_zip", issue = "none")] +#[unstable(feature = "iter_zip", issue = "83574")] pub fn zip(a: A, b: B) -> Zip where A: IntoIterator, diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs index 8d905feeb49..2a179f0b1d7 100644 --- a/library/core/src/iter/mod.rs +++ b/library/core/src/iter/mod.rs @@ -389,7 +389,7 @@ pub use self::traits::{ DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator, Product, Sum, }; -#[unstable(feature = "iter_zip", issue = "none")] +#[unstable(feature = "iter_zip", issue = "83574")] pub use self::adapters::zip; #[stable(feature = "iter_cloned", since = "1.1.0")] pub use self::adapters::Cloned; From d29d87f08bcb495f94b1ebb1b8d1ea197da86dbc Mon Sep 17 00:00:00 2001 From: Violet Date: Sat, 27 Mar 2021 13:45:30 -0400 Subject: [PATCH 150/370] update links to make_ascii_lowercase for slice to point to methods on the same type, rather than on u8 --- library/alloc/src/slice.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 8cd4ef7a14e..7cbb88c820d 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -642,7 +642,7 @@ impl [u8] { /// /// To uppercase the value in-place, use [`make_ascii_uppercase`]. /// - /// [`make_ascii_uppercase`]: u8::make_ascii_uppercase + /// [`make_ascii_uppercase`]: #method.make_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_uppercase(&self) -> Vec { @@ -659,7 +659,7 @@ impl [u8] { /// /// To lowercase the value in-place, use [`make_ascii_lowercase`]. /// - /// [`make_ascii_lowercase`]: u8::make_ascii_lowercase + /// [`make_ascii_lowercase`]: #method.make_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_lowercase(&self) -> Vec { From 634d48d9d6a27a74400de4bbd7a28147d2665ad1 Mon Sep 17 00:00:00 2001 From: Violet Date: Sat, 27 Mar 2021 14:15:42 -0400 Subject: [PATCH 151/370] adjust documentation links for slice ascii case functions to use newer rustdoc link format --- library/alloc/src/slice.rs | 4 ++-- library/core/src/slice/ascii.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 7cbb88c820d..036b84bb1d5 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -642,7 +642,7 @@ impl [u8] { /// /// To uppercase the value in-place, use [`make_ascii_uppercase`]. /// - /// [`make_ascii_uppercase`]: #method.make_ascii_uppercase + /// [`make_ascii_uppercase`]: slice::make_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_uppercase(&self) -> Vec { @@ -659,7 +659,7 @@ impl [u8] { /// /// To lowercase the value in-place, use [`make_ascii_lowercase`]. /// - /// [`make_ascii_lowercase`]: #method.make_ascii_lowercase + /// [`make_ascii_lowercase`]: slice::make_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_lowercase(&self) -> Vec { diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 42032bc9035..4249ac77d47 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -30,7 +30,7 @@ impl [u8] { /// To return a new uppercased value without modifying the existing one, use /// [`to_ascii_uppercase`]. /// - /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase + /// [`to_ascii_uppercase`]: slice::to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn make_ascii_uppercase(&mut self) { @@ -47,7 +47,7 @@ impl [u8] { /// To return a new lowercased value without modifying the existing one, use /// [`to_ascii_lowercase`]. /// - /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase + /// [`to_ascii_lowercase`]: slice::to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn make_ascii_lowercase(&mut self) { From b5d71bfb0f229472c48554c9df4bbfedd0633430 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 27 Mar 2021 19:26:10 +0100 Subject: [PATCH 152/370] add definition of 'allocated object', and link it from relevant method docs --- library/core/src/ptr/const_ptr.rs | 37 +++++++++++++++-------------- library/core/src/ptr/mod.rs | 8 +++++++ library/core/src/ptr/mut_ptr.rs | 39 ++++++++++++++++--------------- 3 files changed, 47 insertions(+), 37 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index b511466acd6..abe40fd96d0 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -184,8 +184,7 @@ impl *const T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -210,6 +209,7 @@ impl *const T { /// enables more aggressive compiler optimizations. /// /// [`wrapping_offset`]: #method.wrapping_offset + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -245,9 +245,8 @@ impl *const T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same allocated object that `self` points to. - /// It may *not* be used to access a different allocated object. Note that in Rust, every - /// (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same [allocated object] that `self` points to. + /// It may *not* be used to access a different allocated object. /// /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -269,6 +268,7 @@ impl *const T { /// do the arithmetic there. /// /// [`offset`]: #method.offset + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -314,8 +314,7 @@ impl *const T { /// Behavior: /// /// * Both the starting and other pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * Both pointers must be *derived from* a pointer to the same object. /// (See below for an example.) @@ -345,6 +344,7 @@ impl *const T { /// such large allocations either.) /// /// [`add`]: #method.add + /// [allocated object]: crate::ptr#allocated-object /// /// # Panics /// @@ -468,8 +468,7 @@ impl *const T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -494,6 +493,7 @@ impl *const T { /// enables more aggressive compiler optimizations. /// /// [`wrapping_add`]: #method.wrapping_add + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -532,8 +532,7 @@ impl *const T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * The computed offset cannot exceed `isize::MAX` **bytes**. /// @@ -558,6 +557,7 @@ impl *const T { /// enables more aggressive compiler optimizations. /// /// [`wrapping_sub`]: #method.wrapping_sub + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -594,9 +594,8 @@ impl *const T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same allocated object that `self` points to. - /// It may *not* be used to access a different allocated object. Note that in Rust, every - /// (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same [allocated object] that `self` points to. + /// It may *not* be used to access a different allocated object. /// /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -618,6 +617,7 @@ impl *const T { /// do the arithmetic there. /// /// [`add`]: #method.add + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -659,9 +659,8 @@ impl *const T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same allocated object that `self` points to. - /// It may *not* be used to access a different allocated object. Note that in Rust, every - /// (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same [allocated object] that `self` points to. + /// It may *not* be used to access a different allocated object. /// /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -683,6 +682,7 @@ impl *const T { /// do the arithmetic there. /// /// [`sub`]: #method.sub + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -997,7 +997,7 @@ impl *const [T] { /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// - /// * The entire memory range of this slice must be contained within a single allocated object! + /// * The entire memory range of this slice must be contained within a single [allocated object]! /// Slices can never span across multiple allocated objects. /// /// * The pointer must be aligned even for zero-length slices. One @@ -1019,6 +1019,7 @@ impl *const [T] { /// See also [`slice::from_raw_parts`][]. /// /// [valid]: crate::ptr#safety + /// [allocated object]: crate::ptr#allocated-object #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] pub unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit]> { diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 7e4f8d570a7..d2f90c7fc8c 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -55,6 +55,14 @@ //! has size 0, i.e., even if memory is not actually touched. Consider using //! [`NonNull::dangling`] in such cases. //! +//! ## Allocated object +//! +//! For several operations, such as [`offset`] or field projections (`expr.field`), the notion of an +//! "allocated object" becomes relevant. An allocated object is a contiguous region of memory. +//! Common examples of allocated objects include stack-allocated variables (each variable is a +//! separate allocated object), heap allocations (each allocation created by the global allocator is +//! a separate allocated object), and `static` variables. +//! //! [aliasing]: ../../nomicon/aliasing.html //! [book]: ../../book/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer //! [ub]: ../../reference/behavior-considered-undefined.html diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index fa09cf85435..51ddc7da8a4 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -189,8 +189,7 @@ impl *mut T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -215,6 +214,7 @@ impl *mut T { /// enables more aggressive compiler optimizations. /// /// [`wrapping_offset`]: #method.wrapping_offset + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -251,9 +251,8 @@ impl *mut T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same allocated object that `self` points to. - /// It may *not* be used to access a different allocated object. Note that in Rust, every - /// (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same [allocated object] that `self` points to. + /// It may *not* be used to access a different allocated object. /// /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -275,6 +274,7 @@ impl *mut T { /// do the arithmetic there. /// /// [`offset`]: #method.offset + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -485,8 +485,7 @@ impl *mut T { /// Behavior: /// /// * Both the starting and other pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * Both pointers must be *derived from* a pointer to the same object. /// (See below for an example.) @@ -516,6 +515,7 @@ impl *mut T { /// such large allocations either.) /// /// [`add`]: #method.add + /// [allocated object]: crate::ptr#allocated-object /// /// # Panics /// @@ -575,8 +575,7 @@ impl *mut T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -639,8 +638,7 @@ impl *mut T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * The computed offset cannot exceed `isize::MAX` **bytes**. /// @@ -665,6 +663,7 @@ impl *mut T { /// enables more aggressive compiler optimizations. /// /// [`wrapping_sub`]: #method.wrapping_sub + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -701,9 +700,8 @@ impl *mut T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same allocated object that `self` points to. - /// It may *not* be used to access a different allocated object. Note that in Rust, every - /// (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same [allocated object] that `self` points to. + /// It may *not* be used to access a different allocated object. /// /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -725,6 +723,7 @@ impl *mut T { /// do the arithmetic there. /// /// [`add`]: #method.add + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -766,9 +765,8 @@ impl *mut T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same allocated object that `self` points to. - /// It may *not* be used to access a different allocated object. Note that in Rust, every - /// (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same [allocated object] that `self` points to. + /// It may *not* be used to access a different allocated object. /// /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -790,6 +788,7 @@ impl *mut T { /// do the arithmetic there. /// /// [`sub`]: #method.sub + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -1261,7 +1260,7 @@ impl *mut [T] { /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// - /// * The entire memory range of this slice must be contained within a single allocated object! + /// * The entire memory range of this slice must be contained within a single [allocated object]! /// Slices can never span across multiple allocated objects. /// /// * The pointer must be aligned even for zero-length slices. One @@ -1283,6 +1282,7 @@ impl *mut [T] { /// See also [`slice::from_raw_parts`][]. /// /// [valid]: crate::ptr#safety + /// [allocated object]: crate::ptr#allocated-object #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] pub unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit]> { @@ -1311,7 +1311,7 @@ impl *mut [T] { /// * The pointer must be [valid] for reads and writes for `ptr.len() * mem::size_of::()` /// many bytes, and it must be properly aligned. This means in particular: /// - /// * The entire memory range of this slice must be contained within a single allocated object! + /// * The entire memory range of this slice must be contained within a single [allocated object]! /// Slices can never span across multiple allocated objects. /// /// * The pointer must be aligned even for zero-length slices. One @@ -1333,6 +1333,7 @@ impl *mut [T] { /// See also [`slice::from_raw_parts_mut`][]. /// /// [valid]: crate::ptr#safety + /// [allocated object]: crate::ptr#allocated-object #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] pub unsafe fn as_uninit_slice_mut<'a>(self) -> Option<&'a mut [MaybeUninit]> { From 4f03f94863dda70ea42ce772b790a520f1490647 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 27 Mar 2021 19:31:43 +0100 Subject: [PATCH 153/370] clarify 'remains attached', and remove recommendation to use integer arithmetic --- library/core/src/ptr/const_ptr.rs | 21 ++++++--------------- library/core/src/ptr/mut_ptr.rs | 21 ++++++--------------- 2 files changed, 12 insertions(+), 30 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index abe40fd96d0..25b8f435acc 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -245,8 +245,8 @@ impl *const T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same [allocated object] that `self` points to. - /// It may *not* be used to access a different allocated object. + /// The resulting pointer "remembers" the [allocated object] that `self` points to; it may not + /// be used to read or write other allocated objects. /// /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -264,9 +264,6 @@ impl *const T { /// `x.wrapping_offset(o).wrapping_offset(o.wrapping_neg())` is always the same as `x`. In other /// words, leaving the allocated object and then re-entering it later is permitted. /// - /// If you need to cross object boundaries, cast the pointer to an integer and - /// do the arithmetic there. - /// /// [`offset`]: #method.offset /// [allocated object]: crate::ptr#allocated-object /// @@ -594,8 +591,8 @@ impl *const T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same [allocated object] that `self` points to. - /// It may *not* be used to access a different allocated object. + /// The resulting pointer "remembers" the [allocated object] that `self` points to; it may not + /// be used to read or write other allocated objects. /// /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -613,9 +610,6 @@ impl *const T { /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the /// allocated object and then re-entering it later is permitted. /// - /// If you need to cross object boundaries, cast the pointer to an integer and - /// do the arithmetic there. - /// /// [`add`]: #method.add /// [allocated object]: crate::ptr#allocated-object /// @@ -659,8 +653,8 @@ impl *const T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same [allocated object] that `self` points to. - /// It may *not* be used to access a different allocated object. + /// The resulting pointer "remembers" the [allocated object] that `self` points to; it may not + /// be used to read or write other allocated objects. /// /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -678,9 +672,6 @@ impl *const T { /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the /// allocated object and then re-entering it later is permitted. /// - /// If you need to cross object boundaries, cast the pointer to an integer and - /// do the arithmetic there. - /// /// [`sub`]: #method.sub /// [allocated object]: crate::ptr#allocated-object /// diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 51ddc7da8a4..732e1273b4b 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -251,8 +251,8 @@ impl *mut T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same [allocated object] that `self` points to. - /// It may *not* be used to access a different allocated object. + /// The resulting pointer "remembers" the [allocated object] that `self` points to; it may not + /// be used to read or write other allocated objects. /// /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -270,9 +270,6 @@ impl *mut T { /// `x.wrapping_offset(o).wrapping_offset(o.wrapping_neg())` is always the same as `x`. In other /// words, leaving the allocated object and then re-entering it later is permitted. /// - /// If you need to cross object boundaries, cast the pointer to an integer and - /// do the arithmetic there. - /// /// [`offset`]: #method.offset /// [allocated object]: crate::ptr#allocated-object /// @@ -700,8 +697,8 @@ impl *mut T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same [allocated object] that `self` points to. - /// It may *not* be used to access a different allocated object. + /// The resulting pointer "remembers" the [allocated object] that `self` points to; it may not + /// be used to read or write other allocated objects. /// /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -719,9 +716,6 @@ impl *mut T { /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the /// allocated object and then re-entering it later is permitted. /// - /// If you need to cross object boundaries, cast the pointer to an integer and - /// do the arithmetic there. - /// /// [`add`]: #method.add /// [allocated object]: crate::ptr#allocated-object /// @@ -765,8 +759,8 @@ impl *mut T { /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same [allocated object] that `self` points to. - /// It may *not* be used to access a different allocated object. + /// The resulting pointer "remembers" the [allocated object] that `self` points to; it may not + /// be used to read or write other allocated objects. /// /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -784,9 +778,6 @@ impl *mut T { /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the /// allocated object and then re-entering it later is permitted. /// - /// If you need to cross object boundaries, cast the pointer to an integer and - /// do the arithmetic there. - /// /// [`sub`]: #method.sub /// [allocated object]: crate::ptr#allocated-object /// From 0a30c5b2ab8bc367803f32933522d39df8b58c9b Mon Sep 17 00:00:00 2001 From: Violet Date: Sat, 27 Mar 2021 14:38:43 -0400 Subject: [PATCH 154/370] revert rustdoc links in core to use #method. because they link to alloc, which may not be available --- library/core/src/slice/ascii.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 4249ac77d47..42032bc9035 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -30,7 +30,7 @@ impl [u8] { /// To return a new uppercased value without modifying the existing one, use /// [`to_ascii_uppercase`]. /// - /// [`to_ascii_uppercase`]: slice::to_ascii_uppercase + /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn make_ascii_uppercase(&mut self) { @@ -47,7 +47,7 @@ impl [u8] { /// To return a new lowercased value without modifying the existing one, use /// [`to_ascii_lowercase`]. /// - /// [`to_ascii_lowercase`]: slice::to_ascii_lowercase + /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn make_ascii_lowercase(&mut self) { From e051db6838496baf97fc34e63c36c73a6ea1c7f7 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 27 Mar 2021 15:56:07 -0400 Subject: [PATCH 155/370] may not -> might not "may not" has two possible meanings: 1. A command: "You may not stay up past your bedtime." 2. A fact that's only sometimes true: "Some cities may not have bike lanes." In some cases, the meaning is ambiguous: "Some cars may not have snow tires." (do the cars *happen* to not have snow tires, or is it physically impossible for them to have snow tires?) This changes places where the standard library uses the "description of fact" meaning to say "might not" instead. This is just `std::vec` for now - if you think this is a good idea I can convert the rest of the standard library. --- library/alloc/src/vec/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 135279874bb..b7b01deb4fc 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -267,12 +267,12 @@ mod spec_extend; /// unspecified, and you should use the appropriate methods to modify these. /// The pointer will never be null, so this type is null-pointer-optimized. /// -/// However, the pointer may not actually point to allocated memory. In particular, +/// However, the pointer might not actually point to allocated memory. In particular, /// if you construct a `Vec` with capacity 0 via [`Vec::new`], [`vec![]`][`vec!`], /// [`Vec::with_capacity(0)`][`Vec::with_capacity`], or by calling [`shrink_to_fit`] /// on an empty Vec, it will not allocate memory. Similarly, if you store zero-sized /// types inside a `Vec`, it will not allocate space for them. *Note that in this case -/// the `Vec` may not report a [`capacity`] of 0*. `Vec` will allocate if and only +/// the `Vec` might not report a [`capacity`] of 0*. `Vec` will allocate if and only /// if [`mem::size_of::`]`() * capacity() > 0`. In general, `Vec`'s allocation /// details are very subtle — if you intend to allocate memory using a `Vec` /// and use it for something else (either to pass to unsafe code, or to build your @@ -347,7 +347,7 @@ mod spec_extend; /// whatever is most efficient or otherwise easy to implement. Do not rely on /// removed data to be erased for security purposes. Even if you drop a `Vec`, its /// buffer may simply be reused by another `Vec`. Even if you zero a `Vec`'s memory -/// first, that may not actually happen because the optimizer does not consider +/// first, that might not actually happen because the optimizer does not consider /// this a side-effect that must be preserved. There is one case which we will /// not break, however: using `unsafe` code to write to the excess capacity, /// and then increasing the length to match, is always valid. From ee0357af3b57379153e023bbc91975e26301e40c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 13 Mar 2021 22:23:18 +0300 Subject: [PATCH 156/370] resolve: Partially unify early and late scope-relative ident resolution --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- compiler/rustc_resolve/src/diagnostics.rs | 4 +- compiler/rustc_resolve/src/lib.rs | 196 +++++++-------------- compiler/rustc_resolve/src/macros.rs | 27 ++- src/test/ui/proc-macro/generate-mod.stderr | 12 +- 5 files changed, 97 insertions(+), 144 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index cd4d01ddc05..e931e9dfcb2 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1977,7 +1977,7 @@ declare_lint! { Warn, "detects proc macro derives using inaccessible names from parent modules", @future_incompatible = FutureIncompatibleInfo { - reference: "issue #50504 ", + reference: "issue #83583 ", edition: None, }; } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index d402fa4f849..327beca218e 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -606,7 +606,7 @@ impl<'a> Resolver<'a> { /// Lookup typo candidate in scope for a macro or import. fn early_lookup_typo_candidate( &mut self, - scope_set: ScopeSet, + scope_set: ScopeSet<'a>, parent_scope: &ParentScope<'a>, ident: Ident, filter_fn: &impl Fn(Res) -> bool, @@ -662,7 +662,7 @@ impl<'a> Resolver<'a> { let root_module = this.resolve_crate_root(root_ident); this.add_module_candidates(root_module, &mut suggestions, filter_fn); } - Scope::Module(module) => { + Scope::Module(module, _) => { this.add_module_candidates(module, &mut suggestions, filter_fn); } Scope::RegisteredAttrs => { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 14e3d8498b0..0febd71a52a 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -25,7 +25,6 @@ use Determinacy::*; use rustc_arena::{DroplessArena, TypedArena}; use rustc_ast::node_id::NodeMap; use rustc_ast::ptr::P; -use rustc_ast::unwrap_or; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{self as ast, NodeId}; use rustc_ast::{Crate, CRATE_NODE_ID}; @@ -42,7 +41,7 @@ use rustc_hir::def::Namespace::*; use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX}; use rustc_hir::definitions::{DefKey, DefPathData, Definitions}; -use rustc_hir::{PrimTy, TraitCandidate}; +use rustc_hir::TraitCandidate; use rustc_index::vec::IndexVec; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::hir::exports::ExportMap; @@ -108,7 +107,9 @@ enum Scope<'a> { DeriveHelpersCompat, MacroRules(MacroRulesScopeRef<'a>), CrateRoot, - Module(Module<'a>), + // The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK` + // lint if it should be reported. + Module(Module<'a>, Option), RegisteredAttrs, MacroUsePrelude, BuiltinAttrs, @@ -122,13 +123,17 @@ enum Scope<'a> { /// with different restrictions when looking up the resolution. /// This enum is currently used only for early resolution (imports and macros), /// but not for late resolution yet. -enum ScopeSet { +#[derive(Clone, Copy)] +enum ScopeSet<'a> { /// All scopes with the given namespace. All(Namespace, /*is_import*/ bool), /// Crate root, then extern prelude (used for mixed 2015-2018 mode in macros). AbsolutePath(Namespace), /// All scopes with macro namespace and the given macro kind restriction. Macro(MacroKind), + /// All scopes with the given namespace, used for partially performing late resolution. + /// The node id enables lints and is used for reporting them. + Late(Namespace, Module<'a>, Option), } /// Everything you need to know about a name's location to resolve it. @@ -1466,7 +1471,7 @@ impl<'a> Resolver<'a> { self.visit_scopes(ScopeSet::All(TypeNS, false), parent_scope, ctxt, |this, scope, _, _| { match scope { - Scope::Module(module) => { + Scope::Module(module, _) => { this.traits_in_module(module, assoc_item, &mut found_traits); } Scope::StdLibPrelude => { @@ -1630,7 +1635,7 @@ impl<'a> Resolver<'a> { /// If the callback returns `Some` result, we stop visiting scopes and return it. fn visit_scopes( &mut self, - scope_set: ScopeSet, + scope_set: ScopeSet<'a>, parent_scope: &ParentScope<'a>, ctxt: SyntaxContext, mut visitor: impl FnMut( @@ -1686,12 +1691,17 @@ impl<'a> Resolver<'a> { ScopeSet::All(ns, _) => (ns, None, false), ScopeSet::AbsolutePath(ns) => (ns, None, true), ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false), + ScopeSet::Late(ns, ..) => (ns, None, false), + }; + let module = match scope_set { + // Start with the specified module. + ScopeSet::Late(_, module, _) => module, + // Jump out of trait or enum modules, they do not act as scopes. + _ => parent_scope.module.nearest_item_scope(), }; - // Jump out of trait or enum modules, they do not act as scopes. - let module = parent_scope.module.nearest_item_scope(); let mut scope = match ns { _ if is_absolute_path => Scope::CrateRoot, - TypeNS | ValueNS => Scope::Module(module), + TypeNS | ValueNS => Scope::Module(module, None), MacroNS => Scope::DeriveHelpers(parent_scope.expansion), }; let mut ctxt = ctxt.normalize_to_macros_2_0(); @@ -1756,7 +1766,7 @@ impl<'a> Resolver<'a> { MacroRulesScope::Invocation(invoc_id) => { Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules) } - MacroRulesScope::Empty => Scope::Module(module), + MacroRulesScope::Empty => Scope::Module(module, None), }, Scope::CrateRoot => match ns { TypeNS => { @@ -1765,10 +1775,16 @@ impl<'a> Resolver<'a> { } ValueNS | MacroNS => break, }, - Scope::Module(module) => { + Scope::Module(module, prev_lint_id) => { use_prelude = !module.no_implicit_prelude; - match self.hygienic_lexical_parent(module, &mut ctxt) { - Some(parent_module) => Scope::Module(parent_module), + let derive_fallback_lint_id = match scope_set { + ScopeSet::Late(.., lint_id) => lint_id, + _ => None, + }; + match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) { + Some((parent_module, lint_id)) => { + Scope::Module(parent_module, lint_id.or(prev_lint_id)) + } None => { ctxt.adjust(ExpnId::root()); match ns { @@ -1824,6 +1840,7 @@ impl<'a> Resolver<'a> { ribs: &[Rib<'a>], ) -> Option> { assert!(ns == TypeNS || ns == ValueNS); + let orig_ident = ident; if ident.name == kw::Empty { return Some(LexicalScopeBinding::Res(Res::Err)); } @@ -1873,6 +1890,11 @@ impl<'a> Resolver<'a> { _ => continue, }; + match module.kind { + ModuleKind::Block(..) => {} // We can see through blocks + _ => break, + } + let item = self.resolve_ident_in_module_unadjusted( ModuleOrUniformRoot::Module(module), ident, @@ -1885,123 +1907,32 @@ impl<'a> Resolver<'a> { // The ident resolves to an item. return Some(LexicalScopeBinding::Item(binding)); } - - match module.kind { - ModuleKind::Block(..) => {} // We can see through blocks - _ => break, - } } - ident = normalized_ident; - let mut poisoned = None; - loop { - let mut span_data = ident.span.data(); - let opt_module = if let Some(node_id) = record_used_id { - self.hygienic_lexical_parent_with_compatibility_fallback( - module, - &mut span_data.ctxt, - node_id, - &mut poisoned, - ) - } else { - self.hygienic_lexical_parent(module, &mut span_data.ctxt) - }; - ident.span = span_data.span(); - module = unwrap_or!(opt_module, break); - let adjusted_parent_scope = &ParentScope { module, ..*parent_scope }; - let result = self.resolve_ident_in_module_unadjusted( - ModuleOrUniformRoot::Module(module), - ident, - ns, - adjusted_parent_scope, - record_used, - path_span, - ); - - match result { - Ok(binding) => { - if let Some(node_id) = poisoned { - self.lint_buffer.buffer_lint_with_diagnostic( - lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, - node_id, - ident.span, - &format!("cannot find {} `{}` in this scope", ns.descr(), ident), - BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(ident.span), - ); - } - return Some(LexicalScopeBinding::Item(binding)); - } - Err(Determined) => continue, - Err(Undetermined) => { - span_bug!(ident.span, "undetermined resolution during main resolution pass") - } - } - } - - if !module.no_implicit_prelude { - ident.span.adjust(ExpnId::root()); - if ns == TypeNS { - if let Some(binding) = self.extern_prelude_get(ident, !record_used) { - return Some(LexicalScopeBinding::Item(binding)); - } - if let Some(ident) = self.registered_tools.get(&ident) { - let binding = - (Res::ToolMod, ty::Visibility::Public, ident.span, ExpnId::root()) - .to_name_binding(self.arenas); - return Some(LexicalScopeBinding::Item(binding)); - } - } - if let Some(prelude) = self.prelude { - if let Ok(binding) = self.resolve_ident_in_module_unadjusted( - ModuleOrUniformRoot::Module(prelude), - ident, - ns, - parent_scope, - false, - path_span, - ) { - return Some(LexicalScopeBinding::Item(binding)); - } - } - } - - if ns == TypeNS { - if let Some(prim_ty) = PrimTy::from_name(ident.name) { - let binding = - (Res::PrimTy(prim_ty), ty::Visibility::Public, DUMMY_SP, ExpnId::root()) - .to_name_binding(self.arenas); - return Some(LexicalScopeBinding::Item(binding)); - } - } - - None + self.early_resolve_ident_in_lexical_scope( + orig_ident, + ScopeSet::Late(ns, module, record_used_id), + parent_scope, + record_used, + record_used, + path_span, + ) + .ok() + .map(LexicalScopeBinding::Item) } fn hygienic_lexical_parent( &mut self, module: Module<'a>, ctxt: &mut SyntaxContext, - ) -> Option> { + derive_fallback_lint_id: Option, + ) -> Option<(Module<'a>, Option)> { if !module.expansion.outer_expn_is_descendant_of(*ctxt) { - return Some(self.macro_def_scope(ctxt.remove_mark())); + return Some((self.macro_def_scope(ctxt.remove_mark()), None)); } if let ModuleKind::Block(..) = module.kind { - return Some(module.parent.unwrap().nearest_item_scope()); - } - - None - } - - fn hygienic_lexical_parent_with_compatibility_fallback( - &mut self, - module: Module<'a>, - ctxt: &mut SyntaxContext, - node_id: NodeId, - poisoned: &mut Option, - ) -> Option> { - if let module @ Some(..) = self.hygienic_lexical_parent(module, ctxt) { - return module; + return Some((module.parent.unwrap().nearest_item_scope(), None)); } // We need to support the next case under a deprecation warning @@ -2015,20 +1946,21 @@ impl<'a> Resolver<'a> { // ---- end // ``` // So we have to fall back to the module's parent during lexical resolution in this case. - if let Some(parent) = module.parent { - // Inner module is inside the macro, parent module is outside of the macro. - if module.expansion != parent.expansion - && module.expansion.is_descendant_of(parent.expansion) - { - // The macro is a proc macro derive - if let Some(def_id) = module.expansion.expn_data().macro_def_id { - let ext = self.get_macro_by_def_id(def_id); - if ext.builtin_name.is_none() - && ext.macro_kind() == MacroKind::Derive - && parent.expansion.outer_expn_is_descendant_of(*ctxt) - { - *poisoned = Some(node_id); - return module.parent; + if derive_fallback_lint_id.is_some() { + if let Some(parent) = module.parent { + // Inner module is inside the macro, parent module is outside of the macro. + if module.expansion != parent.expansion + && module.expansion.is_descendant_of(parent.expansion) + { + // The macro is a proc macro derive + if let Some(def_id) = module.expansion.expn_data().macro_def_id { + let ext = self.get_macro_by_def_id(def_id); + if ext.builtin_name.is_none() + && ext.macro_kind() == MacroKind::Derive + && parent.expansion.outer_expn_is_descendant_of(*ctxt) + { + return Some((parent, derive_fallback_lint_id)); + } } } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 2efce1e1984..d238f65c941 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -24,7 +24,8 @@ use rustc_hir::def_id; use rustc_hir::PrimTy; use rustc_middle::middle::stability; use rustc_middle::ty; -use rustc_session::lint::builtin::{LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE, UNUSED_MACROS}; +use rustc_session::lint::builtin::{LEGACY_DERIVE_HELPERS, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK}; +use rustc_session::lint::builtin::{SOFT_UNSTABLE, UNUSED_MACROS}; use rustc_session::lint::BuiltinLintDiagnostics; use rustc_session::parse::feature_err; use rustc_session::Session; @@ -642,7 +643,7 @@ impl<'a> Resolver<'a> { crate fn early_resolve_ident_in_lexical_scope( &mut self, orig_ident: Ident, - scope_set: ScopeSet, + scope_set: ScopeSet<'a>, parent_scope: &ParentScope<'a>, record_used: bool, force: bool, @@ -669,6 +670,7 @@ impl<'a> Resolver<'a> { ScopeSet::All(ns, is_import) => (ns, None, is_import), ScopeSet::AbsolutePath(ns) => (ns, None, false), ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false), + ScopeSet::Late(ns, ..) => (ns, None, false), }; // This is *the* result, resolution from the scope closest to the resolved identifier. @@ -777,19 +779,34 @@ impl<'a> Resolver<'a> { Err((Determinacy::Determined, _)) => Err(Determinacy::Determined), } } - Scope::Module(module) => { + Scope::Module(module, derive_fallback_lint_id) => { let adjusted_parent_scope = &ParentScope { module, ..*parent_scope }; let binding = this.resolve_ident_in_module_unadjusted_ext( ModuleOrUniformRoot::Module(module), ident, ns, adjusted_parent_scope, - true, + !matches!(scope_set, ScopeSet::Late(..)), record_used, path_span, ); match binding { Ok(binding) => { + if let Some(lint_id) = derive_fallback_lint_id { + this.lint_buffer.buffer_lint_with_diagnostic( + PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, + lint_id, + orig_ident.span, + &format!( + "cannot find {} `{}` in this scope", + ns.descr(), + ident + ), + BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback( + orig_ident.span, + ), + ); + } let misc_flags = if ptr::eq(module, this.graph_root) { Flags::MISC_SUGGEST_CRATE } else if module.is_normal() { @@ -873,7 +890,7 @@ impl<'a> Resolver<'a> { Ok((binding, flags)) if sub_namespace_match(binding.macro_kind(), macro_kind) => { - if !record_used { + if !record_used || matches!(scope_set, ScopeSet::Late(..)) { return Some(Ok(binding)); } diff --git a/src/test/ui/proc-macro/generate-mod.stderr b/src/test/ui/proc-macro/generate-mod.stderr index 9b946b5e244..5a4ed65ecdc 100644 --- a/src/test/ui/proc-macro/generate-mod.stderr +++ b/src/test/ui/proc-macro/generate-mod.stderr @@ -46,7 +46,8 @@ LL | #[derive(generate_mod::CheckDerive)] | = note: `#[warn(proc_macro_derive_resolution_fallback)]` on by default = 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 #50504 + = note: for more information, see issue #83583 + = note: this warning originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: cannot find type `OuterDerive` in this scope --> $DIR/generate-mod.rs:16:10 @@ -55,7 +56,8 @@ LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | = 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 #50504 + = note: for more information, see issue #83583 + = note: this warning originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:23:14 @@ -64,7 +66,8 @@ LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | = 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 #50504 + = note: for more information, see issue #83583 + = note: this warning originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) warning: cannot find type `OuterDerive` in this scope --> $DIR/generate-mod.rs:23:14 @@ -73,7 +76,8 @@ LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | = 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 #50504 + = note: for more information, see issue #83583 + = note: this warning originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors; 4 warnings emitted From 6615ee89be2290c96aa7d4ab24dc94e23a8c7080 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 28 Mar 2021 00:02:23 +0300 Subject: [PATCH 157/370] linker: Use `--as-needed` by default when linker supports it --- compiler/rustc_codegen_ssa/src/back/link.rs | 6 ++++++ compiler/rustc_codegen_ssa/src/back/linker.rs | 7 +++++++ .../rustc_target/src/spec/avr_gnu_base.rs | 19 +++---------------- .../rustc_target/src/spec/dragonfly_base.rs | 5 ----- .../rustc_target/src/spec/freebsd_base.rs | 5 ----- .../src/spec/i686_unknown_netbsd.rs | 2 +- .../rustc_target/src/spec/i686_wrs_vxworks.rs | 2 +- compiler/rustc_target/src/spec/linux_base.rs | 8 -------- .../src/spec/linux_kernel_base.rs | 5 +---- compiler/rustc_target/src/spec/netbsd_base.rs | 15 +-------------- .../rustc_target/src/spec/openbsd_base.rs | 5 ----- .../src/spec/powerpc64_wrs_vxworks.rs | 2 +- .../src/spec/powerpc_unknown_netbsd.rs | 2 +- .../src/spec/powerpc_wrs_vxworks.rs | 4 ++-- .../src/spec/powerpc_wrs_vxworks_spe.rs | 4 ++-- compiler/rustc_target/src/spec/redox_base.rs | 8 -------- .../src/spec/sparc64_unknown_netbsd.rs | 2 +- .../rustc_target/src/spec/vxworks_base.rs | 18 +----------------- .../src/spec/x86_64_fortanix_unknown_sgx.rs | 1 - .../src/spec/x86_64_unknown_netbsd.rs | 2 +- .../src/spec/x86_64_wrs_vxworks.rs | 2 +- 21 files changed, 30 insertions(+), 94 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 4d6bc838130..e7938fe8af9 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1651,6 +1651,12 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( cmd.add_eh_frame_header(); } + // NO-OPT-OUT, OBJECT-FILES-NO + // Avoid linking to dynamic libraries unless they satisfy some undefined symbols + // at the point at which they are specified on the command line. + // Must be passed before any dynamic libraries. + cmd.add_as_needed(); + // NO-OPT-OUT, OBJECT-FILES-NO if crt_objects_fallback { cmd.no_crt_objects(); diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index bb35e7ec894..592675d916a 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -130,6 +130,7 @@ pub trait Linker { fn group_end(&mut self); fn linker_plugin_lto(&mut self); fn add_eh_frame_header(&mut self) {} + fn add_as_needed(&mut self) {} fn finalize(&mut self); } @@ -641,6 +642,12 @@ impl<'a> Linker for GccLinker<'a> { fn add_eh_frame_header(&mut self) { self.linker_arg("--eh-frame-hdr"); } + + fn add_as_needed(&mut self) { + if self.sess.target.linker_is_gnu { + self.linker_arg("--as-needed"); + } + } } pub struct MsvcLinker<'a> { diff --git a/compiler/rustc_target/src/spec/avr_gnu_base.rs b/compiler/rustc_target/src/spec/avr_gnu_base.rs index 67a7684da2c..df4389b8165 100644 --- a/compiler/rustc_target/src/spec/avr_gnu_base.rs +++ b/compiler/rustc_target/src/spec/avr_gnu_base.rs @@ -21,22 +21,9 @@ pub fn target(target_cpu: String) -> Target { has_rpath: false, position_independent_executables: false, eh_frame_header: false, - pre_link_args: vec![( - LinkerFlavor::Gcc, - vec![ - format!("-mmcu={}", target_cpu), - // We want to be able to strip as much executable code as possible - // from the linker command line, and this flag indicates to the - // linker that it can avoid linking in dynamic libraries that don't - // actually satisfy any symbols up to that point (as with many other - // resolutions the linker does). This option only applies to all - // following libraries so we're sure to pass it as one of the first - // arguments. - "-Wl,--as-needed".to_string(), - ], - )] - .into_iter() - .collect(), + pre_link_args: vec![(LinkerFlavor::Gcc, vec![format!("-mmcu={}", target_cpu)])] + .into_iter() + .collect(), late_link_args: vec![(LinkerFlavor::Gcc, vec!["-lgcc".to_owned()])] .into_iter() .collect(), diff --git a/compiler/rustc_target/src/spec/dragonfly_base.rs b/compiler/rustc_target/src/spec/dragonfly_base.rs index b96de7ab1ed..41d372cc6db 100644 --- a/compiler/rustc_target/src/spec/dragonfly_base.rs +++ b/compiler/rustc_target/src/spec/dragonfly_base.rs @@ -5,11 +5,6 @@ pub fn opts() -> TargetOptions { args.insert( LinkerFlavor::Gcc, vec![ - // GNU-style linkers will use this to omit linking to libraries - // which don't actually fulfill any relocations, but only for - // libraries which follow this flag. Thus, use it before - // specifying libraries to link to. - "-Wl,--as-needed".to_string(), // Always enable NX protection when it is available "-Wl,-z,noexecstack".to_string(), ], diff --git a/compiler/rustc_target/src/spec/freebsd_base.rs b/compiler/rustc_target/src/spec/freebsd_base.rs index c70c492716b..86db2bf8eed 100644 --- a/compiler/rustc_target/src/spec/freebsd_base.rs +++ b/compiler/rustc_target/src/spec/freebsd_base.rs @@ -5,11 +5,6 @@ pub fn opts() -> TargetOptions { args.insert( LinkerFlavor::Gcc, vec![ - // GNU-style linkers will use this to omit linking to libraries - // which don't actually fulfill any relocations, but only for - // libraries which follow this flag. Thus, use it before - // specifying libraries to link to. - "-Wl,--as-needed".to_string(), // Always enable NX protection when it is available "-Wl,-z,noexecstack".to_string(), ], diff --git a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs index c4d11bfb13e..e020264ad7a 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs index ec8a2493b4e..e596eca86b0 100644 --- a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/linux_base.rs b/compiler/rustc_target/src/spec/linux_base.rs index 0631644ad63..aa2ff7bb399 100644 --- a/compiler/rustc_target/src/spec/linux_base.rs +++ b/compiler/rustc_target/src/spec/linux_base.rs @@ -5,14 +5,6 @@ pub fn opts() -> TargetOptions { args.insert( LinkerFlavor::Gcc, vec![ - // We want to be able to strip as much executable code as possible - // from the linker command line, and this flag indicates to the - // linker that it can avoid linking in dynamic libraries that don't - // actually satisfy any symbols up to that point (as with many other - // resolutions the linker does). This option only applies to all - // following libraries so we're sure to pass it as one of the first - // arguments. - "-Wl,--as-needed".to_string(), // Always enable NX protection when it is available "-Wl,-z,noexecstack".to_string(), ], diff --git a/compiler/rustc_target/src/spec/linux_kernel_base.rs b/compiler/rustc_target/src/spec/linux_kernel_base.rs index 52201568953..e71c80e556e 100644 --- a/compiler/rustc_target/src/spec/linux_kernel_base.rs +++ b/compiler/rustc_target/src/spec/linux_kernel_base.rs @@ -4,10 +4,7 @@ use crate::spec::{ pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); - pre_link_args.insert( - LinkerFlavor::Gcc, - vec!["-Wl,--as-needed".to_string(), "-Wl,-z,noexecstack".to_string()], - ); + pre_link_args.insert(LinkerFlavor::Gcc, vec!["-Wl,-z,noexecstack".to_string()]); TargetOptions { env: "gnu".to_string(), diff --git a/compiler/rustc_target/src/spec/netbsd_base.rs b/compiler/rustc_target/src/spec/netbsd_base.rs index a77d60bd9d7..680cd60788b 100644 --- a/compiler/rustc_target/src/spec/netbsd_base.rs +++ b/compiler/rustc_target/src/spec/netbsd_base.rs @@ -1,18 +1,6 @@ -use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; +use crate::spec::{RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { - let mut args = LinkArgs::new(); - args.insert( - LinkerFlavor::Gcc, - vec![ - // GNU-style linkers will use this to omit linking to libraries - // which don't actually fulfill any relocations, but only for - // libraries which follow this flag. Thus, use it before - // specifying libraries to link to. - "-Wl,--as-needed".to_string(), - ], - ); - TargetOptions { os: "netbsd".to_string(), dynamic_linking: true, @@ -21,7 +9,6 @@ pub fn opts() -> TargetOptions { linker_is_gnu: true, no_default_libraries: false, has_rpath: true, - pre_link_args: args, position_independent_executables: true, relro_level: RelroLevel::Full, use_ctors_section: true, diff --git a/compiler/rustc_target/src/spec/openbsd_base.rs b/compiler/rustc_target/src/spec/openbsd_base.rs index 2b40a1ed945..0aeefba3647 100644 --- a/compiler/rustc_target/src/spec/openbsd_base.rs +++ b/compiler/rustc_target/src/spec/openbsd_base.rs @@ -5,11 +5,6 @@ pub fn opts() -> TargetOptions { args.insert( LinkerFlavor::Gcc, vec![ - // GNU-style linkers will use this to omit linking to libraries - // which don't actually fulfill any relocations, but only for - // libraries which follow this flag. Thus, use it before - // specifying libraries to link to. - "-Wl,--as-needed".to_string(), // Always enable NX protection when it is available "-Wl,-z,noexecstack".to_string(), ], diff --git a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs index 2f28a856247..3ebc5469e0a 100644 --- a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs @@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "ppc64".to_string(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs index 1245098329a..4cc5224fae3 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs @@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs index bb943a8825c..2f0a6ca44a0 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs @@ -3,8 +3,8 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("--secure-plt".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("--secure-plt".to_string()); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs index 4b4f118ba49..215f1a36227 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs @@ -3,8 +3,8 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mspe".to_string()); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("--secure-plt".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mspe".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("--secure-plt".to_string()); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/redox_base.rs b/compiler/rustc_target/src/spec/redox_base.rs index 5ef705878a8..20c91708faa 100644 --- a/compiler/rustc_target/src/spec/redox_base.rs +++ b/compiler/rustc_target/src/spec/redox_base.rs @@ -5,14 +5,6 @@ pub fn opts() -> TargetOptions { args.insert( LinkerFlavor::Gcc, vec![ - // We want to be able to strip as much executable code as possible - // from the linker command line, and this flag indicates to the - // linker that it can avoid linking in dynamic libraries that don't - // actually satisfy any symbols up to that point (as with many other - // resolutions the linker does). This option only applies to all - // following libraries so we're sure to pass it as one of the first - // arguments. - "-Wl,--as-needed".to_string(), // Always enable NX protection when it is available "-Wl,-z,noexecstack".to_string(), ], diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs index 7d685c83100..b4286dfd88f 100644 --- a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs @@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "v9".to_string(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/vxworks_base.rs b/compiler/rustc_target/src/spec/vxworks_base.rs index 70bc9ce3e0e..8396d0463d9 100644 --- a/compiler/rustc_target/src/spec/vxworks_base.rs +++ b/compiler/rustc_target/src/spec/vxworks_base.rs @@ -1,21 +1,6 @@ -use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::TargetOptions; pub fn opts() -> TargetOptions { - let mut args = LinkArgs::new(); - args.insert( - LinkerFlavor::Gcc, - vec![ - // We want to be able to strip as much executable code as possible - // from the linker command line, and this flag indicates to the - // linker that it can avoid linking in dynamic libraries that don't - // actually satisfy any symbols up to that point (as with many other - // resolutions the linker does). This option only applies to all - // following libraries so we're sure to pass it as one of the first - // arguments. - "-Wl,--as-needed".to_string(), - ], - ); - TargetOptions { os: "vxworks".to_string(), env: "gnu".to_string(), @@ -27,7 +12,6 @@ pub fn opts() -> TargetOptions { os_family: Some("unix".to_string()), linker_is_gnu: true, has_rpath: true, - pre_link_args: args, position_independent_executables: false, has_elf_tls: true, crt_static_default: true, diff --git a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs index 74fb6f0a834..aacbdbdeefb 100644 --- a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs +++ b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs @@ -4,7 +4,6 @@ use super::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions}; pub fn target() -> Target { const PRE_LINK_ARGS: &[&str] = &[ - "--as-needed", "-z", "noexecstack", "-e", diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs index 6d19dec00b4..54e7ceee82e 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs index 1b35e813fcd..f9fa9d93843 100644 --- a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; base.disable_redzone = true; From 049a49b91151a88c95fa0d62a53fd0a0ac2c3af9 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 28 Mar 2021 02:21:36 +0300 Subject: [PATCH 158/370] rustc_target: Avoid unwraps when adding linker flags --- compiler/rustc_target/src/spec/android_base.rs | 4 ++-- compiler/rustc_target/src/spec/armv7_linux_androideabi.rs | 2 +- compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs | 4 ++-- compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs | 6 +++--- compiler/rustc_target/src/spec/i686_unknown_freebsd.rs | 2 +- compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs | 2 +- compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs | 4 ++-- compiler/rustc_target/src/spec/i686_unknown_netbsd.rs | 2 +- compiler/rustc_target/src/spec/i686_unknown_openbsd.rs | 4 ++-- compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs | 4 ++-- compiler/rustc_target/src/spec/i686_wrs_vxworks.rs | 2 +- compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs | 2 +- .../rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs | 2 +- .../rustc_target/src/spec/powerpc64_unknown_linux_musl.rs | 2 +- compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs | 2 +- .../rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs | 2 +- .../rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs | 2 +- compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs | 2 +- .../rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs | 2 +- .../rustc_target/src/spec/powerpc_unknown_linux_musl.rs | 2 +- compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs | 2 +- compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs | 4 ++-- compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs | 4 ++-- compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs | 2 +- compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs | 2 +- compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs | 2 +- compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs | 6 +++--- .../rustc_target/src/spec/thumbv7neon_linux_androideabi.rs | 2 +- compiler/rustc_target/src/spec/uefi_msvc_base.rs | 6 +++--- compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs | 2 +- compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs | 4 ++-- compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs | 6 +++--- compiler/rustc_target/src/spec/x86_64_linux_android.rs | 2 +- compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs | 2 +- compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs | 2 +- compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs | 2 +- compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs | 2 +- .../rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs | 2 +- compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs | 2 +- compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs | 2 +- .../src/spec/x86_64_unknown_none_linuxkernel.rs | 2 +- compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs | 2 +- compiler/rustc_target/src/spec/x86_64_unknown_redox.rs | 2 +- compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs | 2 +- compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs | 2 +- 45 files changed, 61 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_target/src/spec/android_base.rs b/compiler/rustc_target/src/spec/android_base.rs index c7d2f2329ee..aaf81648c51 100644 --- a/compiler/rustc_target/src/spec/android_base.rs +++ b/compiler/rustc_target/src/spec/android_base.rs @@ -6,8 +6,8 @@ pub fn opts() -> TargetOptions { // Many of the symbols defined in compiler-rt are also defined in libgcc. // Android's linker doesn't like that by default. base.pre_link_args - .get_mut(&LinkerFlavor::Gcc) - .unwrap() + .entry(LinkerFlavor::Gcc) + .or_default() .push("-Wl,--allow-multiple-definition".to_string()); base.dwarf_version = Some(2); base.position_independent_executables = true; diff --git a/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs index 9aa378a8018..02a1191463e 100644 --- a/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs @@ -12,7 +12,7 @@ pub fn target() -> Target { let mut base = super::android_base::opts(); base.features = "+v7,+thumb-mode,+thumb2,+vfp3,-d32,-neon".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-march=armv7-a".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-march=armv7-a".to_string()); Target { llvm_target: "armv7-none-linux-android".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs index 4979a5b3bc8..7002d88c512 100644 --- a/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs @@ -12,8 +12,8 @@ pub fn target() -> Target { // Mark all dynamic libraries and executables as compatible with the larger 4GiB address // space available to x86 Windows binaries on x86_64. base.pre_link_args - .get_mut(&LinkerFlavor::Gcc) - .unwrap() + .entry(LinkerFlavor::Gcc) + .or_default() .push("-Wl,--large-address-aware".to_string()); Target { diff --git a/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs index e7a5643eaaa..74074cfb5dd 100644 --- a/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs @@ -14,10 +14,10 @@ pub fn target() -> Target { // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers "/SAFESEH".to_string(), ]; - base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone()); + base.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone()); base.pre_link_args - .get_mut(&LinkerFlavor::Lld(LldFlavor::Link)) - .unwrap() + .entry(LinkerFlavor::Lld(LldFlavor::Link)) + .or_default() .extend(pre_link_args_msvc); Target { diff --git a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs index fc425babb69..a26cabdc90a 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::freebsd_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - let pre_link_args = base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); + let pre_link_args = base.pre_link_args.entry(LinkerFlavor::Gcc).or_default(); pre_link_args.push("-m32".to_string()); pre_link_args.push("-Wl,-znotext".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs index fe1e6a4299d..633e8da0ccb 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs index 623fd1b9ae8..8bcd261e4df 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs @@ -4,8 +4,8 @@ pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,-melf_i386".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-Wl,-melf_i386".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; // The unwinder used by i686-unknown-linux-musl, the LLVM libunwind diff --git a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs index c4d11bfb13e..e020264ad7a 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs index fdaaf6c741e..86448cb9115 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs @@ -4,8 +4,8 @@ pub fn target() -> Target { let mut base = super::openbsd_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-fuse-ld=lld".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-fuse-ld=lld".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs index a3de93efb78..426df59882d 100644 --- a/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs @@ -11,8 +11,8 @@ pub fn target() -> Target { // Mark all dynamic libraries and executables as compatible with the larger 4GiB address // space available to x86 Windows binaries on x86_64. base.pre_link_args - .get_mut(&LinkerFlavor::Gcc) - .unwrap() + .entry(LinkerFlavor::Gcc) + .or_default() .push("-Wl,--large-address-aware".to_string()); Target { diff --git a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs index ec8a2493b4e..e596eca86b0 100644 --- a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs index 3dddeb1129c..b3d6b7c6107 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs @@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::freebsd_base::opts(); base.cpu = "ppc64".to_string(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs index 9db880b0e53..559a1a40868 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs @@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, RelroLevel, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "ppc64".to_string(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.max_atomic_width = Some(64); // ld.so in at least RHEL6 on ppc64 has a bug related to BIND_NOW, so only enable partial RELRO diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs index 8767f86b00b..f1190b159ab 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs @@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.cpu = "ppc64".to_string(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs index 2f28a856247..3ebc5469e0a 100644 --- a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs @@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "ppc64".to_string(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs index 4cbd9976508..76f70e474f0 100644 --- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs @@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "ppc64le".to_string(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs index efdc9ad7517..42c49103b3b 100644 --- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs @@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.cpu = "ppc64le".to_string(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs index 70dd0b2aee6..21ffdd2d160 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs @@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs index 66118b74955..8d8f746f97f 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs @@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mspe".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mspe".to_string()); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs index 679a3a2f6aa..9633705db6d 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs @@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs index 1245098329a..4cc5224fae3 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs @@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs index bb943a8825c..2f0a6ca44a0 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs @@ -3,8 +3,8 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("--secure-plt".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("--secure-plt".to_string()); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs index 4b4f118ba49..215f1a36227 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs @@ -3,8 +3,8 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mspe".to_string()); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("--secure-plt".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mspe".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("--secure-plt".to_string()); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs index 7d685c83100..b4286dfd88f 100644 --- a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs @@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "v9".to_string(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs index 63b13fad4f7..9732983161f 100644 --- a/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs @@ -5,7 +5,7 @@ pub fn target() -> Target { let mut base = super::openbsd_base::opts(); base.endian = Endian::Big; base.cpu = "v9".to_string(); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs index 9e8fbff81c5..1fd4cadfffc 100644 --- a/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs @@ -6,7 +6,7 @@ pub fn target() -> Target { base.endian = Endian::Big; base.cpu = "v9".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mv8plus".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mv8plus".to_string()); Target { llvm_target: "sparc-unknown-linux-gnu".to_string(), diff --git a/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs index 8131a6e2ea4..975fd81d9c3 100644 --- a/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs @@ -11,10 +11,10 @@ pub fn target() -> Target { // where necessary, but this is not the observed behavior. // Disabling the LBR optimization works around the issue. let pre_link_args_msvc = "/OPT:NOLBR".to_string(); - base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push(pre_link_args_msvc.clone()); + base.pre_link_args.entry(LinkerFlavor::Msvc).or_default().push(pre_link_args_msvc.clone()); base.pre_link_args - .get_mut(&LinkerFlavor::Lld(LldFlavor::Link)) - .unwrap() + .entry(LinkerFlavor::Lld(LldFlavor::Link)) + .or_default() .push(pre_link_args_msvc); // FIXME(jordanrh): use PanicStrategy::Unwind when SEH is diff --git a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs index 41fdbc2f0a0..58b0a9d2202 100644 --- a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs @@ -12,7 +12,7 @@ pub fn target() -> Target { let mut base = super::android_base::opts(); base.features = "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-march=armv7-a".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-march=armv7-a".to_string()); Target { llvm_target: "armv7-none-linux-android".to_string(), diff --git a/compiler/rustc_target/src/spec/uefi_msvc_base.rs b/compiler/rustc_target/src/spec/uefi_msvc_base.rs index b9ff16bd19f..6b6b6018601 100644 --- a/compiler/rustc_target/src/spec/uefi_msvc_base.rs +++ b/compiler/rustc_target/src/spec/uefi_msvc_base.rs @@ -30,10 +30,10 @@ pub fn opts() -> TargetOptions { // exit (default for applications). "/subsystem:efi_application".to_string(), ]; - base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone()); + base.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone()); base.pre_link_args - .get_mut(&LinkerFlavor::Lld(LldFlavor::Link)) - .unwrap() + .entry(LinkerFlavor::Lld(LldFlavor::Link)) + .or_default() .extend(pre_link_args_msvc); TargetOptions { diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs index 9f69ce16c21..58d7633fa62 100644 --- a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs @@ -4,7 +4,7 @@ use super::{LinkArgs, LinkerFlavor, PanicStrategy, Target, TargetOptions}; pub fn target() -> Target { let mut options = wasm32_base::options(); - let clang_args = options.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); + let clang_args = options.pre_link_args.entry(LinkerFlavor::Gcc).or_default(); // Rust really needs a way for users to specify exports and imports in // the source code. --export-dynamic isn't the right tool for this job, diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs index 5e89ba2520b..73a5e16c82b 100644 --- a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs @@ -17,7 +17,7 @@ pub fn target() -> Target { let mut options = wasm32_base::options(); options.os = "unknown".to_string(); options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); - let clang_args = options.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); + let clang_args = options.pre_link_args.entry(LinkerFlavor::Gcc).or_default(); // Make sure clang uses LLD as its linker and is configured appropriately // otherwise @@ -35,7 +35,7 @@ pub fn target() -> Target { clang_args.push("-Wl,--export-dynamic".to_string()); // Add the flags to wasm-ld's args too. - let lld_args = options.pre_link_args.get_mut(&LinkerFlavor::Lld(LldFlavor::Wasm)).unwrap(); + let lld_args = options.pre_link_args.entry(LinkerFlavor::Lld(LldFlavor::Wasm)).or_default(); lld_args.push("--no-entry".to_string()); lld_args.push("--export-dynamic".to_string()); diff --git a/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs index 700ee5ec646..b3fa5c22f98 100644 --- a/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs +++ b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs @@ -5,10 +5,10 @@ pub fn opts() -> TargetOptions { opts.vendor = "uwp".to_string(); let pre_link_args_msvc = vec!["/APPCONTAINER".to_string(), "mincore.lib".to_string()]; - opts.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone()); + opts.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone()); opts.pre_link_args - .get_mut(&LinkerFlavor::Lld(LldFlavor::Link)) - .unwrap() + .entry(LinkerFlavor::Lld(LldFlavor::Link)) + .or_default() .extend(pre_link_args_msvc); opts diff --git a/compiler/rustc_target/src/spec/x86_64_linux_android.rs b/compiler/rustc_target/src/spec/x86_64_linux_android.rs index d436242e62b..0945a9f5c59 100644 --- a/compiler/rustc_target/src/spec/x86_64_linux_android.rs +++ b/compiler/rustc_target/src/spec/x86_64_linux_android.rs @@ -6,7 +6,7 @@ pub fn target() -> Target { // https://developer.android.com/ndk/guides/abis.html#86-64 base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs index 36726ab4aed..26a81a484b9 100644 --- a/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs @@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, LldFlavor, Target}; pub fn target() -> Target { let mut base = super::windows_gnu_base::opts(); base.cpu = "x86-64".to_string(); - let gcc_pre_link_args = base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); + let gcc_pre_link_args = base.pre_link_args.entry(LinkerFlavor::Gcc).or_default(); gcc_pre_link_args.push("-m64".to_string()); // Use high-entropy 64 bit address space for ASLR gcc_pre_link_args.push("-Wl,--high-entropy-va".to_string()); diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs index d86b0d67acd..295f9c837c3 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::dragonfly_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs index c7d3b3feed5..aac01445917 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::freebsd_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs index 99906764dfc..dfda49b9c33 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs index 4b2bce37470..5f87534fe95 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mx32".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mx32".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; base.has_elf_tls = false; // BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs index fa9fdf5aa09..da79bc2f338 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; base.static_position_independent_executables = true; diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs index 6d19dec00b4..54e7ceee82e 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs index 68d80205e14..fa6f255d4d9 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs @@ -11,7 +11,7 @@ pub fn target() -> Target { "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float" .to_string(); base.code_model = Some(CodeModel::Kernel); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); Target { // FIXME: Some dispute, the linux-on-clang folks think this should use diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs index ac5939bcb3c..530e63966aa 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::openbsd_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs index ddabe95ab83..934f8de8ecc 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::redox_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs index 57913ba0dab..a5425e1c129 100644 --- a/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs @@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, LldFlavor, Target}; pub fn target() -> Target { let mut base = super::windows_uwp_gnu_base::opts(); base.cpu = "x86-64".to_string(); - let gcc_pre_link_args = base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); + let gcc_pre_link_args = base.pre_link_args.entry(LinkerFlavor::Gcc).or_default(); gcc_pre_link_args.push("-m64".to_string()); // Use high-entropy 64 bit address space for ASLR gcc_pre_link_args.push("-Wl,--high-entropy-va".to_string()); diff --git a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs index 1b35e813fcd..f9fa9d93843 100644 --- a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; base.disable_redzone = true; From 785aeac521e54da8c6826396d05446227e19ee40 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 15 Mar 2021 15:11:40 -0400 Subject: [PATCH 159/370] Remove unused `DiagnosticBuilder::sub` function `Diagnostic::sub` is only ever used directly; it doesn't need to be included in the builder. --- compiler/rustc_errors/src/diagnostic.rs | 2 ++ compiler/rustc_errors/src/diagnostic_builder.rs | 13 ------------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index ce5b130dd97..b2dee6ab78c 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -582,6 +582,8 @@ impl Diagnostic { /// Convenience function for internal use, clients should use one of the /// public methods above. + /// + /// Used by `proc_macro_server` for implementing `server::Diagnostic`. pub fn sub( &mut self, level: Level, diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 79507e61522..26c7f094f6a 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -157,19 +157,6 @@ impl<'a> DiagnosticBuilder<'a> { buffered_diagnostics.extend(self.into_diagnostic().map(|(diag, _)| diag)); } - /// Convenience function for internal use, clients should use one of the - /// span_* methods instead. - pub fn sub>( - &mut self, - level: Level, - message: &str, - span: Option, - ) -> &mut Self { - let span = span.map(|s| s.into()).unwrap_or_else(MultiSpan::new); - self.0.diagnostic.sub(level, message, span, None); - self - } - /// Delay emission of this diagnostic as a bug. /// /// This can be useful in contexts where an error indicates a bug but From 441dc3640a408e612064464b0c6308bdca6c16ce Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 16 Mar 2021 01:50:34 -0400 Subject: [PATCH 160/370] Remove (lots of) dead code Found with https://github.com/est31/warnalyzer. Dubious changes: - Is anyone else using rustc_apfloat? I feel weird completely deleting x87 support. - Maybe some of the dead code in rustc_data_structures, in case someone wants to use it in the future? - Don't change rustc_serialize I plan to scrap most of the json module in the near future (see https://github.com/rust-lang/compiler-team/issues/418) and fixing the tests needed more work than I expected. TODO: check if any of the comments on the deleted code should be kept. --- compiler/rustc_arena/src/lib.rs | 20 ---- compiler/rustc_ast/src/ast.rs | 64 ----------- compiler/rustc_ast/src/attr/mod.rs | 40 +------ compiler/rustc_ast/src/tokenstream.rs | 20 ---- compiler/rustc_ast_pretty/src/pprust/mod.rs | 24 ---- compiler/rustc_ast_pretty/src/pprust/state.rs | 4 - compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 88 +------------- compiler/rustc_data_structures/src/sync.rs | 108 ------------------ .../src/tagged_ptr/drop.rs | 9 -- .../rustc_data_structures/src/work_queue.rs | 6 - compiler/rustc_driver/src/lib.rs | 10 +- compiler/rustc_driver/src/pretty.rs | 11 -- compiler/rustc_errors/src/diagnostic.rs | 58 ++-------- .../rustc_errors/src/diagnostic_builder.rs | 14 --- compiler/rustc_errors/src/lib.rs | 4 - compiler/rustc_errors/src/registry.rs | 4 - compiler/rustc_errors/src/snippet.rs | 10 -- compiler/rustc_expand/src/build.rs | 11 -- .../rustc_expand/src/tokenstream/tests.rs | 10 +- compiler/rustc_graphviz/src/lib.rs | 18 --- compiler/rustc_graphviz/src/tests.rs | 2 +- compiler/rustc_hir/src/definitions.rs | 7 +- compiler/rustc_hir/src/hir.rs | 14 +-- compiler/rustc_hir/src/hir_id.rs | 67 ----------- compiler/rustc_hir/src/pat_util.rs | 20 ---- compiler/rustc_hir_pretty/src/lib.rs | 33 ------ .../src/persist/dirty_clean.rs | 14 --- compiler/rustc_infer/src/infer/mod.rs | 17 --- .../rustc_infer/src/infer/outlives/env.rs | 5 - .../src/infer/outlives/obligations.rs | 22 ---- .../src/infer/region_constraints/mod.rs | 40 ------- .../rustc_infer/src/infer/type_variable.rs | 56 +-------- compiler/rustc_infer/src/infer/undo_log.rs | 4 - compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_lint/src/context.rs | 3 + compiler/rustc_lint/src/levels.rs | 4 - compiler/rustc_middle/src/hir/map/mod.rs | 29 ----- compiler/rustc_middle/src/ich/hcx.rs | 5 - compiler/rustc_middle/src/infer/canonical.rs | 8 -- compiler/rustc_middle/src/infer/unify_key.rs | 7 -- compiler/rustc_middle/src/middle/region.rs | 2 + compiler/rustc_middle/src/middle/stability.rs | 6 - compiler/rustc_middle/src/mir/coverage.rs | 8 -- .../rustc_middle/src/mir/interpret/value.rs | 10 -- compiler/rustc_middle/src/mir/mod.rs | 18 --- compiler/rustc_middle/src/mir/traversal.rs | 4 - compiler/rustc_middle/src/mir/visit.rs | 6 - compiler/rustc_middle/src/traits/query.rs | 12 -- compiler/rustc_middle/src/ty/closure.rs | 17 --- compiler/rustc_middle/src/ty/codec.rs | 4 +- compiler/rustc_middle/src/ty/context.rs | 22 +--- compiler/rustc_middle/src/ty/mod.rs | 19 --- compiler/rustc_middle/src/ty/sty.rs | 81 +------------ .../src/dataflow/framework/cursor.rs | 4 - .../rustc_mir/src/interpret/eval_context.rs | 15 --- compiler/rustc_mir/src/interpret/machine.rs | 5 - compiler/rustc_mir/src/interpret/operand.rs | 8 -- .../rustc_mir/src/util/generic_graphviz.rs | 16 --- compiler/rustc_mir/src/util/patch.rs | 4 - compiler/rustc_query_system/src/cache.rs | 8 -- .../rustc_query_system/src/dep_graph/debug.rs | 1 + .../rustc_query_system/src/dep_graph/graph.rs | 4 +- .../rustc_query_system/src/dep_graph/prev.rs | 5 - .../rustc_query_system/src/dep_graph/query.rs | 4 - compiler/rustc_save_analysis/src/lib.rs | 18 +-- compiler/rustc_session/src/config.rs | 28 +---- compiler/rustc_session/src/parse.rs | 1 + compiler/rustc_session/src/session.rs | 91 +-------------- compiler/rustc_span/src/def_id.rs | 2 + compiler/rustc_span/src/hygiene.rs | 26 +---- compiler/rustc_span/src/lib.rs | 7 -- .../query/type_op/implied_outlives_bounds.rs | 6 - .../clippy/clippy_lints/src/functions.rs | 2 +- .../clippy/clippy_lints/src/missing_doc.rs | 2 +- 74 files changed, 60 insertions(+), 1298 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index c3198fb1043..c3e4945c446 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -236,26 +236,6 @@ impl TypedArena { start_ptr } - /// Allocates a slice of objects that are copied into the `TypedArena`, returning a mutable - /// reference to it. Will panic if passed a zero-sized types. - /// - /// Panics: - /// - /// - Zero-sized types - /// - Zero-length slices - #[inline] - pub fn alloc_slice(&self, slice: &[T]) -> &mut [T] - where - T: Copy, - { - unsafe { - let len = slice.len(); - let start_ptr = self.alloc_raw_slice(len); - slice.as_ptr().copy_to_nonoverlapping(start_ptr, len); - slice::from_raw_parts_mut(start_ptr, len) - } - } - #[inline] pub fn alloc_from_iter>(&self, iter: I) -> &mut [T] { assert!(mem::size_of::() != 0); diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 7e82d7ff77d..2cffddfcd0b 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -762,14 +762,6 @@ pub enum Mutability { } impl Mutability { - /// Returns `MutMutable` only if both `self` and `other` are mutable. - pub fn and(self, other: Self) -> Self { - match self { - Mutability::Mut => other, - Mutability::Not => Mutability::Not, - } - } - pub fn invert(self) -> Self { match self { Mutability::Mut => Mutability::Not, @@ -1722,13 +1714,6 @@ impl FloatTy { FloatTy::F64 => sym::f64, } } - - pub fn bit_width(self) -> u64 { - match self { - FloatTy::F32 => 32, - FloatTy::F64 => 64, - } - } } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] @@ -1764,29 +1749,6 @@ impl IntTy { IntTy::I128 => sym::i128, } } - - pub fn bit_width(&self) -> Option { - Some(match *self { - IntTy::Isize => return None, - IntTy::I8 => 8, - IntTy::I16 => 16, - IntTy::I32 => 32, - IntTy::I64 => 64, - IntTy::I128 => 128, - }) - } - - pub fn normalize(&self, target_width: u32) -> Self { - match self { - IntTy::Isize => match target_width { - 16 => IntTy::I16, - 32 => IntTy::I32, - 64 => IntTy::I64, - _ => unreachable!(), - }, - _ => *self, - } - } } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)] @@ -1822,29 +1784,6 @@ impl UintTy { UintTy::U128 => sym::u128, } } - - pub fn bit_width(&self) -> Option { - Some(match *self { - UintTy::Usize => return None, - UintTy::U8 => 8, - UintTy::U16 => 16, - UintTy::U32 => 32, - UintTy::U64 => 64, - UintTy::U128 => 128, - }) - } - - pub fn normalize(&self, target_width: u32) -> Self { - match self { - UintTy::Usize => match target_width { - 16 => UintTy::U16, - 32 => UintTy::U32, - 64 => UintTy::U64, - _ => unreachable!(), - }, - _ => *self, - } - } } /// A constraint on an associated type (e.g., `A = Bar` in `Foo` or @@ -2215,9 +2154,6 @@ pub struct FnDecl { } impl FnDecl { - pub fn get_self(&self) -> Option { - self.inputs.get(0).and_then(Param::to_self) - } pub fn has_self(&self) -> bool { self.inputs.get(0).map_or(false, Param::is_self) } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 2c5e180f80d..0fbe4d0120c 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -100,16 +100,7 @@ impl NestedMetaItem { self.meta_item().map_or(false, |meta_item| meta_item.is_word()) } - /// Returns `true` if `self` is a `MetaItem` and the meta item is a `ValueString`. - pub fn is_value_str(&self) -> bool { - self.value_str().is_some() - } - - /// Returns `true` if `self` is a `MetaItem` and the meta item is a list. - pub fn is_meta_item_list(&self) -> bool { - self.meta_item_list().is_some() - } - + /// See [`MetaItem::name_value_literal_span`]. pub fn name_value_literal_span(&self) -> Option { self.meta_item()?.name_value_literal_span() } @@ -165,31 +156,6 @@ impl Attribute { false } } - - pub fn is_meta_item_list(&self) -> bool { - self.meta_item_list().is_some() - } - - /// Indicates if the attribute is a `ValueString`. - pub fn is_value_str(&self) -> bool { - self.value_str().is_some() - } - - /// This is used in case you want the value span instead of the whole attribute. Example: - /// - /// ```text - /// #[doc(alias = "foo")] - /// ``` - /// - /// In here, it'll return a span for `"foo"`. - pub fn name_value_literal_span(&self) -> Option { - match self.kind { - AttrKind::Normal(ref item, _) => { - item.meta(self.span).and_then(|meta| meta.name_value_literal_span()) - } - AttrKind::DocComment(..) => None, - } - } } impl MetaItem { @@ -236,10 +202,6 @@ impl MetaItem { self.path == name } - pub fn is_value_str(&self) -> bool { - self.value_str().is_some() - } - /// This is used in case you want the value span instead of the whole attribute. Example: /// /// ```text diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 1e63ca172e7..06d49c7524a 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -89,10 +89,6 @@ impl TokenTree { } } - pub fn joint(self) -> TokenStream { - TokenStream::new(vec![(self, Spacing::Joint)]) - } - pub fn token(kind: TokenKind, span: Span) -> TokenTree { TokenTree::Token(Token::new(kind, span)) } @@ -278,14 +274,6 @@ impl TokenStream { self.0.len() } - pub fn span(&self) -> Option { - match &**self.0 { - [] => None, - [(tt, _)] => Some(tt.span()), - [(tt_start, _), .., (tt_end, _)] => Some(tt_start.span().to(tt_end.span())), - } - } - pub fn from_streams(mut streams: SmallVec<[TokenStream; 2]>) -> TokenStream { match streams.len() { 0 => TokenStream::default(), @@ -325,10 +313,6 @@ impl TokenStream { } } - pub fn trees_ref(&self) -> CursorRef<'_> { - CursorRef::new(self) - } - pub fn trees(&self) -> Cursor { self.clone().into_trees() } @@ -427,10 +411,6 @@ pub struct CursorRef<'t> { } impl<'t> CursorRef<'t> { - fn new(stream: &TokenStream) -> CursorRef<'_> { - CursorRef { stream, index: 0 } - } - fn next_with_spacing(&mut self) -> Option<&'t TreeAndSpacing> { self.stream.0.get(self.index).map(|tree| { self.index += 1; diff --git a/compiler/rustc_ast_pretty/src/pprust/mod.rs b/compiler/rustc_ast_pretty/src/pprust/mod.rs index b88699f6ee1..976725b308e 100644 --- a/compiler/rustc_ast_pretty/src/pprust/mod.rs +++ b/compiler/rustc_ast_pretty/src/pprust/mod.rs @@ -22,10 +22,6 @@ pub fn token_to_string(token: &Token) -> String { State::new().token_to_string(token) } -pub fn token_to_string_ext(token: &Token, convert_dollar_crate: bool) -> String { - State::new().token_to_string_ext(token, convert_dollar_crate) -} - pub fn ty_to_string(ty: &ast::Ty) -> String { State::new().ty_to_string(ty) } @@ -50,18 +46,10 @@ pub fn tts_to_string(tokens: &TokenStream) -> String { State::new().tts_to_string(tokens) } -pub fn stmt_to_string(stmt: &ast::Stmt) -> String { - State::new().stmt_to_string(stmt) -} - pub fn item_to_string(i: &ast::Item) -> String { State::new().item_to_string(i) } -pub fn generic_params_to_string(generic_params: &[ast::GenericParam]) -> String { - State::new().generic_params_to_string(generic_params) -} - pub fn path_to_string(p: &ast::Path) -> String { State::new().path_to_string(p) } @@ -74,26 +62,14 @@ pub fn vis_to_string(v: &ast::Visibility) -> String { State::new().vis_to_string(v) } -pub fn block_to_string(blk: &ast::Block) -> String { - State::new().block_to_string(blk) -} - pub fn meta_list_item_to_string(li: &ast::NestedMetaItem) -> String { State::new().meta_list_item_to_string(li) } -pub fn attr_item_to_string(ai: &ast::AttrItem) -> String { - State::new().attr_item_to_string(ai) -} - pub fn attribute_to_string(attr: &ast::Attribute) -> String { State::new().attribute_to_string(attr) } -pub fn param_to_string(arg: &ast::Param) -> String { - State::new().param_to_string(arg) -} - pub fn to_string(f: impl FnOnce(&mut State<'_>)) -> String { State::new().to_string(f) } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 84f8ce5706a..627c0584b61 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -2292,10 +2292,6 @@ impl<'a> State<'a> { } } - pub fn print_usize(&mut self, i: usize) { - self.s.word(i.to_string()) - } - crate fn print_name(&mut self, name: Symbol) { self.s.word(name.to_string()); self.ann.post(self, AnnNode::Name(&name)) diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 82cd1be3b3b..4a1b76079b3 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -190,33 +190,6 @@ pub enum RealPredicate { RealPredicateTrue = 15, } -impl RealPredicate { - pub fn from_generic(realpred: rustc_codegen_ssa::common::RealPredicate) -> Self { - match realpred { - rustc_codegen_ssa::common::RealPredicate::RealPredicateFalse => { - RealPredicate::RealPredicateFalse - } - rustc_codegen_ssa::common::RealPredicate::RealOEQ => RealPredicate::RealOEQ, - rustc_codegen_ssa::common::RealPredicate::RealOGT => RealPredicate::RealOGT, - rustc_codegen_ssa::common::RealPredicate::RealOGE => RealPredicate::RealOGE, - rustc_codegen_ssa::common::RealPredicate::RealOLT => RealPredicate::RealOLT, - rustc_codegen_ssa::common::RealPredicate::RealOLE => RealPredicate::RealOLE, - rustc_codegen_ssa::common::RealPredicate::RealONE => RealPredicate::RealONE, - rustc_codegen_ssa::common::RealPredicate::RealORD => RealPredicate::RealORD, - rustc_codegen_ssa::common::RealPredicate::RealUNO => RealPredicate::RealUNO, - rustc_codegen_ssa::common::RealPredicate::RealUEQ => RealPredicate::RealUEQ, - rustc_codegen_ssa::common::RealPredicate::RealUGT => RealPredicate::RealUGT, - rustc_codegen_ssa::common::RealPredicate::RealUGE => RealPredicate::RealUGE, - rustc_codegen_ssa::common::RealPredicate::RealULT => RealPredicate::RealULT, - rustc_codegen_ssa::common::RealPredicate::RealULE => RealPredicate::RealULE, - rustc_codegen_ssa::common::RealPredicate::RealUNE => RealPredicate::RealUNE, - rustc_codegen_ssa::common::RealPredicate::RealPredicateTrue => { - RealPredicate::RealPredicateTrue - } - } - } -} - /// LLVMTypeKind #[derive(Copy, Clone, PartialEq, Debug)] #[repr(C)] @@ -711,7 +684,7 @@ pub mod coverageinfo { } impl CounterMappingRegion { - pub fn code_region( + crate fn code_region( counter: coverage_map::Counter, file_id: u32, start_line: u32, @@ -730,65 +703,6 @@ pub mod coverageinfo { kind: RegionKind::CodeRegion, } } - - pub fn expansion_region( - file_id: u32, - expanded_file_id: u32, - start_line: u32, - start_col: u32, - end_line: u32, - end_col: u32, - ) -> Self { - Self { - counter: coverage_map::Counter::zero(), - file_id, - expanded_file_id, - start_line, - start_col, - end_line, - end_col, - kind: RegionKind::ExpansionRegion, - } - } - - pub fn skipped_region( - file_id: u32, - start_line: u32, - start_col: u32, - end_line: u32, - end_col: u32, - ) -> Self { - Self { - counter: coverage_map::Counter::zero(), - file_id, - expanded_file_id: 0, - start_line, - start_col, - end_line, - end_col, - kind: RegionKind::SkippedRegion, - } - } - - pub fn gap_region( - counter: coverage_map::Counter, - file_id: u32, - start_line: u32, - start_col: u32, - end_line: u32, - end_col: u32, - ) -> Self { - Self { - counter, - file_id, - expanded_file_id: 0, - start_line, - start_col, - end_line, - end_col: ((1 as u32) << 31) | end_col, - kind: RegionKind::GapRegion, - } - } } } diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 26706cd2b1b..c17c28df872 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -43,46 +43,6 @@ cfg_if! { use std::ops::Add; use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe}; - /// This is a single threaded variant of AtomicCell provided by crossbeam. - /// Unlike `Atomic` this is intended for all `Copy` types, - /// but it lacks the explicit ordering arguments. - #[derive(Debug)] - pub struct AtomicCell(Cell); - - impl AtomicCell { - #[inline] - pub fn new(v: T) -> Self { - AtomicCell(Cell::new(v)) - } - - #[inline] - pub fn get_mut(&mut self) -> &mut T { - self.0.get_mut() - } - } - - impl AtomicCell { - #[inline] - pub fn into_inner(self) -> T { - self.0.into_inner() - } - - #[inline] - pub fn load(&self) -> T { - self.0.get() - } - - #[inline] - pub fn store(&self, val: T) { - self.0.set(val) - } - - #[inline] - pub fn swap(&self, val: T) -> T { - self.0.replace(val) - } - } - /// This is a single threaded variant of `AtomicU64`, `AtomicUsize`, etc. /// It differs from `AtomicCell` in that it has explicit ordering arguments /// and is only intended for use with the native atomic types. @@ -99,11 +59,6 @@ cfg_if! { } impl Atomic { - #[inline] - pub fn into_inner(self) -> T { - self.0.into_inner() - } - #[inline] pub fn load(&self, _: Ordering) -> T { self.0.get() @@ -113,11 +68,6 @@ cfg_if! { pub fn store(&self, val: T, _: Ordering) { self.0.set(val) } - - #[inline] - pub fn swap(&self, val: T, _: Ordering) -> T { - self.0.replace(val) - } } impl Atomic { @@ -159,22 +109,6 @@ cfg_if! { (oper_a(), oper_b()) } - pub struct SerialScope; - - impl SerialScope { - pub fn spawn(&self, f: F) - where F: FnOnce(&SerialScope) - { - f(self) - } - } - - pub fn scope(f: F) -> R - where F: FnOnce(&SerialScope) -> R - { - f(&SerialScope) - } - #[macro_export] macro_rules! parallel { ($($blocks:tt),*) => { @@ -246,12 +180,6 @@ cfg_if! { pub fn new T>(mut f: F) -> WorkerLocal { WorkerLocal(OneThread::new(f(0))) } - - /// Returns the worker-local value for each thread - #[inline] - pub fn into_inner(self) -> Vec { - vec![OneThread::into_inner(self.0)] - } } impl Deref for WorkerLocal { @@ -279,16 +207,6 @@ cfg_if! { self.0 } - #[inline(always)] - pub fn get_mut(&mut self) -> &mut T { - &mut self.0 - } - - #[inline(always)] - pub fn lock(&self) -> &T { - &self.0 - } - #[inline(always)] pub fn lock_mut(&mut self) -> &mut T { &mut self.0 @@ -521,16 +439,6 @@ impl RwLock { RwLock(InnerRwLock::new(inner)) } - #[inline(always)] - pub fn into_inner(self) -> T { - self.0.into_inner() - } - - #[inline(always)] - pub fn get_mut(&mut self) -> &mut T { - self.0.get_mut() - } - #[cfg(not(parallel_compiler))] #[inline(always)] pub fn read(&self) -> ReadGuard<'_, T> { @@ -547,11 +455,6 @@ impl RwLock { } } - #[inline(always)] - pub fn with_read_lock R, R>(&self, f: F) -> R { - f(&*self.read()) - } - #[cfg(not(parallel_compiler))] #[inline(always)] pub fn try_write(&self) -> Result, ()> { @@ -580,11 +483,6 @@ impl RwLock { } } - #[inline(always)] - pub fn with_write_lock R, R>(&self, f: F) -> R { - f(&mut *self.write()) - } - #[inline(always)] pub fn borrow(&self) -> ReadGuard<'_, T> { self.read() @@ -633,12 +531,6 @@ impl OneThread { inner, } } - - #[inline(always)] - pub fn into_inner(value: Self) -> T { - value.check(); - value.inner - } } impl Deref for OneThread { diff --git a/compiler/rustc_data_structures/src/tagged_ptr/drop.rs b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs index 63f64beae5a..d44ccd368b3 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/drop.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs @@ -42,18 +42,9 @@ where pub fn pointer_ref(&self) -> &P::Target { self.raw.pointer_ref() } - pub fn pointer_mut(&mut self) -> &mut P::Target - where - P: std::ops::DerefMut, - { - self.raw.pointer_mut() - } pub fn tag(&self) -> T { self.raw.tag() } - pub fn set_tag(&mut self, tag: T) { - self.raw.set_tag(tag); - } } impl std::ops::Deref for TaggedPtr diff --git a/compiler/rustc_data_structures/src/work_queue.rs b/compiler/rustc_data_structures/src/work_queue.rs index cc562bc1e4d..10317f1afff 100644 --- a/compiler/rustc_data_structures/src/work_queue.rs +++ b/compiler/rustc_data_structures/src/work_queue.rs @@ -41,10 +41,4 @@ impl WorkQueue { None } } - - /// Returns `true` if nothing is enqueued. - #[inline] - pub fn is_empty(&self) -> bool { - self.deque.is_empty() - } } diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index e527d55fc2a..2a61fb54772 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -146,6 +146,7 @@ impl<'a, 'b> RunCompiler<'a, 'b> { pub fn new(at_args: &'a [String], callbacks: &'b mut (dyn Callbacks + Send)) -> Self { Self { at_args, callbacks, file_loader: None, emitter: None, make_codegen_backend: None } } + /// Used by cg_clif. pub fn set_make_codegen_backend( &mut self, make_codegen_backend: Option< @@ -155,10 +156,13 @@ impl<'a, 'b> RunCompiler<'a, 'b> { self.make_codegen_backend = make_codegen_backend; self } - pub fn set_emitter(&mut self, emitter: Option>) -> &mut Self { - self.emitter = emitter; - self + /// Used by RLS. + pub fn set_emitter(&mut self, emitter: Option>) -> &mut Self + { + self.emitter = emitter; + self } + /// Used by RLS. pub fn set_file_loader( &mut self, file_loader: Option>, diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs index 1544c975838..e0c140b143b 100644 --- a/compiler/rustc_driver/src/pretty.rs +++ b/compiler/rustc_driver/src/pretty.rs @@ -108,13 +108,6 @@ trait HirPrinterSupport<'hir>: pprust_hir::PpAnn { /// (Rust does not yet support upcasting from a trait object to /// an object for one of its super-traits.) fn pp_ann(&self) -> &dyn pprust_hir::PpAnn; - - /// Computes an user-readable representation of a path, if possible. - fn node_path(&self, id: hir::HirId) -> Option { - self.hir_map().and_then(|map| map.def_path_from_hir_id(id)).map(|path| { - path.data.into_iter().map(|elem| elem.data.to_string()).collect::>().join("::") - }) - } } struct NoAnn<'hir> { @@ -327,10 +320,6 @@ impl<'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'tcx> { fn pp_ann(&self) -> &dyn pprust_hir::PpAnn { self } - - fn node_path(&self, id: hir::HirId) -> Option { - Some(self.tcx.def_path_str(self.tcx.hir().local_def_id(id).to_def_id())) - } } impl<'tcx> pprust_hir::PpAnn for TypedAnnotation<'tcx> { diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index b2dee6ab78c..b2f6a0c1014 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -69,10 +69,6 @@ impl DiagnosticStyledString { pub fn highlighted>(t: S) -> DiagnosticStyledString { DiagnosticStyledString(vec![StringPart::Highlighted(t.into())]) } - - pub fn content(&self) -> String { - self.0.iter().map(|x| x.content()).collect::() - } } #[derive(Debug, PartialEq, Eq)] @@ -81,14 +77,6 @@ pub enum StringPart { Highlighted(String), } -impl StringPart { - pub fn content(&self) -> &str { - match self { - &StringPart::Normal(ref s) | &StringPart::Highlighted(ref s) => s, - } - } -} - impl Diagnostic { pub fn new(level: Level, message: &str) -> Self { Diagnostic::new_with_code(level, None, message) @@ -156,7 +144,7 @@ impl Diagnostic { self } - pub fn note_expected_found( + crate fn note_expected_found( &mut self, expected_label: &dyn fmt::Display, expected: DiagnosticStyledString, @@ -166,7 +154,7 @@ impl Diagnostic { self.note_expected_found_extra(expected_label, expected, found_label, found, &"", &"") } - pub fn note_unsuccessful_coercion( + crate fn note_unsuccessful_coercion( &mut self, expected: DiagnosticStyledString, found: DiagnosticStyledString, @@ -256,33 +244,33 @@ impl Diagnostic { /// Prints the span with a note above it. /// This is like [`Diagnostic::note()`], but it gets its own span. - pub fn span_note>(&mut self, sp: S, msg: &str) -> &mut Self { + crate fn span_note>(&mut self, sp: S, msg: &str) -> &mut Self { self.sub(Level::Note, msg, sp.into(), None); self } /// Add a warning attached to this diagnostic. - pub fn warn(&mut self, msg: &str) -> &mut Self { + crate fn warn(&mut self, msg: &str) -> &mut Self { self.sub(Level::Warning, msg, MultiSpan::new(), None); self } /// Prints the span with a warning above it. /// This is like [`Diagnostic::warn()`], but it gets its own span. - pub fn span_warn>(&mut self, sp: S, msg: &str) -> &mut Self { + crate fn span_warn>(&mut self, sp: S, msg: &str) -> &mut Self { self.sub(Level::Warning, msg, sp.into(), None); self } /// Add a help message attached to this diagnostic. - pub fn help(&mut self, msg: &str) -> &mut Self { + crate fn help(&mut self, msg: &str) -> &mut Self { self.sub(Level::Help, msg, MultiSpan::new(), None); self } /// Prints the span with some help above it. /// This is like [`Diagnostic::help()`], but it gets its own span. - pub fn span_help>(&mut self, sp: S, msg: &str) -> &mut Self { + crate fn span_help>(&mut self, sp: S, msg: &str) -> &mut Self { self.sub(Level::Help, msg, sp.into(), None); self } @@ -311,36 +299,6 @@ impl Diagnostic { self } - /// Show multiple suggestions that have multiple parts. - /// See also [`Diagnostic::multipart_suggestion()`]. - pub fn multipart_suggestions( - &mut self, - msg: &str, - suggestions: Vec>, - applicability: Applicability, - ) -> &mut Self { - assert!(!suggestions.is_empty()); - for s in &suggestions { - assert!(!s.is_empty()); - } - self.suggestions.push(CodeSuggestion { - substitutions: suggestions - .into_iter() - .map(|suggestion| Substitution { - parts: suggestion - .into_iter() - .map(|(span, snippet)| SubstitutionPart { snippet, span }) - .collect(), - }) - .collect(), - msg: msg.to_owned(), - style: SuggestionStyle::ShowCode, - applicability, - tool_metadata: Default::default(), - }); - self - } - /// Prints out a message with for a multipart suggestion without showing the suggested code. /// /// This is intended to be used for suggestions that are obvious in what the changes need to @@ -567,7 +525,7 @@ impl Diagnostic { self.code.clone() } - pub fn set_primary_message>(&mut self, msg: M) -> &mut Self { + crate fn set_primary_message>(&mut self, msg: M) -> &mut Self { self.message[0] = (msg.into(), Style::NoStyle); self } diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 26c7f094f6a..282877d5dd1 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -257,20 +257,6 @@ impl<'a> DiagnosticBuilder<'a> { self } - /// See [`Diagnostic::multipart_suggestions()`]. - pub fn multipart_suggestions( - &mut self, - msg: &str, - suggestions: Vec>, - applicability: Applicability, - ) -> &mut Self { - if !self.0.allow_suggestions { - return self; - } - self.0.diagnostic.multipart_suggestions(msg, suggestions, applicability); - self - } - /// See [`Diagnostic::tool_only_multipart_suggestion()`]. pub fn tool_only_multipart_suggestion( &mut self, diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6f3ce20fc8e..ac7353730ad 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -691,10 +691,6 @@ impl Handler { db } - pub fn failure(&self, msg: &str) { - self.inner.borrow_mut().failure(msg); - } - pub fn fatal(&self, msg: &str) -> FatalError { self.inner.borrow_mut().fatal(msg) } diff --git a/compiler/rustc_errors/src/registry.rs b/compiler/rustc_errors/src/registry.rs index b1d770d5bd5..da764d993bb 100644 --- a/compiler/rustc_errors/src/registry.rs +++ b/compiler/rustc_errors/src/registry.rs @@ -13,10 +13,6 @@ impl Registry { Registry { long_descriptions: long_descriptions.iter().copied().collect() } } - /// This will panic if an invalid error code is passed in - pub fn find_description(&self, code: &str) -> Option<&'static str> { - self.long_descriptions[code] - } /// Returns `InvalidErrorCode` if the code requested does not exist in the /// registry. Otherwise, returns an `Option` where `None` means the error /// code is valid but has no extended information. diff --git a/compiler/rustc_errors/src/snippet.rs b/compiler/rustc_errors/src/snippet.rs index acb88e57db5..3fe02bd0cee 100644 --- a/compiler/rustc_errors/src/snippet.rs +++ b/compiler/rustc_errors/src/snippet.rs @@ -121,16 +121,6 @@ impl Annotation { matches!(self.annotation_type, AnnotationType::MultilineLine(_)) } - pub fn is_multiline(&self) -> bool { - matches!( - self.annotation_type, - AnnotationType::Multiline(_) - | AnnotationType::MultilineStart(_) - | AnnotationType::MultilineLine(_) - | AnnotationType::MultilineEnd(_) - ) - } - pub fn len(&self) -> usize { // Account for usize underflows if self.end_col > self.start_col { diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 3664ff3ae8a..cb8b9398283 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -253,17 +253,6 @@ impl<'a> ExtCtxt<'a> { let pathexpr = self.expr_path(self.path_global(sp, fn_path)); self.expr_call(sp, pathexpr, args) } - pub fn expr_method_call( - &self, - span: Span, - expr: P, - ident: Ident, - mut args: Vec>, - ) -> P { - args.insert(0, expr); - let segment = ast::PathSegment::from_ident(ident.with_span_pos(span)); - self.expr(span, ast::ExprKind::MethodCall(segment, args, span)) - } pub fn expr_block(&self, b: P) -> P { self.expr(b.span, ast::ExprKind::Block(b, None)) } diff --git a/compiler/rustc_expand/src/tokenstream/tests.rs b/compiler/rustc_expand/src/tokenstream/tests.rs index 4e818e9feb0..8b546e7e4a3 100644 --- a/compiler/rustc_expand/src/tokenstream/tests.rs +++ b/compiler/rustc_expand/src/tokenstream/tests.rs @@ -1,7 +1,7 @@ use crate::tests::string_to_stream; use rustc_ast::token; -use rustc_ast::tokenstream::{TokenStream, TokenStreamBuilder, TokenTree}; +use rustc_ast::tokenstream::{Spacing, TokenStream, TokenStreamBuilder, TokenTree}; use rustc_span::with_default_session_globals; use rustc_span::{BytePos, Span, Symbol}; use smallvec::smallvec; @@ -14,6 +14,10 @@ fn sp(a: u32, b: u32) -> Span { Span::with_root_ctxt(BytePos(a), BytePos(b)) } +fn joint(tree: TokenTree) -> TokenStream { + TokenStream::new(vec![(tree, Spacing::Joint)]) +} + #[test] fn test_concat() { with_default_session_globals(|| { @@ -99,8 +103,8 @@ fn test_is_empty() { fn test_dotdotdot() { with_default_session_globals(|| { let mut builder = TokenStreamBuilder::new(); - builder.push(TokenTree::token(token::Dot, sp(0, 1)).joint()); - builder.push(TokenTree::token(token::Dot, sp(1, 2)).joint()); + builder.push(joint(TokenTree::token(token::Dot, sp(0, 1)))); + builder.push(joint(TokenTree::token(token::Dot, sp(1, 2)))); builder.push(TokenTree::token(token::Dot, sp(2, 3))); let stream = builder.build(); assert!(stream.eq_unspanned(&string_to_ts("..."))); diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index 9653ff022f1..db70beb5914 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -413,10 +413,6 @@ impl<'a> Id<'a> { pub fn as_slice(&'a self) -> &'a str { &*self.name } - - pub fn name(self) -> Cow<'a, str> { - self.name - } } /// Each instance of a type that implements `Label` maps to a @@ -484,10 +480,6 @@ impl<'a> LabelText<'a> { LabelStr(s.into()) } - pub fn escaped>>(s: S) -> LabelText<'a> { - EscStr(s.into()) - } - pub fn html>>(s: S) -> LabelText<'a> { HtmlStr(s.into()) } @@ -543,11 +535,6 @@ impl<'a> LabelText<'a> { } } - /// Puts `prefix` on a line above this label, with a blank line separator. - pub fn prefix_line(self, prefix: LabelText<'_>) -> LabelText<'static> { - prefix.suffix_line(self) - } - /// Puts `suffix` on a line below this label, with a blank line separator. pub fn suffix_line(self, suffix: LabelText<'_>) -> LabelText<'static> { let mut prefix = self.pre_escaped_content().into_owned(); @@ -602,11 +589,6 @@ pub enum RenderOption { DarkTheme, } -/// Returns vec holding all the default render options. -pub fn default_options() -> Vec { - vec![] -} - /// Renders directed graph `g` into the writer `w` in DOT syntax. /// (Simple wrapper around `render_opts` that passes a default set of options.) pub fn render<'a, N, E, G, W>(g: &'a G, w: &mut W) -> io::Result<()> diff --git a/compiler/rustc_graphviz/src/tests.rs b/compiler/rustc_graphviz/src/tests.rs index 70b8197f5ef..a297bac86c4 100644 --- a/compiler/rustc_graphviz/src/tests.rs +++ b/compiler/rustc_graphviz/src/tests.rs @@ -111,7 +111,7 @@ impl<'a> Labeller<'a> for LabelledGraph { fn node_label(&'a self, n: &Node) -> LabelText<'a> { match self.node_labels[*n] { Some(l) => LabelStr(l.into()), - None => LabelStr(id_name(n).name()), + None => LabelStr(id_name(n).name), } } fn edge_label(&'a self, e: &&'a Edge) -> LabelText<'a> { diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 3266dfac702..0f77de9fb25 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -87,6 +87,7 @@ impl DefPathTable { hash } + /// Used by librustdoc for fake DefIds. pub fn num_def_ids(&self) -> usize { self.index_to_key.len() } @@ -319,12 +320,6 @@ impl Definitions { self.table.def_path_hash(id.local_def_index) } - #[inline] - pub fn def_path_hash_to_def_id(&self, def_path_hash: DefPathHash) -> LocalDefId { - let local_def_index = self.table.def_path_hash_to_index[&def_path_hash]; - LocalDefId { local_def_index } - } - /// Returns the path from the crate root to `index`. The root /// nodes are not included in the path (i.e., this will be an /// empty vector for the crate root). For an inlined item, this diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index d03584d49a5..aaf15c60f1e 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1,5 +1,5 @@ // ignore-tidy-filelength -use crate::def::{CtorKind, DefKind, Namespace, Res}; +use crate::def::{CtorKind, DefKind, Res}; use crate::def_id::DefId; crate use crate::hir_id::HirId; use crate::{itemlikevisit, LangItem}; @@ -2118,15 +2118,6 @@ pub enum ImplItemKind<'hir> { TyAlias(&'hir Ty<'hir>), } -impl ImplItemKind<'_> { - pub fn namespace(&self) -> Namespace { - match self { - ImplItemKind::TyAlias(..) => Namespace::TypeNS, - ImplItemKind::Const(..) | ImplItemKind::Fn(..) => Namespace::ValueNS, - } - } -} - // The name of the associated type for `Fn` return types. pub const FN_OUTPUT_NAME: Symbol = sym::Output; @@ -2215,6 +2206,9 @@ impl PrimTy { Self::Str, ]; + /// [`PrimTy::name`], but returns a &str instead of a symbol. + /// + /// Used by rustdoc. pub fn name_str(self) -> &'static str { match self { PrimTy::Int(i) => i.name_str(), diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index e0b3d9026a0..e24eb5e4490 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -1,5 +1,4 @@ use crate::def_id::{LocalDefId, CRATE_DEF_INDEX}; -use rustc_index::vec::IndexVec; use std::fmt; /// Uniquely identifies a node in the HIR of the current crate. It is @@ -62,69 +61,3 @@ pub const CRATE_HIR_ID: HirId = HirId { owner: LocalDefId { local_def_index: CRATE_DEF_INDEX }, local_id: ItemLocalId::from_u32(0), }; - -#[derive(Clone, Default, Debug, Encodable, Decodable)] -pub struct HirIdVec { - map: IndexVec>, -} - -impl HirIdVec { - pub fn push_owner(&mut self, id: LocalDefId) { - self.map.ensure_contains_elem(id, IndexVec::new); - } - - pub fn push(&mut self, id: HirId, value: T) { - if id.local_id == ItemLocalId::from_u32(0) { - self.push_owner(id.owner); - } - let submap = &mut self.map[id.owner]; - let _ret_id = submap.push(value); - debug_assert_eq!(_ret_id, id.local_id); - } - - pub fn push_sparse(&mut self, id: HirId, value: T) - where - T: Default, - { - self.map.ensure_contains_elem(id.owner, IndexVec::new); - let submap = &mut self.map[id.owner]; - let i = id.local_id.index(); - let len = submap.len(); - if i >= len { - submap.extend(std::iter::repeat_with(T::default).take(i - len + 1)); - } - submap[id.local_id] = value; - } - - pub fn get(&self, id: HirId) -> Option<&T> { - self.map.get(id.owner)?.get(id.local_id) - } - - pub fn get_owner(&self, id: LocalDefId) -> &IndexVec { - &self.map[id] - } - - pub fn iter(&self) -> impl Iterator { - self.map.iter().flat_map(|la| la.iter()) - } - - pub fn iter_enumerated(&self) -> impl Iterator { - self.map.iter_enumerated().flat_map(|(owner, la)| { - la.iter_enumerated().map(move |(local_id, attr)| (HirId { owner, local_id }, attr)) - }) - } -} - -impl std::ops::Index for HirIdVec { - type Output = T; - - fn index(&self, id: HirId) -> &T { - &self.map[id.owner][id.local_id] - } -} - -impl std::ops::IndexMut for HirIdVec { - fn index_mut(&mut self, id: HirId) -> &mut T { - &mut self.map[id.owner][id.local_id] - } -} diff --git a/compiler/rustc_hir/src/pat_util.rs b/compiler/rustc_hir/src/pat_util.rs index 9e0a6aae242..28529affd5d 100644 --- a/compiler/rustc_hir/src/pat_util.rs +++ b/compiler/rustc_hir/src/pat_util.rs @@ -89,26 +89,6 @@ impl hir::Pat<'_> { }) } - /// Checks if the pattern contains any patterns that bind something to - /// an ident, e.g., `foo`, or `Foo(foo)` or `foo @ Bar(..)`. - pub fn contains_bindings(&self) -> bool { - self.satisfies(|p| matches!(p.kind, PatKind::Binding(..))) - } - - /// Checks if the pattern satisfies the given predicate on some sub-pattern. - fn satisfies(&self, pred: impl Fn(&hir::Pat<'_>) -> bool) -> bool { - let mut satisfies = false; - self.walk_short(|p| { - if pred(p) { - satisfies = true; - false // Found one, can short circuit now. - } else { - true - } - }); - satisfies - } - pub fn simple_ident(&self) -> Option { match self.kind { PatKind::Binding( diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 7eeda6013ed..89d56ed3174 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -221,10 +221,6 @@ pub fn bounds_to_string<'b>(bounds: impl IntoIterator) -> String { - to_string(NO_ANN, |s| s.print_param(arg)) -} - pub fn ty_to_string(ty: &hir::Ty<'_>) -> String { to_string(NO_ANN, |s| s.print_type(ty)) } @@ -1701,21 +1697,10 @@ impl<'a> State<'a> { } } - pub fn print_usize(&mut self, i: usize) { - self.s.word(i.to_string()) - } - pub fn print_name(&mut self, name: Symbol) { self.print_ident(Ident::with_dummy_span(name)) } - pub fn print_for_decl(&mut self, loc: &hir::Local<'_>, coll: &hir::Expr<'_>) { - self.print_local_decl(loc); - self.s.space(); - self.word_space("in"); - self.print_expr(coll) - } - pub fn print_path(&mut self, path: &hir::Path<'_>, colons_before_params: bool) { self.maybe_print_comment(path.span.lo()); @@ -2430,24 +2415,6 @@ impl<'a> State<'a> { } } - pub fn print_opt_abi_and_extern_if_nondefault(&mut self, opt_abi: Option) { - match opt_abi { - Some(Abi::Rust) => {} - Some(abi) => { - self.word_nbsp("extern"); - self.word_nbsp(abi.to_string()) - } - None => {} - } - } - - pub fn print_extern_opt_abi(&mut self, opt_abi: Option) { - if let Some(abi) = opt_abi { - self.word_nbsp("extern"); - self.word_nbsp(abi.to_string()) - } - } - pub fn print_fn_header_info(&mut self, header: hir::FnHeader, vis: &hir::Visibility<'_>) { self.s.word(visibility_qualified(vis, "")); diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index cb089a728ee..91b7221f205 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -74,16 +74,6 @@ const BASE_STRUCT: &[&str] = &[label_strs::generics_of, label_strs::predicates_of, label_strs::type_of]; /// Trait definition `DepNode`s. -const BASE_TRAIT_DEF: &[&str] = &[ - label_strs::associated_item_def_ids, - label_strs::generics_of, - label_strs::object_safety_violations, - label_strs::predicates_of, - label_strs::specialization_graph_of, - label_strs::trait_def, - label_strs::trait_impls_of, -]; - /// Extra `DepNode`s for functions and methods. const EXTRA_ASSOCIATED: &[&str] = &[label_strs::associated_item]; @@ -118,10 +108,6 @@ const LABELS_IMPL: &[&[&str]] = &[BASE_HIR, BASE_IMPL]; /// Abstract data type (struct, enum, union) `DepNode`s. const LABELS_ADT: &[&[&str]] = &[BASE_HIR, BASE_STRUCT]; -/// Trait definition `DepNode`s. -#[allow(dead_code)] -const LABELS_TRAIT: &[&[&str]] = &[BASE_HIR, BASE_TRAIT_DEF]; - // FIXME: Struct/Enum/Unions Fields (there is currently no way to attach these) // // Fields are kind of separate from their containers, as they can change independently from diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 7b18f4d0ff6..9fb045e8e40 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1266,15 +1266,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.resolve_vars_if_possible(t).to_string() } - pub fn tys_to_string(&self, ts: &[Ty<'tcx>]) -> String { - let tstrs: Vec = ts.iter().map(|t| self.ty_to_string(*t)).collect(); - format!("({})", tstrs.join(", ")) - } - - pub fn trait_ref_to_string(&self, t: ty::TraitRef<'tcx>) -> String { - self.resolve_vars_if_possible(t).print_only_trait_path().to_string() - } - /// If `TyVar(vid)` resolves to a type, return that type. Else, return the /// universe index of `TyVar(vid)`. pub fn probe_ty_var(&self, vid: TyVid) -> Result, ty::UniverseIndex> { @@ -1704,14 +1695,6 @@ impl<'tcx> TypeTrace<'tcx> { ) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), values: Consts(ExpectedFound::new(a_is_expected, a, b)) } } - - pub fn dummy(tcx: TyCtxt<'tcx>) -> TypeTrace<'tcx> { - let err = tcx.ty_error(); - TypeTrace { - cause: ObligationCause::dummy(), - values: Types(ExpectedFound { expected: err, found: err }), - } - } } impl<'tcx> SubregionOrigin<'tcx> { diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index 1a9e20e79fe..9e04773c5fa 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -92,11 +92,6 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> { &self.region_bound_pairs_map } - /// Returns ownership of the `free_region_map`. - pub fn into_free_region_map(self) -> FreeRegionMap<'tcx> { - self.free_region_map - } - /// This is a hack to support the old-skool regionck, which /// processes region constraints from the main function and the /// closure together. In that context, when we enter a closure, we diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 16d86e6243d..3e2978fd170 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -186,28 +186,6 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { } } } - - /// Processes a single ad-hoc region obligation that was not - /// registered in advance. - pub fn type_must_outlive( - &self, - region_bound_pairs: &RegionBoundPairs<'tcx>, - implicit_region_bound: Option>, - param_env: ty::ParamEnv<'tcx>, - origin: infer::SubregionOrigin<'tcx>, - ty: Ty<'tcx>, - region: ty::Region<'tcx>, - ) { - let outlives = &mut TypeOutlives::new( - self, - self.tcx, - region_bound_pairs, - implicit_region_bound, - param_env, - ); - let ty = self.resolve_vars_if_possible(ty); - outlives.type_must_outlive(origin, ty, region); - } } /// The `TypeOutlives` struct has the job of "lowering" a `T: 'a` diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 2902c41a6bc..9ffcddfae99 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -309,31 +309,6 @@ pub struct RegionSnapshot { any_unifications: bool, } -/// When working with placeholder regions, we often wish to find all of -/// the regions that are either reachable from a placeholder region, or -/// which can reach a placeholder region, or both. We call such regions -/// *tainted* regions. This struct allows you to decide what set of -/// tainted regions you want. -#[derive(Debug)] -pub struct TaintDirections { - incoming: bool, - outgoing: bool, -} - -impl TaintDirections { - pub fn incoming() -> Self { - TaintDirections { incoming: true, outgoing: false } - } - - pub fn outgoing() -> Self { - TaintDirections { incoming: false, outgoing: true } - } - - pub fn both() -> Self { - TaintDirections { incoming: true, outgoing: true } - } -} - impl<'tcx> RegionConstraintStorage<'tcx> { pub fn new() -> Self { Self::default() @@ -472,11 +447,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { self.var_infos[vid].universe } - /// Returns the origin for the given variable. - pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin { - self.var_infos[vid].origin - } - fn add_constraint(&mut self, constraint: Constraint<'tcx>, origin: SubregionOrigin<'tcx>) { // cannot add constraints once regions are resolved debug!("RegionConstraintCollector: add_constraint({:?})", constraint); @@ -795,16 +765,6 @@ impl<'tcx> VerifyBound<'tcx> { VerifyBound::AnyBound(vec![self, vb]) } } - - pub fn and(self, vb: VerifyBound<'tcx>) -> VerifyBound<'tcx> { - if self.must_hold() && vb.must_hold() { - self - } else if self.cannot_hold() && vb.cannot_hold() { - self - } else { - VerifyBound::AllBounds(vec![self, vb]) - } - } } impl<'tcx> RegionConstraintData<'tcx> { diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 35b97fff3da..49fb2d7993c 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -146,9 +146,7 @@ impl<'tcx> TypeVariableValue<'tcx> { } } -pub(crate) struct Instantiate { - vid: ty::TyVid, -} +pub(crate) struct Instantiate {} pub(crate) struct Delegate; @@ -224,7 +222,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> { // Hack: we only need this so that `types_escaping_snapshot` // can see what has been unified; see the Delegate impl for // more details. - self.undo_log.push(Instantiate { vid }); + self.undo_log.push(Instantiate {}); } /// Creates a new type variable. @@ -346,56 +344,6 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> { ) } - /// Finds the set of type variables that existed *before* `s` - /// but which have only been unified since `s` started, and - /// return the types with which they were unified. So if we had - /// a type variable `V0`, then we started the snapshot, then we - /// created a type variable `V1`, unified `V0` with `T0`, and - /// unified `V1` with `T1`, this function would return `{T0}`. - pub fn types_escaping_snapshot(&mut self, s: &super::Snapshot<'tcx>) -> Vec> { - let mut new_elem_threshold = u32::MAX; - let mut escaping_types = Vec::new(); - let actions_since_snapshot = self.undo_log.actions_since_snapshot(s); - debug!("actions_since_snapshot.len() = {}", actions_since_snapshot.len()); - for i in 0..actions_since_snapshot.len() { - let actions_since_snapshot = self.undo_log.actions_since_snapshot(s); - match actions_since_snapshot[i] { - super::UndoLog::TypeVariables(UndoLog::Values(sv::UndoLog::NewElem(index))) => { - // if any new variables were created during the - // snapshot, remember the lower index (which will - // always be the first one we see). Note that this - // action must precede those variables being - // specified. - new_elem_threshold = cmp::min(new_elem_threshold, index as u32); - debug!("NewElem({}) new_elem_threshold={}", index, new_elem_threshold); - } - - super::UndoLog::TypeVariables(UndoLog::Values(sv::UndoLog::Other( - Instantiate { vid, .. }, - ))) => { - if vid.index < new_elem_threshold { - // quick check to see if this variable was - // created since the snapshot started or not. - let mut eq_relations = ut::UnificationTable::with_log( - &mut self.storage.eq_relations, - &mut *self.undo_log, - ); - let escaping_type = match eq_relations.probe_value(vid) { - TypeVariableValue::Unknown { .. } => bug!(), - TypeVariableValue::Known { value } => value, - }; - escaping_types.push(escaping_type); - } - debug!("SpecifyVar({:?}) new_elem_threshold={}", vid, new_elem_threshold); - } - - _ => {} - } - } - - escaping_types - } - /// Returns indices of all variables that are not yet /// instantiated. pub fn unsolved_variables(&mut self) -> Vec { diff --git a/compiler/rustc_infer/src/infer/undo_log.rs b/compiler/rustc_infer/src/infer/undo_log.rs index 4be0e7948f7..f41e872e004 100644 --- a/compiler/rustc_infer/src/infer/undo_log.rs +++ b/compiler/rustc_infer/src/infer/undo_log.rs @@ -165,10 +165,6 @@ impl<'tcx> InferCtxtInner<'tcx> { } impl<'tcx> InferCtxtUndoLogs<'tcx> { - pub fn actions_since_snapshot(&self, snapshot: &Snapshot<'tcx>) -> &[UndoLog<'tcx>] { - &self.logs[snapshot.undo_len..] - } - pub fn start_snapshot(&mut self) -> Snapshot<'tcx> { self.num_open_snapshots += 1; Snapshot { undo_len: self.logs.len(), _marker: PhantomData } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 1a8bbb67cfe..218248e715b 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -481,7 +481,7 @@ fn has_doc(sess: &Session, attr: &ast::Attribute) -> bool { return false; } - if attr.is_value_str() { + if attr.value_str().is_some() { return true; } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index cf2f1489e02..e4403f879ff 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -177,6 +177,7 @@ impl LintStore { self.early_passes.push(Box::new(pass)); } + /// Used by clippy. pub fn register_pre_expansion_pass( &mut self, pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync, @@ -862,6 +863,8 @@ impl<'tcx> LateContext<'tcx> { /// // The given `def_id` is that of an `Option` type /// } /// ``` + /// + /// Used by clippy, but should be replaced by diagnostic items eventually. pub fn match_def_path(&self, def_id: DefId, path: &[Symbol]) -> bool { let names = self.get_def_path(def_id); diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index a332c300787..863023fa7b5 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -564,10 +564,6 @@ impl<'s> LintLevelsBuilder<'s> { self.id_to_set.insert(id, self.cur); } - pub fn build(self) -> LintLevelSets { - self.sets - } - pub fn build_map(self) -> LintLevelMap { LintLevelMap { sets: self.sets, id_to_set: self.id_to_set } } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 9d00f0715a0..9e763befe29 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -550,24 +550,6 @@ impl<'hir> Map<'hir> { ParentHirIterator { current_id, map: self } } - /// Checks if the node is an argument. An argument is a local variable whose - /// immediate parent is an item or a closure. - pub fn is_argument(&self, id: HirId) -> bool { - match self.find(id) { - Some(Node::Binding(_)) => (), - _ => return false, - } - matches!( - self.find(self.get_parent_node(id)), - Some( - Node::Item(_) - | Node::TraitItem(_) - | Node::ImplItem(_) - | Node::Expr(Expr { kind: ExprKind::Closure(..), .. }), - ) - ) - } - /// Checks if the node is left-hand side of an assignment. pub fn is_lhs(&self, id: HirId) -> bool { match self.find(self.get_parent_node(id)) { @@ -779,17 +761,6 @@ impl<'hir> Map<'hir> { } } - pub fn expect_variant_data(&self, id: HirId) -> &'hir VariantData<'hir> { - match self.find(id) { - Some( - Node::Ctor(vd) - | Node::Item(Item { kind: ItemKind::Struct(vd, _) | ItemKind::Union(vd, _), .. }), - ) => vd, - Some(Node::Variant(variant)) => &variant.data, - _ => bug!("expected struct or variant, found {}", self.node_to_string(id)), - } - } - pub fn expect_variant(&self, id: HirId) -> &'hir Variant<'hir> { match self.find(id) { Some(Node::Variant(variant)) => variant, diff --git a/compiler/rustc_middle/src/ich/hcx.rs b/compiler/rustc_middle/src/ich/hcx.rs index cf29d21927c..b2fef731b7e 100644 --- a/compiler/rustc_middle/src/ich/hcx.rs +++ b/compiler/rustc_middle/src/ich/hcx.rs @@ -119,11 +119,6 @@ impl<'a> StableHashingContext<'a> { Self::new_with_or_without_spans(sess, krate, definitions, cstore, always_ignore_spans) } - #[inline] - pub fn sess(&self) -> &'a Session { - self.sess - } - #[inline] pub fn while_hashing_hir_bodies(&mut self, hash_bodies: bool, f: F) { let prev_hash_bodies = self.hash_bodies; diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 8a13ceec221..7ed4cbf034f 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -228,20 +228,12 @@ impl Certainty { Certainty::Ambiguous => false, } } - - pub fn is_ambiguous(&self) -> bool { - !self.is_proven() - } } impl<'tcx, R> QueryResponse<'tcx, R> { pub fn is_proven(&self) -> bool { self.certainty.is_proven() } - - pub fn is_ambiguous(&self) -> bool { - !self.is_proven() - } } impl<'tcx, R> Canonical<'tcx, QueryResponse<'tcx, R>> { diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index 8318bdefc8e..641cf23781e 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -97,13 +97,6 @@ impl<'tcx> ConstVariableValue<'tcx> { ConstVariableValue::Known { value } => Some(value), } } - - pub fn is_unknown(&self) -> bool { - match *self { - ConstVariableValue::Unknown { .. } => true, - ConstVariableValue::Known { .. } => false, - } - } } #[derive(Copy, Clone, Debug)] diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index eb48198991c..5440e63543d 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -430,6 +430,8 @@ impl ScopeTree { /// Returns `true` if `subscope` is equal to or is lexically nested inside `superscope`, and /// `false` otherwise. + /// + /// Used by clippy. pub fn is_subscope_of(&self, subscope: Scope, superscope: Scope) -> bool { let mut s = subscope; debug!("is_subscope_of({:?}, {:?})", subscope, superscope); diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 89ca8eed39a..fc9a2970e00 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -29,12 +29,6 @@ pub enum StabilityLevel { Stable, } -impl StabilityLevel { - pub fn from_attr_level(level: &attr::StabilityLevel) -> Self { - if level.is_stable() { Stable } else { Unstable } - } -} - /// An entry in the `depr_map`. #[derive(Clone, HashStable, Debug)] pub struct DeprecationEntry { diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index eae02a8cbfc..ad48b236a9a 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -117,17 +117,9 @@ impl CoverageKind { } } - pub fn is_counter(&self) -> bool { - matches!(self, Self::Counter { .. }) - } - pub fn is_expression(&self) -> bool { matches!(self, Self::Expression { .. }) } - - pub fn is_unreachable(&self) -> bool { - *self == Self::Unreachable - } } impl Debug for CoverageKind { diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 5172dfd041a..888777a9418 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -307,16 +307,6 @@ impl<'tcx, Tag> Scalar { .unwrap_or_else(|| bug!("Signed value {:#x} does not fit in {} bits", i, size.bits())) } - #[inline] - pub fn from_i8(i: i8) -> Self { - Self::from_int(i, Size::from_bits(8)) - } - - #[inline] - pub fn from_i16(i: i16) -> Self { - Self::from_int(i, Size::from_bits(16)) - } - #[inline] pub fn from_i32(i: i32) -> Self { Self::from_int(i, Size::from_bits(32)) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 807d6394800..abca2ecdb06 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -379,24 +379,6 @@ impl<'tcx> Body<'tcx> { } } - /// Returns an iterator over all temporaries. - #[inline] - pub fn temps_iter<'a>(&'a self) -> impl Iterator + 'a { - (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| { - let local = Local::new(index); - if self.local_decls[local].is_user_variable() { None } else { Some(local) } - }) - } - - /// Returns an iterator over all user-declared locals. - #[inline] - pub fn vars_iter<'a>(&'a self) -> impl Iterator + 'a { - (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| { - let local = Local::new(index); - self.local_decls[local].is_user_variable().then_some(local) - }) - } - /// Returns an iterator over all user-declared mutable locals. #[inline] pub fn mut_vars_iter<'a>(&'a self) -> impl Iterator + 'a { diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index 36e277d1a88..725448584dd 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -264,10 +264,6 @@ impl<'a, 'tcx> ReversePostorder<'a, 'tcx> { ReversePostorder { body, blocks, idx: len } } - - pub fn reset(&mut self) { - self.idx = self.blocks.len(); - } } pub fn reverse_postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> ReversePostorder<'a, 'tcx> { diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index be248ccabda..32b4cd665d0 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -1247,12 +1247,6 @@ impl PlaceContext { matches!(self, PlaceContext::MutatingUse(..)) } - /// Returns `true` if this place context represents a use that does not change the value. - #[inline] - pub fn is_nonmutating_use(&self) -> bool { - matches!(self, PlaceContext::NonMutatingUse(..)) - } - /// Returns `true` if this place context represents a use. #[inline] pub fn is_use(&self) -> bool { diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index f9cadb3bb2d..eac3ab7282f 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -44,24 +44,12 @@ pub mod type_op { pub b: Ty<'tcx>, } - impl<'tcx> Eq<'tcx> { - pub fn new(a: Ty<'tcx>, b: Ty<'tcx>) -> Self { - Self { a, b } - } - } - #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] pub struct Subtype<'tcx> { pub sub: Ty<'tcx>, pub sup: Ty<'tcx>, } - impl<'tcx> Subtype<'tcx> { - pub fn new(sub: Ty<'tcx>, sup: Ty<'tcx>) -> Self { - Self { sub, sup } - } - } - #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] pub struct ProvePredicate<'tcx> { pub predicate: Predicate<'tcx>, diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index c31a882c272..52cb6b301b0 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -6,7 +6,6 @@ use crate::ty; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::lang_items::LangItem; use rustc_span::Span; use super::{Ty, TyCtxt}; @@ -113,14 +112,6 @@ impl<'tcx> ClosureKind { // This is the initial value used when doing upvar inference. pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn; - pub fn trait_did(&self, tcx: TyCtxt<'tcx>) -> DefId { - match *self { - ClosureKind::Fn => tcx.require_lang_item(LangItem::Fn, None), - ClosureKind::FnMut => tcx.require_lang_item(LangItem::FnMut, None), - ClosureKind::FnOnce => tcx.require_lang_item(LangItem::FnOnce, None), - } - } - /// Returns `true` if a type that impls this closure kind /// must also implement `other`. pub fn extends(self, other: ty::ClosureKind) -> bool { @@ -377,12 +368,4 @@ impl BorrowKind { UniqueImmBorrow => hir::Mutability::Mut, } } - - pub fn to_user_str(&self) -> &'static str { - match *self { - MutBorrow => "mutable", - ImmBorrow => "immutable", - UniqueImmBorrow => "uniquely immutable", - } - } } diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 3225efd05e4..59e1695cdb9 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -188,7 +188,7 @@ pub trait TyDecoder<'tcx>: Decoder { } #[inline] -pub fn decode_arena_allocable<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>( +fn decode_arena_allocable<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>( decoder: &mut D, ) -> Result<&'tcx T, D::Error> where @@ -198,7 +198,7 @@ where } #[inline] -pub fn decode_arena_allocable_slice<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>( +fn decode_arena_allocable_slice<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>( decoder: &mut D, ) -> Result<&'tcx [T], D::Error> where diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8fdae695ceb..da3bdc5c721 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -14,7 +14,7 @@ use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstValue, Scalar}; use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted}; use crate::traits; -use crate::ty::query::{self, OnDiskCache, TyCtxtAt}; +use crate::ty::query::{self, OnDiskCache}; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts}; use crate::ty::TyKind::*; use crate::ty::{ @@ -2288,11 +2288,6 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Not }) } - #[inline] - pub fn mk_nil_ptr(self) -> Ty<'tcx> { - self.mk_imm_ptr(self.mk_unit()) - } - #[inline] pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> { self.mk_ty(Array(ty, ty::Const::from_usize(self, n))) @@ -2655,21 +2650,6 @@ impl<'tcx> TyCtxt<'tcx> { } } -impl TyCtxtAt<'tcx> { - /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used. - #[track_caller] - pub fn ty_error(self) -> Ty<'tcx> { - self.tcx.ty_error_with_message(self.span, "TyKind::Error constructed but no error reported") - } - - /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to - /// ensure it gets used. - #[track_caller] - pub fn ty_error_with_message(self, msg: &str) -> Ty<'tcx> { - self.tcx.ty_error_with_message(self.span, msg) - } -} - pub trait InternAs { type Output; fn intern_with(self, f: F) -> Self::Output diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index ed10a156622..6a1ea6df3f0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -618,22 +618,12 @@ pub struct ProjectionPredicate<'tcx> { pub type PolyProjectionPredicate<'tcx> = Binder>; impl<'tcx> PolyProjectionPredicate<'tcx> { - /// Returns the `DefId` of the associated item being projected. - pub fn item_def_id(&self) -> DefId { - self.skip_binder().projection_ty.item_def_id - } - /// Returns the `DefId` of the trait of the associated item being projected. #[inline] pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId { self.skip_binder().projection_ty.trait_def_id(tcx) } - #[inline] - pub fn projection_self_ty(&self) -> Binder> { - self.map_bound(|predicate| predicate.projection_ty.self_ty()) - } - /// Get the [PolyTraitRef] required for this projection to be well formed. /// Note that for generic associated types the predicates of the associated /// type also need to be checked. @@ -1039,10 +1029,6 @@ impl WithOptConstParam { None } - pub fn expect_local(self) -> WithOptConstParam { - self.as_local().unwrap() - } - pub fn is_local(self) -> bool { self.did.is_local() } @@ -1222,11 +1208,6 @@ pub trait WithConstness: Sized { ConstnessAnd { constness, value: self } } - #[inline] - fn with_const(self) -> ConstnessAnd { - self.with_constness(Constness::Const) - } - #[inline] fn without_const(self) -> ConstnessAnd { self.with_constness(Constness::NotConst) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index e78e928398f..b42375aec6e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -977,22 +977,6 @@ impl Binder { Binder(value) } - /// Wraps `value` in a binder without actually binding any currently - /// unbound variables. - /// - /// Note that this will shift all debrujin indices of escaping bound variables - /// by 1 to avoid accidential captures. - pub fn wrap_nonbinding(tcx: TyCtxt<'tcx>, value: T) -> Binder - where - T: TypeFoldable<'tcx>, - { - if value.has_escaping_bound_vars() { - Binder::bind(super::fold::shift_vars(tcx, value, 1)) - } else { - Binder::dummy(value) - } - } - /// Skips the binder and returns the "bound" value. This is a /// risky thing to do because it's easy to get confused about /// De Bruijn indices and the like. It is usually better to @@ -1074,20 +1058,6 @@ impl Binder { { Binder(f(self.0, u.0)) } - - /// Splits the contents into two things that share the same binder - /// level as the original, returning two distinct binders. - /// - /// `f` should consider bound regions at depth 1 to be free, and - /// anything it produces with bound regions at depth 1 will be - /// bound in the resulting return values. - pub fn split(self, f: F) -> (Binder, Binder) - where - F: FnOnce(T) -> (U, V), - { - let (u, v) = f(self.0); - (Binder(u), Binder(v)) - } } impl Binder> { @@ -1157,18 +1127,6 @@ pub struct GenSig<'tcx> { pub type PolyGenSig<'tcx> = Binder>; -impl<'tcx> PolyGenSig<'tcx> { - pub fn resume_ty(&self) -> ty::Binder> { - self.map_bound_ref(|sig| sig.resume_ty) - } - pub fn yield_ty(&self) -> ty::Binder> { - self.map_bound_ref(|sig| sig.yield_ty) - } - pub fn return_ty(&self) -> ty::Binder> { - self.map_bound_ref(|sig| sig.return_ty) - } -} - /// Signature of a function type, which we have arbitrarily /// decided to use to refer to the input/output types. /// @@ -1248,10 +1206,6 @@ impl<'tcx> ParamTy { ParamTy { index, name } } - pub fn for_self() -> ParamTy { - ParamTy::new(0, kw::SelfUpper) - } - pub fn for_def(def: &ty::GenericParamDef) -> ParamTy { ParamTy::new(def.index, def.name) } @@ -1269,7 +1223,7 @@ pub struct ParamConst { pub name: Symbol, } -impl<'tcx> ParamConst { +impl ParamConst { pub fn new(index: u32, name: Symbol) -> ParamConst { ParamConst { index, name } } @@ -1277,10 +1231,6 @@ impl<'tcx> ParamConst { pub fn for_def(def: &ty::GenericParamDef) -> ParamConst { ParamConst::new(def.index, def.name) } - - pub fn to_const(self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> { - tcx.mk_const_param(self.index, self.name, ty) - } } pub type Region<'tcx> = &'tcx RegionKind; @@ -1580,35 +1530,6 @@ impl RegionKind { } } - /// Adjusts any De Bruijn indices so as to make `to_binder` the - /// innermost binder. That is, if we have something bound at `to_binder`, - /// it will now be bound at INNERMOST. This is an appropriate thing to do - /// when moving a region out from inside binders: - /// - /// ``` - /// for<'a> fn(for<'b> for<'c> fn(&'a u32), _) - /// // Binder: D3 D2 D1 ^^ - /// ``` - /// - /// Here, the region `'a` would have the De Bruijn index D3, - /// because it is the bound 3 binders out. However, if we wanted - /// to refer to that region `'a` in the second argument (the `_`), - /// those two binders would not be in scope. In that case, we - /// might invoke `shift_out_to_binder(D3)`. This would adjust the - /// De Bruijn index of `'a` to D1 (the innermost binder). - /// - /// If we invoke `shift_out_to_binder` and the region is in fact - /// bound by one of the binders we are shifting out of, that is an - /// error (and should fail an assertion failure). - pub fn shifted_out_to_binder(&self, to_binder: ty::DebruijnIndex) -> RegionKind { - match *self { - ty::ReLateBound(debruijn, r) => { - ty::ReLateBound(debruijn.shifted_out_to_binder(to_binder), r) - } - r => r, - } - } - pub fn type_flags(&self) -> TypeFlags { let mut flags = TypeFlags::empty(); diff --git a/compiler/rustc_mir/src/dataflow/framework/cursor.rs b/compiler/rustc_mir/src/dataflow/framework/cursor.rs index 4942bed656c..c000e49c14b 100644 --- a/compiler/rustc_mir/src/dataflow/framework/cursor.rs +++ b/compiler/rustc_mir/src/dataflow/framework/cursor.rs @@ -64,10 +64,6 @@ where } } - pub fn body(&self) -> &'mir mir::Body<'tcx> { - self.body - } - /// Returns the underlying `Results`. pub fn results(&self) -> &Results<'tcx, A> { &self.results.borrow() diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 149a9f81ea0..3f20a83fc25 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -226,16 +226,6 @@ impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> { } impl<'mir, 'tcx, Tag, Extra> Frame<'mir, 'tcx, Tag, Extra> { - /// Get the current location within the Frame. - /// - /// If this is `Err`, we are not currently executing any particular statement in - /// this frame (can happen e.g. during frame initialization, and during unwinding on - /// frames without cleanup code). - /// We basically abuse `Result` as `Either`. - pub fn current_loc(&self) -> Result { - self.loc - } - /// Return the `SourceInfo` of the current instruction. pub fn current_source_info(&self) -> Option<&mir::SourceInfo> { self.loc.ok().map(|loc| self.body.source_info(loc)) @@ -459,11 +449,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty.size.truncate(value) } - #[inline] - pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { - ty.is_sized(self.tcx, self.param_env) - } - #[inline] pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { ty.is_freeze(self.tcx, self.param_env) diff --git a/compiler/rustc_mir/src/interpret/machine.rs b/compiler/rustc_mir/src/interpret/machine.rs index 65869f95639..593a90cb54d 100644 --- a/compiler/rustc_mir/src/interpret/machine.rs +++ b/compiler/rustc_mir/src/interpret/machine.rs @@ -71,11 +71,6 @@ pub trait AllocMap { fn get(&self, k: K) -> Option<&V> { self.get_or(k, || Err(())).ok() } - - /// Mutable lookup. - fn get_mut(&mut self, k: K) -> Option<&mut V> { - self.get_mut_or(k, || Err(())).ok() - } } /// Methods of this trait signifies a point where CTFE evaluation would fail diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index c70b57e631a..0f436fb3b03 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -77,14 +77,6 @@ impl<'tcx, Tag> Immediate { pub fn to_scalar(self) -> InterpResult<'tcx, Scalar> { self.to_scalar_or_uninit().check_init() } - - #[inline] - pub fn to_scalar_pair(self) -> InterpResult<'tcx, (Scalar, Scalar)> { - match self { - Immediate::Scalar(..) => bug!("Got a thin pointer where a scalar pair was expected"), - Immediate::ScalarPair(a, b) => Ok((a.check_init()?, b.check_init()?)), - } - } } // ScalarPair needs a type to interpret, so we often have an immediate and a type together diff --git a/compiler/rustc_mir/src/util/generic_graphviz.rs b/compiler/rustc_mir/src/util/generic_graphviz.rs index fd41e282266..21c18b28e25 100644 --- a/compiler/rustc_mir/src/util/generic_graphviz.rs +++ b/compiler/rustc_mir/src/util/generic_graphviz.rs @@ -40,22 +40,6 @@ impl< } } - pub fn new_subgraph( - graph: &'a G, - graphviz_name: &str, - node_content_fn: NodeContentFn, - edge_labels_fn: EdgeLabelsFn, - ) -> Self { - Self { - graph, - is_subgraph: true, - graphviz_name: graphviz_name.to_owned(), - graph_label: None, - node_content_fn, - edge_labels_fn, - } - } - pub fn set_graph_label(&mut self, graph_label: &str) { self.graph_label = Some(graph_label.to_owned()); } diff --git a/compiler/rustc_mir/src/util/patch.rs b/compiler/rustc_mir/src/util/patch.rs index 6566a996fe4..374bc19c711 100644 --- a/compiler/rustc_mir/src/util/patch.rs +++ b/compiler/rustc_mir/src/util/patch.rs @@ -117,10 +117,6 @@ impl<'tcx> MirPatch<'tcx> { self.add_statement(loc, StatementKind::Assign(box (place, rv))); } - pub fn make_nop(&mut self, loc: Location) { - self.make_nop.push(loc); - } - pub fn apply(self, body: &mut Body<'tcx>) { debug!("MirPatch: make nops at: {:?}", self.make_nop); for loc in self.make_nop { diff --git a/compiler/rustc_query_system/src/cache.rs b/compiler/rustc_query_system/src/cache.rs index c6dc7b4fe28..d592812f79b 100644 --- a/compiler/rustc_query_system/src/cache.rs +++ b/compiler/rustc_query_system/src/cache.rs @@ -3,7 +3,6 @@ use crate::dep_graph::{DepContext, DepNodeIndex}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::HashMapExt; use rustc_data_structures::sync::Lock; use std::hash::Hash; @@ -34,13 +33,6 @@ impl Cache { pub fn insert(&self, key: Key, dep_node: DepNodeIndex, value: Value) { self.hashmap.borrow_mut().insert(key, WithDepNode::new(dep_node, value)); } - - pub fn insert_same(&self, key: Key, dep_node: DepNodeIndex, value: Value) - where - Value: Eq, - { - self.hashmap.borrow_mut().insert_same(key, WithDepNode::new(dep_node, value)); - } } #[derive(Clone, Eq, PartialEq)] diff --git a/compiler/rustc_query_system/src/dep_graph/debug.rs b/compiler/rustc_query_system/src/dep_graph/debug.rs index 718a2f1039a..43429cd11a2 100644 --- a/compiler/rustc_query_system/src/dep_graph/debug.rs +++ b/compiler/rustc_query_system/src/dep_graph/debug.rs @@ -52,6 +52,7 @@ impl EdgeFilter { } } + #[cfg(debug_assertions)] pub fn test(&self, source: &DepNode, target: &DepNode) -> bool { self.source.test(source) && self.target.test(target) } diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 0f25572170f..9fe2497a57b 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -488,8 +488,8 @@ impl DepGraph { self.data.is_some() && self.dep_node_index_of_opt(dep_node).is_some() } - #[inline] - pub fn dep_node_of(&self, dep_node_index: DepNodeIndex) -> DepNode { + #[cfg(debug_assertions)] + fn dep_node_of(&self, dep_node_index: DepNodeIndex) -> DepNode { let data = self.data.as_ref().unwrap(); let previous = &data.previous; let data = data.current.data.lock(); diff --git a/compiler/rustc_query_system/src/dep_graph/prev.rs b/compiler/rustc_query_system/src/dep_graph/prev.rs index c3d0f795255..6303bbf53b9 100644 --- a/compiler/rustc_query_system/src/dep_graph/prev.rs +++ b/compiler/rustc_query_system/src/dep_graph/prev.rs @@ -35,11 +35,6 @@ impl PreviousDepGraph { self.data.nodes[dep_node_index] } - #[inline] - pub fn node_to_index(&self, dep_node: &DepNode) -> SerializedDepNodeIndex { - self.index[dep_node] - } - #[inline] pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option { self.index.get(dep_node).cloned() diff --git a/compiler/rustc_query_system/src/dep_graph/query.rs b/compiler/rustc_query_system/src/dep_graph/query.rs index cc25d08cb54..e678a16249b 100644 --- a/compiler/rustc_query_system/src/dep_graph/query.rs +++ b/compiler/rustc_query_system/src/dep_graph/query.rs @@ -31,10 +31,6 @@ impl DepGraphQuery { DepGraphQuery { graph, indices } } - pub fn contains_node(&self, node: &DepNode) -> bool { - self.indices.contains_key(&node) - } - pub fn nodes(&self) -> Vec<&DepNode> { self.graph.all_nodes().iter().map(|n| &n.data).collect() } diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index 13d613132c0..1ef3204a2aa 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -516,19 +516,6 @@ impl<'tcx> SaveContext<'tcx> { }) } - pub fn get_trait_ref_data(&self, trait_ref: &hir::TraitRef<'_>) -> Option { - self.lookup_def_id(trait_ref.hir_ref_id).and_then(|def_id| { - let span = trait_ref.path.span; - if generated_code(span) { - return None; - } - let sub_span = trait_ref.path.segments.last().unwrap().ident.span; - filter!(self.span_utils, sub_span); - let span = self.span_from_span(sub_span); - Some(Ref { kind: RefKind::Type, span, ref_id: id_from_def_id(def_id) }) - }) - } - pub fn get_expr_data(&self, expr: &hir::Expr<'_>) -> Option { let ty = self.typeck_results().expr_ty_adjusted_opt(expr)?; if matches!(ty.kind(), ty::Error(_)) { @@ -784,7 +771,10 @@ impl<'tcx> SaveContext<'tcx> { /// For a given piece of AST defined by the supplied Span and NodeId, /// returns `None` if the node is not macro-generated or the span is malformed, /// else uses the expansion callsite and callee to return some MacroRef. - pub fn get_macro_use_data(&self, span: Span) -> Option { + /// + /// FIXME: [`dump_visitor::process_macro_use`] should actually dump this data + #[allow(dead_code)] + fn get_macro_use_data(&self, span: Span) -> Option { if !generated_code(span) { return None; } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 3d69943e889..6540d461047 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -505,6 +505,7 @@ impl<'a> From<&'a ExternDepSpec> for rustc_lint_defs::ExternDepSpec { } impl Externs { + /// Used for testing. pub fn new(data: BTreeMap) -> Externs { Externs(data) } @@ -604,13 +605,6 @@ impl Input { } } - pub fn get_input(&mut self) -> Option<&mut String> { - match *self { - Input::File(_) => None, - Input::Str { ref mut input, .. } => Some(input), - } - } - pub fn source_name(&self) -> FileName { match *self { Input::File(ref ifile) => ifile.clone().into(), @@ -778,12 +772,6 @@ impl Options { || self.debugging_opts.query_dep_graph } - #[inline(always)] - pub fn enable_dep_node_debug_strs(&self) -> bool { - cfg!(debug_assertions) - && (self.debugging_opts.query_dep_graph || self.debugging_opts.incremental_info) - } - pub fn file_path_mapping(&self) -> FilePathMapping { FilePathMapping::new(self.remap_path_prefix.clone()) } @@ -1060,9 +1048,6 @@ mod opt { pub fn flag_s(a: S, b: S, c: S) -> R { stable(longer(a, b), move |opts| opts.optflag(a, b, c)) } - pub fn flagopt_s(a: S, b: S, c: S, d: S) -> R { - stable(longer(a, b), move |opts| opts.optflagopt(a, b, c, d)) - } pub fn flagmulti_s(a: S, b: S, c: S) -> R { stable(longer(a, b), move |opts| opts.optflagmulti(a, b, c)) } @@ -1073,15 +1058,6 @@ mod opt { pub fn multi(a: S, b: S, c: S, d: S) -> R { unstable(longer(a, b), move |opts| opts.optmulti(a, b, c, d)) } - pub fn flag(a: S, b: S, c: S) -> R { - unstable(longer(a, b), move |opts| opts.optflag(a, b, c)) - } - pub fn flagopt(a: S, b: S, c: S, d: S) -> R { - unstable(longer(a, b), move |opts| opts.optflagopt(a, b, c, d)) - } - pub fn flagmulti(a: S, b: S, c: S) -> R { - unstable(longer(a, b), move |opts| opts.optflagmulti(a, b, c)) - } } /// Returns the "short" subset of the rustc command line options, @@ -2459,7 +2435,7 @@ crate mod dep_tracking { } // This is a stable hash because BTreeMap is a sorted container - pub fn stable_hash( + crate fn stable_hash( sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>, hasher: &mut DefaultHasher, error_format: ErrorOutputType, diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 592773bfe1b..65d5d96aba1 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -140,6 +140,7 @@ pub struct ParseSess { } impl ParseSess { + /// Used for testing. pub fn new(file_path_mapping: FilePathMapping) -> Self { let sm = Lrc::new(SourceMap::new(file_path_mapping)); let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, None, Some(sm.clone())); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index ca9214c03a8..621907f19aa 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -20,7 +20,7 @@ use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitterWriter; use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType}; use rustc_errors::json::JsonEmitter; use rustc_errors::registry::Registry; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId, ErrorReported}; +use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId, ErrorReported}; use rustc_lint_defs::FutureBreakage; pub use rustc_span::crate_disambiguator::CrateDisambiguator; use rustc_span::edition::Edition; @@ -241,8 +241,7 @@ pub struct PerfStats { enum DiagnosticBuilderMethod { Note, SpanNote, - SpanSuggestion(String), // suggestion - // Add more variants as needed to support one-time diagnostics. + // Add more variants as needed to support one-time diagnostics. } /// Trait implemented by error types. This should not be implemented manually. Instead, use @@ -365,14 +364,6 @@ impl Session { pub fn struct_span_warn>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_warn(sp, msg) } - pub fn struct_span_warn_with_code>( - &self, - sp: S, - msg: &str, - code: DiagnosticId, - ) -> DiagnosticBuilder<'_> { - self.diagnostic().struct_span_warn_with_code(sp, msg, code) - } pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> { self.diagnostic().struct_warn(msg) } @@ -411,37 +402,16 @@ impl Session { ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_fatal_with_code(sp, msg, code) } - pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_> { - self.diagnostic().struct_fatal(msg) - } pub fn span_fatal>(&self, sp: S, msg: &str) -> ! { self.diagnostic().span_fatal(sp, msg).raise() } - pub fn span_fatal_with_code>( - &self, - sp: S, - msg: &str, - code: DiagnosticId, - ) -> ! { - self.diagnostic().span_fatal_with_code(sp, msg, code).raise() - } pub fn fatal(&self, msg: &str) -> ! { self.diagnostic().fatal(msg).raise() } - pub fn span_err_or_warn>(&self, is_warning: bool, sp: S, msg: &str) { - if is_warning { - self.span_warn(sp, msg); - } else { - self.span_err(sp, msg); - } - } pub fn span_err>(&self, sp: S, msg: &str) { self.diagnostic().span_err(sp, msg) } - pub fn span_err_with_code>(&self, sp: S, msg: &str, code: DiagnosticId) { - self.diagnostic().span_err_with_code(sp, &msg, code) - } pub fn err(&self, msg: &str) { self.diagnostic().err(msg) } @@ -481,18 +451,9 @@ impl Session { pub fn span_warn>(&self, sp: S, msg: &str) { self.diagnostic().span_warn(sp, msg) } - pub fn span_warn_with_code>(&self, sp: S, msg: &str, code: DiagnosticId) { - self.diagnostic().span_warn_with_code(sp, msg, code) - } pub fn warn(&self, msg: &str) { self.diagnostic().warn(msg) } - pub fn opt_span_warn>(&self, opt_sp: Option, msg: &str) { - match opt_sp { - Some(sp) => self.span_warn(sp, msg), - None => self.warn(msg), - } - } /// Delay a span_bug() call until abort_if_errors() #[track_caller] pub fn delay_span_bug>(&self, sp: S, msg: &str) { @@ -519,9 +480,6 @@ impl Session { pub fn note_without_error(&self, msg: &str) { self.diagnostic().note_without_error(msg) } - pub fn span_note_without_error>(&self, sp: S, msg: &str) { - self.diagnostic().span_note_without_error(sp, msg) - } pub fn struct_note_without_error(&self, msg: &str) -> DiagnosticBuilder<'_> { self.diagnostic().struct_note_without_error(msg) } @@ -551,15 +509,6 @@ impl Session { let span = span_maybe.expect("`span_note` needs a span"); diag_builder.span_note(span, message); } - DiagnosticBuilderMethod::SpanSuggestion(suggestion) => { - let span = span_maybe.expect("`span_suggestion_*` needs a span"); - diag_builder.span_suggestion( - span, - message, - suggestion, - Applicability::Unspecified, - ); - } } } } @@ -589,23 +538,6 @@ impl Session { self.diag_once(diag_builder, DiagnosticBuilderMethod::Note, msg_id, message, None); } - pub fn diag_span_suggestion_once<'a, 'b>( - &'a self, - diag_builder: &'b mut DiagnosticBuilder<'a>, - msg_id: DiagnosticMessageId, - span: Span, - message: &str, - suggestion: String, - ) { - self.diag_once( - diag_builder, - DiagnosticBuilderMethod::SpanSuggestion(suggestion), - msg_id, - message, - Some(span), - ); - } - #[inline] pub fn source_map(&self) -> &SourceMap { self.parse_sess.source_map() @@ -631,9 +563,6 @@ impl Session { pub fn verify_llvm_ir(&self) -> bool { self.opts.debugging_opts.verify_llvm_ir || option_env!("RUSTC_VERIFY_LLVM_IR").is_some() } - pub fn borrowck_stats(&self) -> bool { - self.opts.debugging_opts.borrowck_stats - } pub fn print_llvm_passes(&self) -> bool { self.opts.debugging_opts.print_llvm_passes } @@ -890,22 +819,6 @@ impl Session { ) } - pub fn set_incr_session_load_dep_graph(&self, load: bool) { - let mut incr_comp_session = self.incr_comp_session.borrow_mut(); - - if let IncrCompSession::Active { ref mut load_dep_graph, .. } = *incr_comp_session { - *load_dep_graph = load; - } - } - - pub fn incr_session_load_dep_graph(&self) -> bool { - let incr_comp_session = self.incr_comp_session.borrow(); - match *incr_comp_session { - IncrCompSession::Active { load_dep_graph, .. } => load_dep_graph, - _ => false, - } - } - pub fn init_incr_comp_session( &self, session_dir: PathBuf, diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 885f30ebb4e..95bb0ad7ba2 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -160,6 +160,8 @@ impl DefPathHash { } /// Returns the crate-local part of the [DefPathHash]. + /// + /// Used for tests. #[inline] pub fn local_hash(&self) -> u64 { self.0.as_value().1 diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index daecbe92250..6805d4f2890 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1176,11 +1176,7 @@ pub fn decode_syntax_context< Ok(new_ctxt) } -pub fn num_syntax_ctxts() -> usize { - HygieneData::with(|data| data.syntax_context_data.len()) -} - -pub fn for_all_ctxts_in Result<(), E>>( +fn for_all_ctxts_in Result<(), E>>( ctxts: impl Iterator, mut f: F, ) -> Result<(), E> { @@ -1193,7 +1189,7 @@ pub fn for_all_ctxts_in Ok(()) } -pub fn for_all_expns_in Result<(), E>>( +fn for_all_expns_in Result<(), E>>( expns: impl Iterator, mut f: F, ) -> Result<(), E> { @@ -1206,16 +1202,6 @@ pub fn for_all_expns_in Result<(), E>>( Ok(()) } -pub fn for_all_data Result<(), E>>( - mut f: F, -) -> Result<(), E> { - let all_data = HygieneData::with(|data| data.syntax_context_data.clone()); - for (i, data) in all_data.into_iter().enumerate() { - f((i as u32, SyntaxContext(i as u32), &data))?; - } - Ok(()) -} - impl Encodable for ExpnId { default fn encode(&self, _: &mut E) -> Result<(), E::Error> { panic!("cannot encode `ExpnId` with `{}`", std::any::type_name::()); @@ -1228,14 +1214,6 @@ impl Decodable for ExpnId { } } -pub fn for_all_expn_data Result<(), E>>(mut f: F) -> Result<(), E> { - let all_data = HygieneData::with(|data| data.expn_data.clone()); - for (i, data) in all_data.into_iter().enumerate() { - f(i as u32, &data.unwrap_or_else(|| panic!("Missing ExpnData!")))?; - } - Ok(()) -} - pub fn raw_encode_syntax_context( ctxt: SyntaxContext, context: &HygieneEncodeContext, diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index d2790335b5a..6f6ff37c525 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1037,10 +1037,6 @@ pub enum ExternalSourceKind { } impl ExternalSource { - pub fn is_absent(&self) -> bool { - !matches!(self, ExternalSource::Foreign { kind: ExternalSourceKind::Present(_), .. }) - } - pub fn get_source(&self) -> Option<&Lrc> { match self { ExternalSource::Foreign { kind: ExternalSourceKind::Present(ref src), .. } => Some(src), @@ -1433,9 +1429,6 @@ impl SourceFile { self.src.is_none() } - pub fn byte_length(&self) -> u32 { - self.end_pos.0 - self.start_pos.0 - } pub fn count_lines(&self) -> usize { self.lines.len() } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index cf7f0a553c7..b351af44e94 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -8,12 +8,6 @@ pub struct ImpliedOutlivesBounds<'tcx> { pub ty: Ty<'tcx>, } -impl<'tcx> ImpliedOutlivesBounds<'tcx> { - pub fn new(ty: Ty<'tcx>) -> Self { - ImpliedOutlivesBounds { ty } - } -} - impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> { type QueryResponse = Vec>; diff --git a/src/tools/clippy/clippy_lints/src/functions.rs b/src/tools/clippy/clippy_lints/src/functions.rs index 730492fc7e3..5fe46065348 100644 --- a/src/tools/clippy/clippy_lints/src/functions.rs +++ b/src/tools/clippy/clippy_lints/src/functions.rs @@ -516,7 +516,7 @@ fn check_needless_must_use( ); }, ); - } else if !attr.is_value_str() && is_must_use_ty(cx, return_ty(cx, item_id)) { + } else if !attr.value_str().is_some() && is_must_use_ty(cx, return_ty(cx, item_id)) { span_lint_and_help( cx, DOUBLE_MUST_USE, diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index ff87828c2e7..5741aad261b 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -95,7 +95,7 @@ impl MissingDoc { let has_doc = attrs .iter() - .any(|a| a.is_doc_comment() || a.doc_str().is_some() || a.is_value_str() || Self::has_include(a.meta())); + .any(|a| a.is_doc_comment() || a.doc_str().is_some() || a.value_str().is_some() || Self::has_include(a.meta())); if !has_doc { span_lint( cx, From de0fda9558e5b9eed94cd1e2c1599ea72115d744 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 16 Mar 2021 12:57:31 -0400 Subject: [PATCH 161/370] Address review comments - Add back `HirIdVec`, with a comment that it will soon be used. - Add back `*_region` functions, with a comment they may soon be used. - Remove `-Z borrowck_stats` completely. It didn't do anything. - Remove `make_nop` completely. - Add back `current_loc`, which is used by an out-of-tree tool. - Fix style nits - Remove `AtomicCell` with `cfg(parallel_compiler)` for consistency. --- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 68 +++++++++++++++++++ compiler/rustc_data_structures/src/sync.rs | 2 - compiler/rustc_driver/src/lib.rs | 7 +- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_hir/src/hir_id.rs | 68 +++++++++++++++++++ .../rustc_infer/src/infer/type_variable.rs | 4 +- compiler/rustc_interface/src/tests.rs | 1 - .../rustc_mir/src/interpret/eval_context.rs | 12 ++++ compiler/rustc_mir/src/util/patch.rs | 6 -- compiler/rustc_session/src/options.rs | 2 - 10 files changed, 154 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 4a1b76079b3..af9d3d2dc26 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -703,6 +703,74 @@ pub mod coverageinfo { kind: RegionKind::CodeRegion, } } + + // This function might be used in the future; the LLVM API is still evolving, as is coverage + // support. + #[allow(dead_code)] + crate fn expansion_region( + file_id: u32, + expanded_file_id: u32, + start_line: u32, + start_col: u32, + end_line: u32, + end_col: u32, + ) -> Self { + Self { + counter: coverage_map::Counter::zero(), + file_id, + expanded_file_id, + start_line, + start_col, + end_line, + end_col, + kind: RegionKind::ExpansionRegion, + } + } + + // This function might be used in the future; the LLVM API is still evolving, as is coverage + // support. + #[allow(dead_code)] + crate fn skipped_region( + file_id: u32, + start_line: u32, + start_col: u32, + end_line: u32, + end_col: u32, + ) -> Self { + Self { + counter: coverage_map::Counter::zero(), + file_id, + expanded_file_id: 0, + start_line, + start_col, + end_line, + end_col, + kind: RegionKind::SkippedRegion, + } + } + + // This function might be used in the future; the LLVM API is still evolving, as is coverage + // support. + #[allow(dead_code)] + crate fn gap_region( + counter: coverage_map::Counter, + file_id: u32, + start_line: u32, + start_col: u32, + end_line: u32, + end_col: u32, + ) -> Self { + Self { + counter, + file_id, + expanded_file_id: 0, + start_line, + start_col, + end_line, + end_col: ((1 as u32) << 31) | end_col, + kind: RegionKind::GapRegion, + } + } } } diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index c17c28df872..357686342be 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -236,8 +236,6 @@ cfg_if! { pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64}; - pub use crossbeam_utils::atomic::AtomicCell; - pub use std::sync::Arc as Lrc; pub use std::sync::Weak as Weak; diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 2a61fb54772..c8891734cce 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -157,10 +157,9 @@ impl<'a, 'b> RunCompiler<'a, 'b> { self } /// Used by RLS. - pub fn set_emitter(&mut self, emitter: Option>) -> &mut Self - { - self.emitter = emitter; - self + pub fn set_emitter(&mut self, emitter: Option>) -> &mut Self { + self.emitter = emitter; + self } /// Used by RLS. pub fn set_file_loader( diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index aaf15c60f1e..d91c1813da3 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2206,7 +2206,7 @@ impl PrimTy { Self::Str, ]; - /// [`PrimTy::name`], but returns a &str instead of a symbol. + /// Like [`PrimTy::name`], but returns a &str instead of a symbol. /// /// Used by rustdoc. pub fn name_str(self) -> &'static str { diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index e24eb5e4490..0b25ebc27bd 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -1,4 +1,5 @@ use crate::def_id::{LocalDefId, CRATE_DEF_INDEX}; +use rustc_index::vec::IndexVec; use std::fmt; /// Uniquely identifies a node in the HIR of the current crate. It is @@ -61,3 +62,70 @@ pub const CRATE_HIR_ID: HirId = HirId { owner: LocalDefId { local_def_index: CRATE_DEF_INDEX }, local_id: ItemLocalId::from_u32(0), }; + +/// N.B. This collection is currently unused, but will be used by #72015 and future PRs. +#[derive(Clone, Default, Debug, Encodable, Decodable)] +pub struct HirIdVec { + map: IndexVec>, +} + +impl HirIdVec { + pub fn push_owner(&mut self, id: LocalDefId) { + self.map.ensure_contains_elem(id, IndexVec::new); + } + + pub fn push(&mut self, id: HirId, value: T) { + if id.local_id == ItemLocalId::from_u32(0) { + self.push_owner(id.owner); + } + let submap = &mut self.map[id.owner]; + let _ret_id = submap.push(value); + debug_assert_eq!(_ret_id, id.local_id); + } + + pub fn push_sparse(&mut self, id: HirId, value: T) + where + T: Default, + { + self.map.ensure_contains_elem(id.owner, IndexVec::new); + let submap = &mut self.map[id.owner]; + let i = id.local_id.index(); + let len = submap.len(); + if i >= len { + submap.extend(std::iter::repeat_with(T::default).take(i - len + 1)); + } + submap[id.local_id] = value; + } + + pub fn get(&self, id: HirId) -> Option<&T> { + self.map.get(id.owner)?.get(id.local_id) + } + + pub fn get_owner(&self, id: LocalDefId) -> &IndexVec { + &self.map[id] + } + + pub fn iter(&self) -> impl Iterator { + self.map.iter().flat_map(|la| la.iter()) + } + + pub fn iter_enumerated(&self) -> impl Iterator { + self.map.iter_enumerated().flat_map(|(owner, la)| { + la.iter_enumerated().map(move |(local_id, attr)| (HirId { owner, local_id }, attr)) + }) + } +} + +impl std::ops::Index for HirIdVec { + type Output = T; + + fn index(&self, id: HirId) -> &T { + &self.map[id.owner][id.local_id] + } +} + +impl std::ops::IndexMut for HirIdVec { + fn index_mut(&mut self, id: HirId) -> &mut T { + &mut self.map[id.owner][id.local_id] + } +} diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 49fb2d7993c..683c1df783e 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -146,7 +146,7 @@ impl<'tcx> TypeVariableValue<'tcx> { } } -pub(crate) struct Instantiate {} +pub(crate) struct Instantiate; pub(crate) struct Delegate; @@ -222,7 +222,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> { // Hack: we only need this so that `types_escaping_snapshot` // can see what has been unified; see the Delegate impl for // more details. - self.undo_log.push(Instantiate {}); + self.undo_log.push(Instantiate); } /// Creates a new type variable. diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 8e6a1ec5095..1653d3bdba1 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -471,7 +471,6 @@ fn test_debugging_options_tracking_hash() { untracked!(ast_json, true); untracked!(ast_json_noexpand, true); untracked!(borrowck, String::from("other")); - untracked!(borrowck_stats, true); untracked!(deduplicate_diagnostics, true); untracked!(dep_tasks, true); untracked!(dont_buffer_diagnostics, true); diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 3f20a83fc25..18d4d71e517 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -226,6 +226,18 @@ impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> { } impl<'mir, 'tcx, Tag, Extra> Frame<'mir, 'tcx, Tag, Extra> { + /// Get the current location within the Frame. + /// + /// If this is `Err`, we are not currently executing any particular statement in + /// this frame (can happen e.g. during frame initialization, and during unwinding on + /// frames without cleanup code). + /// We basically abuse `Result` as `Either`. + /// + /// Used by priroda. + pub fn current_loc(&self) -> Result { + self.loc + } + /// Return the `SourceInfo` of the current instruction. pub fn current_source_info(&self) -> Option<&mir::SourceInfo> { self.loc.ok().map(|loc| self.body.source_info(loc)) diff --git a/compiler/rustc_mir/src/util/patch.rs b/compiler/rustc_mir/src/util/patch.rs index 374bc19c711..d09195f53ae 100644 --- a/compiler/rustc_mir/src/util/patch.rs +++ b/compiler/rustc_mir/src/util/patch.rs @@ -13,7 +13,6 @@ pub struct MirPatch<'tcx> { new_locals: Vec>, resume_block: BasicBlock, next_local: usize, - make_nop: Vec, } impl<'tcx> MirPatch<'tcx> { @@ -25,7 +24,6 @@ impl<'tcx> MirPatch<'tcx> { new_locals: vec![], next_local: body.local_decls.len(), resume_block: START_BLOCK, - make_nop: vec![], }; // make sure the MIR we create has a resume block. It is @@ -118,10 +116,6 @@ impl<'tcx> MirPatch<'tcx> { } pub fn apply(self, body: &mut Body<'tcx>) { - debug!("MirPatch: make nops at: {:?}", self.make_nop); - for loc in self.make_nop { - body.make_statement_nop(loc); - } debug!( "MirPatch: {:?} new temps, starting from index {}: {:?}", self.new_locals.len(), diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index e071c58d1cd..e50972e59a7 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -906,8 +906,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, (default: no)"), borrowck: String = ("migrate".to_string(), parse_string, [UNTRACKED], "select which borrowck is used (`mir` or `migrate`) (default: `migrate`)"), - borrowck_stats: bool = (false, parse_bool, [UNTRACKED], - "gather borrowck statistics (default: no)"), cgu_partitioning_strategy: Option = (None, parse_opt_string, [TRACKED], "the codegen unit partitioning strategy to use"), chalk: bool = (false, parse_bool, [TRACKED], From 230e396a7663d933d24c3c30f556abbc1dd9405e Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 17 Mar 2021 09:59:45 -0400 Subject: [PATCH 162/370] Fix compiler docs --- compiler/rustc_errors/src/diagnostic_builder.rs | 9 +++++++++ compiler/rustc_save_analysis/src/lib.rs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 282877d5dd1..3fc63b4e50c 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -45,6 +45,9 @@ macro_rules! forward { pub fn $n:ident(&self, $($name:ident: $ty:ty),* $(,)?) -> &Self ) => { $(#[$attrs])* + // we always document with --document-private-items + #[cfg_attr(not(bootstrap), allow(rustdoc::private_intra_doc_links))] + #[cfg_attr(bootstrap, allow(private_intra_doc_links))] #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] pub fn $n(&self, $($name: $ty),*) -> &Self { self.diagnostic.$n($($name),*); @@ -59,6 +62,9 @@ macro_rules! forward { ) => { $(#[$attrs])* #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] + // we always document with --document-private-items + #[cfg_attr(not(bootstrap), allow(rustdoc::private_intra_doc_links))] + #[cfg_attr(bootstrap, allow(private_intra_doc_links))] pub fn $n(&mut self, $($name: $ty),*) -> &mut Self { self.0.diagnostic.$n($($name),*); self @@ -76,6 +82,9 @@ macro_rules! forward { ) => { $(#[$attrs])* #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] + // we always document with --document-private-items + #[cfg_attr(not(bootstrap), allow(rustdoc::private_intra_doc_links))] + #[cfg_attr(bootstrap, allow(private_intra_doc_links))] pub fn $n<$($generic: $bound),*>(&mut self, $($name: $ty),*) -> &mut Self { self.0.diagnostic.$n($($name),*); self diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index 1ef3204a2aa..c19c16b88a7 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -772,7 +772,7 @@ impl<'tcx> SaveContext<'tcx> { /// returns `None` if the node is not macro-generated or the span is malformed, /// else uses the expansion callsite and callee to return some MacroRef. /// - /// FIXME: [`dump_visitor::process_macro_use`] should actually dump this data + /// FIXME: [`DumpVisitor::process_macro_use`] should actually dump this data #[allow(dead_code)] fn get_macro_use_data(&self, span: Span) -> Option { if !generated_code(span) { From f3523544f114a4a4cc2ced3f1a53f5f3bc158751 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 27 Mar 2021 22:16:17 -0400 Subject: [PATCH 163/370] Address more review comments - Add back various diagnostic methods on `Session`. It seems unfortunate to duplicate these in so many places, but in the meantime, making the API inconsistent between `Session` and `Diagnostic` also seems unfortunate. - Add back TyCtxtAt methods These will hopefully be used in the near future. - Add back `with_const`, it would need to be added soon after anyway. - Add back `split()` and `get_mut()`, they're useful. --- compiler/rustc_middle/src/ty/context.rs | 17 ++++++++- compiler/rustc_middle/src/ty/mod.rs | 5 +++ compiler/rustc_middle/src/ty/sty.rs | 14 +++++++ compiler/rustc_mir/src/interpret/machine.rs | 5 +++ compiler/rustc_session/src/session.rs | 41 +++++++++++++++++++++ 5 files changed, 81 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index da3bdc5c721..94c1758b25c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -14,7 +14,7 @@ use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstValue, Scalar}; use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted}; use crate::traits; -use crate::ty::query::{self, OnDiskCache}; +use crate::ty::query::{self, OnDiskCache, TyCtxtAt}; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts}; use crate::ty::TyKind::*; use crate::ty::{ @@ -2650,6 +2650,21 @@ impl<'tcx> TyCtxt<'tcx> { } } +impl TyCtxtAt<'tcx> { + /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used. + #[track_caller] + pub fn ty_error(self) -> Ty<'tcx> { + self.tcx.ty_error_with_message(self.span, "TyKind::Error constructed but no error reported") + } + + /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to + /// ensure it gets used. + #[track_caller] + pub fn ty_error_with_message(self, msg: &str) -> Ty<'tcx> { + self.tcx.ty_error_with_message(self.span, msg) + } +} + pub trait InternAs { type Output; fn intern_with(self, f: F) -> Self::Output diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6a1ea6df3f0..c0025cf3fc8 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1208,6 +1208,11 @@ pub trait WithConstness: Sized { ConstnessAnd { constness, value: self } } + #[inline] + fn with_const(self) -> ConstnessAnd { + self.with_constness(Constness::Const) + } + #[inline] fn without_const(self) -> ConstnessAnd { self.with_constness(Constness::NotConst) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index b42375aec6e..b8fe7aa7fd0 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1058,6 +1058,20 @@ impl Binder { { Binder(f(self.0, u.0)) } + + /// Splits the contents into two things that share the same binder + /// level as the original, returning two distinct binders. + /// + /// `f` should consider bound regions at depth 1 to be free, and + /// anything it produces with bound regions at depth 1 will be + /// bound in the resulting return values. + pub fn split(self, f: F) -> (Binder, Binder) + where + F: FnOnce(T) -> (U, V), + { + let (u, v) = f(self.0); + (Binder(u), Binder(v)) + } } impl Binder> { diff --git a/compiler/rustc_mir/src/interpret/machine.rs b/compiler/rustc_mir/src/interpret/machine.rs index 593a90cb54d..65869f95639 100644 --- a/compiler/rustc_mir/src/interpret/machine.rs +++ b/compiler/rustc_mir/src/interpret/machine.rs @@ -71,6 +71,11 @@ pub trait AllocMap { fn get(&self, k: K) -> Option<&V> { self.get_or(k, || Err(())).ok() } + + /// Mutable lookup. + fn get_mut(&mut self, k: K) -> Option<&mut V> { + self.get_mut_or(k, || Err(())).ok() + } } /// Methods of this trait signifies a point where CTFE evaluation would fail diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 621907f19aa..693f427d7af 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -364,6 +364,14 @@ impl Session { pub fn struct_span_warn>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_warn(sp, msg) } + pub fn struct_span_warn_with_code>( + &self, + sp: S, + msg: &str, + code: DiagnosticId, + ) -> DiagnosticBuilder<'_> { + self.diagnostic().struct_span_warn_with_code(sp, msg, code) + } pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> { self.diagnostic().struct_warn(msg) } @@ -402,16 +410,37 @@ impl Session { ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_fatal_with_code(sp, msg, code) } + pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_> { + self.diagnostic().struct_fatal(msg) + } pub fn span_fatal>(&self, sp: S, msg: &str) -> ! { self.diagnostic().span_fatal(sp, msg).raise() } + pub fn span_fatal_with_code>( + &self, + sp: S, + msg: &str, + code: DiagnosticId, + ) -> ! { + self.diagnostic().span_fatal_with_code(sp, msg, code).raise() + } pub fn fatal(&self, msg: &str) -> ! { self.diagnostic().fatal(msg).raise() } + pub fn span_err_or_warn>(&self, is_warning: bool, sp: S, msg: &str) { + if is_warning { + self.span_warn(sp, msg); + } else { + self.span_err(sp, msg); + } + } pub fn span_err>(&self, sp: S, msg: &str) { self.diagnostic().span_err(sp, msg) } + pub fn span_err_with_code>(&self, sp: S, msg: &str, code: DiagnosticId) { + self.diagnostic().span_err_with_code(sp, &msg, code) + } pub fn err(&self, msg: &str) { self.diagnostic().err(msg) } @@ -451,9 +480,18 @@ impl Session { pub fn span_warn>(&self, sp: S, msg: &str) { self.diagnostic().span_warn(sp, msg) } + pub fn span_warn_with_code>(&self, sp: S, msg: &str, code: DiagnosticId) { + self.diagnostic().span_warn_with_code(sp, msg, code) + } pub fn warn(&self, msg: &str) { self.diagnostic().warn(msg) } + pub fn opt_span_warn>(&self, opt_sp: Option, msg: &str) { + match opt_sp { + Some(sp) => self.span_warn(sp, msg), + None => self.warn(msg), + } + } /// Delay a span_bug() call until abort_if_errors() #[track_caller] pub fn delay_span_bug>(&self, sp: S, msg: &str) { @@ -480,6 +518,9 @@ impl Session { pub fn note_without_error(&self, msg: &str) { self.diagnostic().note_without_error(msg) } + pub fn span_note_without_error>(&self, sp: S, msg: &str) { + self.diagnostic().span_note_without_error(sp, msg) + } pub fn struct_note_without_error(&self, msg: &str) -> DiagnosticBuilder<'_> { self.diagnostic().struct_note_without_error(msg) } From a0957c9d2685178d1d19406661a7082bac506acb Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 28 Mar 2021 00:51:31 -0400 Subject: [PATCH 164/370] Avoid sorting by DefId for `necessary_variants()` --- compiler/rustc_hir/src/pat_util.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir/src/pat_util.rs b/compiler/rustc_hir/src/pat_util.rs index 9e0a6aae242..c6a40b51a86 100644 --- a/compiler/rustc_hir/src/pat_util.rs +++ b/compiler/rustc_hir/src/pat_util.rs @@ -1,6 +1,7 @@ use crate::def::{CtorOf, DefKind, Res}; use crate::def_id::DefId; use crate::hir::{self, HirId, PatKind}; +use rustc_data_structures::stable_set::FxHashSet; use rustc_span::symbol::Ident; use rustc_span::Span; @@ -138,8 +139,10 @@ impl hir::Pat<'_> { } _ => true, }); - variants.sort(); - variants.dedup(); + // We remove duplicates by inserting into a `FxHashSet` to avoid re-ordering + // the bounds + let mut duplicates = FxHashSet::default(); + variants.retain(|def_id| duplicates.insert(*def_id)); variants } From 4a314b9911dc6057d2f3a741964f0ca1a18deeca Mon Sep 17 00:00:00 2001 From: JohnTitor Date: Sun, 28 Mar 2021 15:34:59 +0900 Subject: [PATCH 165/370] Remove unnecessary `ignore-cloudabi` flag --- src/test/ui/command/command-setgroups.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/ui/command/command-setgroups.rs b/src/test/ui/command/command-setgroups.rs index 2067314f740..aff67f91bba 100644 --- a/src/test/ui/command/command-setgroups.rs +++ b/src/test/ui/command/command-setgroups.rs @@ -1,6 +1,5 @@ // run-pass // ignore-windows - this is a unix-specific test -// ignore-cloudabi // ignore-emscripten // ignore-sgx // ignore-musl - returns dummy result for _SC_NGROUPS_MAX From a515cfd966d68a5a0a1b2d90425580f81cdabdbf Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 27 Mar 2021 14:23:29 +0100 Subject: [PATCH 166/370] update Miri --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri b/src/tools/miri index 12dac5c0f7a..2cdd1744b89 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 12dac5c0f7acd106401aa14fec758f0ff552f678 +Subproject commit 2cdd1744b896e8129322229f253f95fd7ad491f1 From ee1caae33c9082c44387b2dc9b939db9f764a8f3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 28 Mar 2021 12:50:20 +0200 Subject: [PATCH 167/370] unaligned_references: align(N) fields in packed(N) structs are fine --- compiler/rustc_mir/src/util/alignment.rs | 35 ++++++++++++++------ src/test/ui/lint/unaligned_references.rs | 15 +++++++++ src/test/ui/lint/unaligned_references.stderr | 24 ++++++++++---- 3 files changed, 56 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_mir/src/util/alignment.rs b/compiler/rustc_mir/src/util/alignment.rs index f567c9cfaab..5d4ca871faa 100644 --- a/compiler/rustc_mir/src/util/alignment.rs +++ b/compiler/rustc_mir/src/util/alignment.rs @@ -1,5 +1,6 @@ use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; +use rustc_target::abi::Align; /// Returns `true` if this place is allowed to be less aligned /// than its containing struct (because it is within a packed @@ -14,17 +15,25 @@ where L: HasLocalDecls<'tcx>, { debug!("is_disaligned({:?})", place); - if !is_within_packed(tcx, local_decls, place) { - debug!("is_disaligned({:?}) - not within packed", place); - return false; - } + let pack = match is_within_packed(tcx, local_decls, place) { + None => { + debug!("is_disaligned({:?}) - not within packed", place); + return false; + } + Some(pack) => pack, + }; let ty = place.ty(local_decls, tcx).ty; match tcx.layout_raw(param_env.and(ty)) { - Ok(layout) if layout.align.abi.bytes() == 1 => { - // if the alignment is 1, the type can't be further - // disaligned. - debug!("is_disaligned({:?}) - align = 1", place); + Ok(layout) if layout.align.abi <= pack => { + // If the packed alignment is greater or equal to the field alignment, the type won't be + // further disaligned. + debug!( + "is_disaligned({:?}) - align = {}, packed = {}; not disaligned", + place, + layout.align.abi.bytes(), + pack.bytes() + ); false } _ => { @@ -34,7 +43,11 @@ where } } -fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: Place<'tcx>) -> bool +fn is_within_packed<'tcx, L>( + tcx: TyCtxt<'tcx>, + local_decls: &L, + place: Place<'tcx>, +) -> Option where L: HasLocalDecls<'tcx>, { @@ -45,7 +58,7 @@ where ProjectionElem::Field(..) => { let ty = place_base.ty(local_decls, tcx).ty; match ty.kind() { - ty::Adt(def, _) if def.repr.packed() => return true, + ty::Adt(def, _) => return def.repr.pack, _ => {} } } @@ -53,5 +66,5 @@ where } } - false + None } diff --git a/src/test/ui/lint/unaligned_references.rs b/src/test/ui/lint/unaligned_references.rs index ad38c21d96c..d06b06b504f 100644 --- a/src/test/ui/lint/unaligned_references.rs +++ b/src/test/ui/lint/unaligned_references.rs @@ -8,6 +8,13 @@ pub struct Good { aligned: [u8; 32], } +#[repr(packed(2))] +pub struct Packed2 { + x: u32, + y: u16, + z: u8, +} + fn main() { unsafe { let good = Good { data: 0, ptr: &0, data2: [0, 0], aligned: [0; 32] }; @@ -32,4 +39,12 @@ fn main() { let _ = &good.aligned; // ok, has align 1 let _ = &good.aligned[2]; // ok, has align 1 } + + unsafe { + let packed2 = Packed2 { x: 0, y: 0, z: 0 }; + let _ = &packed2.x; //~ ERROR reference to packed field + //~^ previously accepted + let _ = &packed2.y; // ok, has align 2 in packed(2) struct + let _ = &packed2.z; // ok, has align 1 + } } diff --git a/src/test/ui/lint/unaligned_references.stderr b/src/test/ui/lint/unaligned_references.stderr index 9ae25f5b59e..b4cce3cfea2 100644 --- a/src/test/ui/lint/unaligned_references.stderr +++ b/src/test/ui/lint/unaligned_references.stderr @@ -1,5 +1,5 @@ error: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:15:17 + --> $DIR/unaligned_references.rs:22:17 | LL | let _ = &good.ptr; | ^^^^^^^^^ @@ -14,7 +14,7 @@ LL | #![deny(unaligned_references)] = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) error: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:17:17 + --> $DIR/unaligned_references.rs:24:17 | LL | let _ = &good.data; | ^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | let _ = &good.data; = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) error: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:20:17 + --> $DIR/unaligned_references.rs:27:17 | LL | let _ = &good.data as *const _; | ^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = &good.data as *const _; = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) error: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:22:27 + --> $DIR/unaligned_references.rs:29:27 | LL | let _: *const _ = &good.data; | ^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | let _: *const _ = &good.data; = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) error: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:25:17 + --> $DIR/unaligned_references.rs:32:17 | LL | let _ = good.data.clone(); | ^^^^^^^^^ @@ -54,7 +54,7 @@ LL | let _ = good.data.clone(); = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) error: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:28:17 + --> $DIR/unaligned_references.rs:35:17 | LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ @@ -63,5 +63,15 @@ LL | let _ = &good.data2[0]; = note: for more information, see issue #82523 = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) -error: aborting due to 6 previous errors +error: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:45:17 + | +LL | let _ = &packed2.x; + | ^^^^^^^^^^ + | + = 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 #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +error: aborting due to 7 previous errors From 1ab05c13dde13d08a2e1990960582cb9970e90a2 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 28 Mar 2021 13:54:27 +0200 Subject: [PATCH 168/370] adjust old test --- .../packed-struct-borrow-element-64bit.rs | 17 +++++++++++++++++ .../packed-struct-borrow-element-64bit.stderr | 13 +++++++++++++ .../ui/packed/packed-struct-borrow-element.rs | 5 ----- .../packed/packed-struct-borrow-element.stderr | 12 +----------- 4 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 src/test/ui/packed/packed-struct-borrow-element-64bit.rs create mode 100644 src/test/ui/packed/packed-struct-borrow-element-64bit.stderr diff --git a/src/test/ui/packed/packed-struct-borrow-element-64bit.rs b/src/test/ui/packed/packed-struct-borrow-element-64bit.rs new file mode 100644 index 00000000000..ad932fdcd01 --- /dev/null +++ b/src/test/ui/packed/packed-struct-borrow-element-64bit.rs @@ -0,0 +1,17 @@ +// run-pass (note: this is spec-UB, but it works for now) +// ignore-32bit (needs `usize` to be 8-aligned to reproduce all the errors below) +#![allow(dead_code)] +// ignore-emscripten weird assertion? + +#[repr(C, packed(4))] +struct Foo4C { + bar: u8, + baz: usize +} + +pub fn main() { + let foo = Foo4C { bar: 1, baz: 2 }; + let brw = &foo.baz; //~WARN reference to packed field is unaligned + //~^ previously accepted + assert_eq!(*brw, 2); +} diff --git a/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr b/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr new file mode 100644 index 00000000000..766d8a72c34 --- /dev/null +++ b/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr @@ -0,0 +1,13 @@ +warning: reference to packed field is unaligned + --> $DIR/packed-struct-borrow-element-64bit.rs:14:15 + | +LL | let brw = &foo.baz; + | ^^^^^^^^ + | + = note: `#[warn(unaligned_references)]` on by default + = 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 #82523 + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +warning: 1 warning emitted + diff --git a/src/test/ui/packed/packed-struct-borrow-element.rs b/src/test/ui/packed/packed-struct-borrow-element.rs index 5dad084eecf..fb6c9c11d56 100644 --- a/src/test/ui/packed/packed-struct-borrow-element.rs +++ b/src/test/ui/packed/packed-struct-borrow-element.rs @@ -30,9 +30,4 @@ pub fn main() { let brw = &foo.baz; //~WARN reference to packed field is unaligned //~^ previously accepted assert_eq!(*brw, 2); - - let foo = Foo4C { bar: 1, baz: 2 }; - let brw = &foo.baz; //~WARN reference to packed field is unaligned - //~^ previously accepted - assert_eq!(*brw, 2); } diff --git a/src/test/ui/packed/packed-struct-borrow-element.stderr b/src/test/ui/packed/packed-struct-borrow-element.stderr index d9d9a71ff58..5764e951a46 100644 --- a/src/test/ui/packed/packed-struct-borrow-element.stderr +++ b/src/test/ui/packed/packed-struct-borrow-element.stderr @@ -19,15 +19,5 @@ LL | let brw = &foo.baz; = note: for more information, see issue #82523 = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) -warning: reference to packed field is unaligned - --> $DIR/packed-struct-borrow-element.rs:35:15 - | -LL | let brw = &foo.baz; - | ^^^^^^^^ - | - = 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 #82523 - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - -warning: 3 warnings emitted +warning: 2 warnings emitted From a143d6d4674169f12402fae56a1fa4053436754c Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Sat, 9 Jan 2021 22:54:21 +0000 Subject: [PATCH 169/370] run-make: Specify --target to rustc Resolves #78911 The target's linker was used but rustc wasn't told to build for that target (instead defaulting to the host). This led to the host instead of the target getting tested and to the linker getting inappropriate arguments. --- src/test/run-make/incr-prev-body-beyond-eof/Makefile | 7 ++----- src/test/run-make/issue-36710/Makefile | 5 +---- .../run-make/issue-83112-incr-test-moved-file/Makefile | 7 ++----- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/test/run-make/incr-prev-body-beyond-eof/Makefile b/src/test/run-make/incr-prev-body-beyond-eof/Makefile index 49a7ee5f900..ae447e1bd9c 100644 --- a/src/test/run-make/incr-prev-body-beyond-eof/Makefile +++ b/src/test/run-make/incr-prev-body-beyond-eof/Makefile @@ -1,8 +1,5 @@ include ../../run-make-fulldeps/tools.mk -# FIXME https://github.com/rust-lang/rust/issues/78911 -# ignore-32bit wrong/no cross compiler and sometimes we pass wrong gcc args (-m64) - # 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 # in the new file, but its start line/column and length remain the same. @@ -14,6 +11,6 @@ all: mkdir $(SRC) mkdir $(INCR) cp a.rs $(SRC)/main.rs - $(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs + $(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs --target $(TARGET) cp b.rs $(SRC)/main.rs - $(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs + $(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs --target $(TARGET) diff --git a/src/test/run-make/issue-36710/Makefile b/src/test/run-make/issue-36710/Makefile index b0e8451ff5d..3d93b2f6961 100644 --- a/src/test/run-make/issue-36710/Makefile +++ b/src/test/run-make/issue-36710/Makefile @@ -1,13 +1,10 @@ include ../../run-make-fulldeps/tools.mk -# FIXME https://github.com/rust-lang/rust/issues/78911 -# ignore-32bit wrong/no cross compiler and sometimes we pass wrong gcc args (-m64) - all: foo $(call RUN,foo) foo: foo.rs $(call NATIVE_STATICLIB,foo) - $(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS) + $(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS) --target $(TARGET) $(TMPDIR)/libfoo.o: foo.cpp $(call COMPILE_OBJ_CXX,$@,$<) diff --git a/src/test/run-make/issue-83112-incr-test-moved-file/Makefile b/src/test/run-make/issue-83112-incr-test-moved-file/Makefile index 76ecaba0f6a..c89eebf3745 100644 --- a/src/test/run-make/issue-83112-incr-test-moved-file/Makefile +++ b/src/test/run-make/issue-83112-incr-test-moved-file/Makefile @@ -1,8 +1,5 @@ include ../../run-make-fulldeps/tools.mk -# FIXME https://github.com/rust-lang/rust/issues/78911 -# ignore-32bit wrong/no cross compiler and sometimes we pass wrong gcc args (-m64) - # Regression test for issue #83112 # The generated test harness code contains spans with a dummy location, # but a non-dummy SyntaxContext. Previously, the incremental cache was encoding @@ -20,6 +17,6 @@ all: mkdir $(SRC)/mydir mkdir $(INCR) cp main.rs $(SRC)/main.rs - $(RUSTC) --test -C incremental=$(INCR) $(SRC)/main.rs + $(RUSTC) --test -C incremental=$(INCR) $(SRC)/main.rs --target $(TARGET) mv $(SRC)/main.rs $(SRC)/mydir/main.rs - $(RUSTC) --test -C incremental=$(INCR) $(SRC)/mydir/main.rs + $(RUSTC) --test -C incremental=$(INCR) $(SRC)/mydir/main.rs --target $(TARGET) From d9dc5d83e239fa0e411d99264b0462e8e94b350a Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Mon, 11 Jan 2021 18:24:54 +0000 Subject: [PATCH 170/370] run-make: skip issue-36710 on riscv64 and armhf The test assumes it can run target binaries on the host. This not true for riscv64 CI (or for other platforms using remote-test-server). --- src/test/run-make/issue-36710/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/run-make/issue-36710/Makefile b/src/test/run-make/issue-36710/Makefile index 3d93b2f6961..fbb3ec97d55 100644 --- a/src/test/run-make/issue-36710/Makefile +++ b/src/test/run-make/issue-36710/Makefile @@ -1,3 +1,7 @@ +# ignore-riscv64 $(call RUN,foo) expects to run the target executable natively +# so it won't work with remote-test-server +# ignore-arm Another build using remote-test-server + include ../../run-make-fulldeps/tools.mk all: foo From 8b40dd1f50db8ed3086ada80d42f9d834723ed58 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Sat, 20 Feb 2021 19:31:28 +0000 Subject: [PATCH 171/370] ci: docker: riscv64gc: specify host explicitly --- src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile b/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile index f3f52ed61d1..4377608700b 100644 --- a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile @@ -98,6 +98,6 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS --qemu-riscv64-rootfs=/tmp/rootfs -ENV SCRIPT python3 ../x.py --stage 2 test --target riscv64gc-unknown-linux-gnu +ENV SCRIPT python3 ../x.py --stage 2 test --host='' --target riscv64gc-unknown-linux-gnu ENV NO_CHANGE_USER=1 From b2a97ff415ca950e49448c3ad766246cf3a48443 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Sun, 21 Feb 2021 11:19:50 +0000 Subject: [PATCH 172/370] bootstrap: don't run linkcheck when crosscompiling When we cross compile, some things (and their documentation) are built for the host (e.g. rustc), while others (and their documentation) are built for the target. This generated documentation will have broken links between documentation for different platforms e.g. between rustc and cargo. --- src/bootstrap/test.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 86d940cd733..248c8a5f82b 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -122,7 +122,21 @@ impl Step for Linkcheck { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let builder = run.builder; - run.path("src/tools/linkchecker").default_condition(builder.config.docs) + let run = run.path("src/tools/linkchecker"); + let hosts = &builder.hosts; + let targets = &builder.targets; + + // if we have different hosts and targets, some things may be built for + // the host (e.g. rustc) and others for the target (e.g. std). The + // documentation built for each will contain broken links to + // docs built for the other platform (e.g. rustc linking to cargo) + if (hosts != targets) && !hosts.is_empty() && !targets.is_empty() { + panic!( + "Linkcheck currently does not support builds with different hosts and targets. +You can skip linkcheck with --exclude src/tools/linkchecker" + ); + } + run.default_condition(builder.config.docs) } fn make_run(run: RunConfig<'_>) { From 980961e33052c3f838db3879bd9e0f284252bb2f Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Sun, 21 Feb 2021 19:32:16 +0000 Subject: [PATCH 173/370] ci: docker: x86_64: specify host explicitly --- src/ci/docker/host-x86_64/x86_64-gnu-llvm-10/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-10/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-10/Dockerfile index 0d32a9ec5eb..c34198708c4 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-10/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-10/Dockerfile @@ -46,6 +46,7 @@ ENV SCRIPT python2.7 ../x.py --stage 2 test --exclude src/tools/tidy && \ # This is intended to make sure that both `--pass=check` continues to # work. # - python2.7 ../x.py --stage 2 test src/test/ui --pass=check --target=i686-unknown-linux-gnu && \ + python2.7 ../x.py --stage 2 test src/test/ui --pass=check \ + --host='' --target=i686-unknown-linux-gnu && \ # Run tidy at the very end, after all the other tests. python2.7 ../x.py --stage 2 test src/tools/tidy From e7505fb7454d946fd307b57e4cb0d45f8e50fdba Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Mon, 15 Mar 2021 18:00:14 +0000 Subject: [PATCH 174/370] test: run-make: flag tests which won't work in no-std environments --- src/test/run-make/incr-prev-body-beyond-eof/Makefile | 2 ++ src/test/run-make/issue-36710/Makefile | 1 + src/test/run-make/issue-83112-incr-test-moved-file/Makefile | 2 ++ 3 files changed, 5 insertions(+) diff --git a/src/test/run-make/incr-prev-body-beyond-eof/Makefile b/src/test/run-make/incr-prev-body-beyond-eof/Makefile index ae447e1bd9c..c57ce9c53e7 100644 --- a/src/test/run-make/incr-prev-body-beyond-eof/Makefile +++ b/src/test/run-make/incr-prev-body-beyond-eof/Makefile @@ -1,3 +1,5 @@ +# ignore-none no-std is not supported + include ../../run-make-fulldeps/tools.mk # Tests that we don't ICE during incremental compilation after modifying a diff --git a/src/test/run-make/issue-36710/Makefile b/src/test/run-make/issue-36710/Makefile index fbb3ec97d55..7014b763ae3 100644 --- a/src/test/run-make/issue-36710/Makefile +++ b/src/test/run-make/issue-36710/Makefile @@ -1,6 +1,7 @@ # ignore-riscv64 $(call RUN,foo) expects to run the target executable natively # so it won't work with remote-test-server # ignore-arm Another build using remote-test-server +# ignore-none no-std is not supported include ../../run-make-fulldeps/tools.mk diff --git a/src/test/run-make/issue-83112-incr-test-moved-file/Makefile b/src/test/run-make/issue-83112-incr-test-moved-file/Makefile index c89eebf3745..30bb259ef6d 100644 --- a/src/test/run-make/issue-83112-incr-test-moved-file/Makefile +++ b/src/test/run-make/issue-83112-incr-test-moved-file/Makefile @@ -1,5 +1,7 @@ include ../../run-make-fulldeps/tools.mk +# ignore-none no-std is not supported + # Regression test for issue #83112 # The generated test harness code contains spans with a dummy location, # but a non-dummy SyntaxContext. Previously, the incremental cache was encoding From 1fa48cf181f1fe7e1aba133be199804c652fe55c Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Tue, 16 Mar 2021 18:22:21 +0000 Subject: [PATCH 175/370] test: run-make: skip tests on unsupported platforms The tests issue-36710 and incr-prev-body-beyond-eof were changed in a previous commit so that the correct target was passed to rustc (previously rustc was building for the host not for the specific target). Since that change it turns out that these platforms never worked (they only appeared to work because rustc was actually building for the host architecture). The wasm architectures fall over trying to build the C++ file in issue-36710. They look for clang (which isn't installed in the test-various docker container). If clang is installed, they can't find a wasm c++ standard library to link to. nvtptx64-nvidia-cuda fails in rustc saying it can't find std. The rust platforms support page says that std is supported on cuda so this is surprising. dist-i586-gnu-i586-i686-musl can't find the C++ compiler. There is only a musl-gcc and no musl-g++ in /musl-i586/bin/. The Docker image probably needs tweaking. --- src/test/run-make/incr-prev-body-beyond-eof/Makefile | 1 + src/test/run-make/issue-36710/Makefile | 5 +++++ src/test/run-make/issue-83112-incr-test-moved-file/Makefile | 1 + 3 files changed, 7 insertions(+) diff --git a/src/test/run-make/incr-prev-body-beyond-eof/Makefile b/src/test/run-make/incr-prev-body-beyond-eof/Makefile index c57ce9c53e7..24eea3acaea 100644 --- a/src/test/run-make/incr-prev-body-beyond-eof/Makefile +++ b/src/test/run-make/incr-prev-body-beyond-eof/Makefile @@ -1,4 +1,5 @@ # ignore-none no-std is not supported +# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for `std` include ../../run-make-fulldeps/tools.mk diff --git a/src/test/run-make/issue-36710/Makefile b/src/test/run-make/issue-36710/Makefile index 7014b763ae3..b5270ad2ba9 100644 --- a/src/test/run-make/issue-36710/Makefile +++ b/src/test/run-make/issue-36710/Makefile @@ -2,6 +2,11 @@ # so it won't work with remote-test-server # ignore-arm Another build using remote-test-server # 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 +# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for `std` +# ignore-musl FIXME: this makefile needs teaching how to use a musl toolchain +# (see dist-i586-gnu-i586-i686-musl Dockerfile) include ../../run-make-fulldeps/tools.mk diff --git a/src/test/run-make/issue-83112-incr-test-moved-file/Makefile b/src/test/run-make/issue-83112-incr-test-moved-file/Makefile index 30bb259ef6d..2f796e5b2fc 100644 --- a/src/test/run-make/issue-83112-incr-test-moved-file/Makefile +++ b/src/test/run-make/issue-83112-incr-test-moved-file/Makefile @@ -1,6 +1,7 @@ include ../../run-make-fulldeps/tools.mk # ignore-none no-std is not supported +# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for 'std' # Regression test for issue #83112 # The generated test harness code contains spans with a dummy location, From 84542d22a71cb486b0f79cf3bfd7a264b688030c Mon Sep 17 00:00:00 2001 From: klensy Date: Sun, 28 Mar 2021 19:34:38 +0300 Subject: [PATCH 176/370] ffi::c_str added tests for empty strings --- library/std/src/ffi/c_str/tests.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/library/std/src/ffi/c_str/tests.rs b/library/std/src/ffi/c_str/tests.rs index 4dff3df63a8..4f7ba9ad437 100644 --- a/library/std/src/ffi/c_str/tests.rs +++ b/library/std/src/ffi/c_str/tests.rs @@ -193,3 +193,19 @@ fn cstr_index_from_empty() { let cstr = CStr::from_bytes_with_nul(original).unwrap(); let _ = &cstr[original.len()..]; } + +#[test] +fn c_string_from_empty_string() { + let original = ""; + let cstring = CString::new(original).unwrap(); + assert_eq!(original.as_bytes(), cstring.as_bytes()); + assert_eq!([b'\0'], cstring.as_bytes_with_nul()); +} + +#[test] +fn c_str_from_empty_string() { + let original = b"\0"; + let cstr = CStr::from_bytes_with_nul(original).unwrap(); + assert_eq!([] as [u8; 0], cstr.to_bytes()); + assert_eq!([b'\0'], cstr.to_bytes_with_nul()); +} From cc5392e76bb164a8a08bf7c4e99fdf0bf339193a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 28 Mar 2021 23:18:39 +0300 Subject: [PATCH 177/370] linker: Use data execution prevention options by default when linker supports them --- compiler/rustc_codegen_ssa/src/back/link.rs | 4 ++++ compiler/rustc_codegen_ssa/src/back/linker.rs | 13 +++++++++++++ compiler/rustc_target/src/spec/dragonfly_base.rs | 12 +----------- compiler/rustc_target/src/spec/freebsd_base.rs | 12 +----------- compiler/rustc_target/src/spec/linux_base.rs | 12 +----------- compiler/rustc_target/src/spec/linux_kernel_base.rs | 8 +------- compiler/rustc_target/src/spec/msvc_base.rs | 7 ------- compiler/rustc_target/src/spec/openbsd_base.rs | 12 +----------- compiler/rustc_target/src/spec/redox_base.rs | 12 +----------- compiler/rustc_target/src/spec/windows_gnu_base.rs | 2 -- .../src/spec/x86_64_fortanix_unknown_sgx.rs | 2 -- 11 files changed, 23 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index e7938fe8af9..686ebc13ea3 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1651,6 +1651,10 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( cmd.add_eh_frame_header(); } + // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER + // Make the binary compatible with data execution prevention schemes. + cmd.add_no_exec(); + // NO-OPT-OUT, OBJECT-FILES-NO // Avoid linking to dynamic libraries unless they satisfy some undefined symbols // at the point at which they are specified on the command line. diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 592675d916a..e19274e579b 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -130,6 +130,7 @@ pub trait Linker { fn group_end(&mut self); fn linker_plugin_lto(&mut self); fn add_eh_frame_header(&mut self) {} + fn add_no_exec(&mut self) {} fn add_as_needed(&mut self) {} fn finalize(&mut self); } @@ -643,6 +644,14 @@ impl<'a> Linker for GccLinker<'a> { self.linker_arg("--eh-frame-hdr"); } + fn add_no_exec(&mut self) { + if self.sess.target.is_like_windows { + self.linker_arg("--nxcompat"); + } else if self.sess.target.linker_is_gnu { + self.linker_arg("-znoexecstack"); + } + } + fn add_as_needed(&mut self) { if self.sess.target.linker_is_gnu { self.linker_arg("--as-needed"); @@ -885,6 +894,10 @@ impl<'a> Linker for MsvcLinker<'a> { fn linker_plugin_lto(&mut self) { // Do nothing } + + fn add_no_exec(&mut self) { + self.cmd.arg("/NXCOMPAT"); + } } pub struct EmLinker<'a> { diff --git a/compiler/rustc_target/src/spec/dragonfly_base.rs b/compiler/rustc_target/src/spec/dragonfly_base.rs index 41d372cc6db..dd017098782 100644 --- a/compiler/rustc_target/src/spec/dragonfly_base.rs +++ b/compiler/rustc_target/src/spec/dragonfly_base.rs @@ -1,15 +1,6 @@ -use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; +use crate::spec::{RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { - let mut args = LinkArgs::new(); - args.insert( - LinkerFlavor::Gcc, - vec![ - // Always enable NX protection when it is available - "-Wl,-z,noexecstack".to_string(), - ], - ); - TargetOptions { os: "dragonfly".to_string(), dynamic_linking: true, @@ -17,7 +8,6 @@ pub fn opts() -> TargetOptions { os_family: Some("unix".to_string()), linker_is_gnu: true, has_rpath: true, - pre_link_args: args, position_independent_executables: true, relro_level: RelroLevel::Full, dwarf_version: Some(2), diff --git a/compiler/rustc_target/src/spec/freebsd_base.rs b/compiler/rustc_target/src/spec/freebsd_base.rs index 86db2bf8eed..ad3383cc5f2 100644 --- a/compiler/rustc_target/src/spec/freebsd_base.rs +++ b/compiler/rustc_target/src/spec/freebsd_base.rs @@ -1,15 +1,6 @@ -use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; +use crate::spec::{RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { - let mut args = LinkArgs::new(); - args.insert( - LinkerFlavor::Gcc, - vec![ - // Always enable NX protection when it is available - "-Wl,-z,noexecstack".to_string(), - ], - ); - TargetOptions { os: "freebsd".to_string(), dynamic_linking: true, @@ -17,7 +8,6 @@ pub fn opts() -> TargetOptions { os_family: Some("unix".to_string()), linker_is_gnu: true, has_rpath: true, - pre_link_args: args, position_independent_executables: true, eliminate_frame_pointer: false, // FIXME 43575 relro_level: RelroLevel::Full, diff --git a/compiler/rustc_target/src/spec/linux_base.rs b/compiler/rustc_target/src/spec/linux_base.rs index aa2ff7bb399..eeefd056e4b 100644 --- a/compiler/rustc_target/src/spec/linux_base.rs +++ b/compiler/rustc_target/src/spec/linux_base.rs @@ -1,15 +1,6 @@ -use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; +use crate::spec::{RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { - let mut args = LinkArgs::new(); - args.insert( - LinkerFlavor::Gcc, - vec![ - // Always enable NX protection when it is available - "-Wl,-z,noexecstack".to_string(), - ], - ); - TargetOptions { os: "linux".to_string(), dynamic_linking: true, @@ -17,7 +8,6 @@ pub fn opts() -> TargetOptions { os_family: Some("unix".to_string()), linker_is_gnu: true, has_rpath: true, - pre_link_args: args, position_independent_executables: true, relro_level: RelroLevel::Full, has_elf_tls: true, diff --git a/compiler/rustc_target/src/spec/linux_kernel_base.rs b/compiler/rustc_target/src/spec/linux_kernel_base.rs index e71c80e556e..d17d729c289 100644 --- a/compiler/rustc_target/src/spec/linux_kernel_base.rs +++ b/compiler/rustc_target/src/spec/linux_kernel_base.rs @@ -1,11 +1,6 @@ -use crate::spec::{ - LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, RelroLevel, StackProbeType, TargetOptions, -}; +use crate::spec::{PanicStrategy, RelocModel, RelroLevel, StackProbeType, TargetOptions}; pub fn opts() -> TargetOptions { - let mut pre_link_args = LinkArgs::new(); - pre_link_args.insert(LinkerFlavor::Gcc, vec!["-Wl,-z,noexecstack".to_string()]); - TargetOptions { env: "gnu".to_string(), disable_redzone: true, @@ -17,7 +12,6 @@ pub fn opts() -> TargetOptions { needs_plt: true, relro_level: RelroLevel::Full, relocation_model: RelocModel::Static, - pre_link_args, ..Default::default() } diff --git a/compiler/rustc_target/src/spec/msvc_base.rs b/compiler/rustc_target/src/spec/msvc_base.rs index 39c0d5f0bb4..4ed7685ca07 100644 --- a/compiler/rustc_target/src/spec/msvc_base.rs +++ b/compiler/rustc_target/src/spec/msvc_base.rs @@ -5,13 +5,6 @@ pub fn opts() -> TargetOptions { // Suppress the verbose logo and authorship debugging output, which would needlessly // clog any log files. "/NOLOGO".to_string(), - // Tell the compiler that non-code sections can be marked as non-executable, - // including stack pages. - // UEFI is fully compatible to non-executable data pages. - // In fact, firmware might enforce this, so we better let the linker know about this, - // so it will fail if the compiler ever tries placing code on the stack - // (e.g., trampoline constructs and alike). - "/NXCOMPAT".to_string(), ]; let mut pre_link_args = LinkArgs::new(); pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc.clone()); diff --git a/compiler/rustc_target/src/spec/openbsd_base.rs b/compiler/rustc_target/src/spec/openbsd_base.rs index 0aeefba3647..a6fd01ab110 100644 --- a/compiler/rustc_target/src/spec/openbsd_base.rs +++ b/compiler/rustc_target/src/spec/openbsd_base.rs @@ -1,15 +1,6 @@ -use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; +use crate::spec::{RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { - let mut args = LinkArgs::new(); - args.insert( - LinkerFlavor::Gcc, - vec![ - // Always enable NX protection when it is available - "-Wl,-z,noexecstack".to_string(), - ], - ); - TargetOptions { os: "openbsd".to_string(), dynamic_linking: true, @@ -18,7 +9,6 @@ pub fn opts() -> TargetOptions { linker_is_gnu: true, has_rpath: true, abi_return_struct_as_int: true, - pre_link_args: args, position_independent_executables: true, eliminate_frame_pointer: false, // FIXME 43575 relro_level: RelroLevel::Full, diff --git a/compiler/rustc_target/src/spec/redox_base.rs b/compiler/rustc_target/src/spec/redox_base.rs index 20c91708faa..0afb4a72ac1 100644 --- a/compiler/rustc_target/src/spec/redox_base.rs +++ b/compiler/rustc_target/src/spec/redox_base.rs @@ -1,15 +1,6 @@ -use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; +use crate::spec::{RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { - let mut args = LinkArgs::new(); - args.insert( - LinkerFlavor::Gcc, - vec![ - // Always enable NX protection when it is available - "-Wl,-z,noexecstack".to_string(), - ], - ); - TargetOptions { os: "redox".to_string(), env: "relibc".to_string(), @@ -18,7 +9,6 @@ pub fn opts() -> TargetOptions { os_family: Some("unix".to_string()), linker_is_gnu: true, has_rpath: true, - pre_link_args: args, position_independent_executables: true, relro_level: RelroLevel::Full, has_elf_tls: true, diff --git a/compiler/rustc_target/src/spec/windows_gnu_base.rs b/compiler/rustc_target/src/spec/windows_gnu_base.rs index f556a13a519..7036f338150 100644 --- a/compiler/rustc_target/src/spec/windows_gnu_base.rs +++ b/compiler/rustc_target/src/spec/windows_gnu_base.rs @@ -9,8 +9,6 @@ pub fn opts() -> TargetOptions { // Tell GCC to avoid linker plugins, because we are not bundling // them with Windows installer, and Rust does its own LTO anyways. "-fno-use-linker-plugin".to_string(), - // Always enable DEP (NX bit) when it is available - "-Wl,--nxcompat".to_string(), // Enable ASLR "-Wl,--dynamicbase".to_string(), // ASLR will rebase it anyway so leaving that option enabled only leads to confusion diff --git a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs index aacbdbdeefb..6365e5650e4 100644 --- a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs +++ b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs @@ -4,8 +4,6 @@ use super::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions}; pub fn target() -> Target { const PRE_LINK_ARGS: &[&str] = &[ - "-z", - "noexecstack", "-e", "elf_entry", "-Bstatic", From c20ba9cdae257c70c934e2c9dc1a77c1798d8113 Mon Sep 17 00:00:00 2001 From: ltdk Date: Sat, 24 Oct 2020 00:45:41 -0400 Subject: [PATCH 178/370] Add escape_default method to u8 and [u8] --- library/core/src/num/mod.rs | 26 ++++++++++ library/core/src/slice/ascii.rs | 92 +++++++++++++++++++++++++++++++++ library/core/src/slice/mod.rs | 3 ++ 3 files changed, 121 insertions(+) diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index f0bd976ba83..6032dc9a2d3 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -2,6 +2,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::ascii; use crate::intrinsics; use crate::mem; use crate::str::FromStr; @@ -661,6 +662,31 @@ impl u8 { pub const fn is_ascii_control(&self) -> bool { matches!(*self, b'\0'..=b'\x1F' | b'\x7F') } + + /// Returns an iterator that produces an escaped version of a `u8`, + /// treating it as an ASCII character. + /// + /// The behavior is identical to [`ascii::escape_default`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(inherent_ascii_escape)] + /// + /// assert_eq!("0", b'0'.escape_ascii().to_string()); + /// assert_eq!("\\t", b'\t'.escape_ascii().to_string()); + /// assert_eq!("\\r", b'\r'.escape_ascii().to_string()); + /// assert_eq!("\\n", b'\n'.escape_ascii().to_string()); + /// assert_eq!("\\'", b'\''.escape_ascii().to_string()); + /// assert_eq!("\\\"", b'"'.escape_ascii().to_string()); + /// assert_eq!("\\\\", b'\\'.escape_ascii().to_string()); + /// assert_eq!("\\x9d", b'\x9d'.escape_ascii().to_string()); + /// ``` + #[unstable(feature = "inherent_ascii_escape", issue = "77174")] + #[inline] + pub fn escape_ascii(&self) -> ascii::EscapeDefault { + ascii::escape_default(*self) + } } #[lang = "u16"] diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 009ef9e0a9c..22fa08b9795 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -1,7 +1,10 @@ //! Operations on ASCII `[u8]`. +use crate::ascii; +use crate::fmt::{self, Write}; use crate::iter; use crate::mem; +use crate::ops; #[lang = "slice_u8"] #[cfg(not(test))] @@ -56,6 +59,95 @@ impl [u8] { byte.make_ascii_lowercase(); } } + + /// Returns an iterator that produces an escaped version of this slice, + /// treating it as an ASCII string. + /// + /// # Examples + /// + /// ``` + /// #![feature(inherent_ascii_escape)] + /// + /// let s = b"0\t\r\n'\"\\\x9d"; + /// let escaped = s.escape_ascii().to_string(); + /// assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d"); + /// ``` + #[unstable(feature = "inherent_ascii_escape", issue = "77174")] + pub fn escape_ascii(&self) -> EscapeAscii<'_> { + EscapeAscii { inner: self.iter().flat_map(EscapeByte) } + } +} + +impl_fn_for_zst! { + #[derive(Clone)] + struct EscapeByte impl Fn = |byte: &u8| -> ascii::EscapeDefault { + ascii::escape_default(*byte) + }; +} + +/// An iterator over the escaped version of a byte slice. +/// +/// This `struct` is created by the [`slice::escape_ascii`] method. See its +/// documentation for more information. +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +#[derive(Clone)] +pub struct EscapeAscii<'a> { + inner: iter::FlatMap, ascii::EscapeDefault, EscapeByte>, +} + +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +impl<'a> iter::Iterator for EscapeAscii<'a> { + type Item = u8; + #[inline] + fn next(&mut self) -> Option { + self.inner.next() + } + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } + #[inline] + fn try_fold(&mut self, init: Acc, fold: Fold) -> R + where + Fold: FnMut(Acc, Self::Item) -> R, + R: ops::Try, + { + self.inner.try_fold(init, fold) + } + #[inline] + fn fold(self, init: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.inner.fold(init, fold) + } + #[inline] + fn last(mut self) -> Option { + self.next_back() + } +} + +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +impl<'a> iter::DoubleEndedIterator for EscapeAscii<'a> { + fn next_back(&mut self) -> Option { + self.inner.next_back() + } +} +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +impl<'a> iter::ExactSizeIterator for EscapeAscii<'a> {} +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +impl<'a> iter::FusedIterator for EscapeAscii<'a> {} +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +impl<'a> fmt::Display for EscapeAscii<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.clone().try_for_each(|b| f.write_char(b as char)) + } +} +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +impl<'a> fmt::Debug for EscapeAscii<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.pad("EscapeAscii { .. }") + } } /// Returns `true` if any byte in the word `v` is nonascii (>= 128). Snarfed diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index d7a28c8d08f..59fad8c813c 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -81,6 +81,9 @@ pub use index::SliceIndex; #[unstable(feature = "slice_range", issue = "76393")] pub use index::range; +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +pub use ascii::EscapeAscii; + #[lang = "slice"] #[cfg(not(test))] impl [T] { From 56347a173a49ef1232ced3974ccbf8e16c5da78c Mon Sep 17 00:00:00 2001 From: Camelid Date: Sun, 28 Mar 2021 17:02:26 -0700 Subject: [PATCH 179/370] Point to disambiguator instead of whole link And, now that we do that, we can remove the explanatory note since the error span should make it clear what the disambiguator is. --- src/librustdoc/html/markdown.rs | 1 + .../passes/collect_intra_doc_links.rs | 39 ++++++++++++++----- .../intra-doc/unknown-disambiguator.stderr | 17 +++----- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index b39f9f87892..c44514ed3cb 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1162,6 +1162,7 @@ crate fn plain_text_summary(md: &str) -> String { s } +#[derive(Debug)] crate struct MarkdownLink { pub kind: LinkType, pub link: String, diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index f5c5c9ca4aa..417637d2384 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -950,6 +950,7 @@ impl LinkCollector<'_, '_> { } let link = ori_link.link.replace("`", ""); + let no_backticks_range = range_between_backticks(&ori_link); let parts = link.split('#').collect::>(); let (link, extra_fragment) = if parts.len() > 2 { // A valid link can't have multiple #'s @@ -976,8 +977,10 @@ impl LinkCollector<'_, '_> { let (mut path_str, disambiguator) = match Disambiguator::from_str(&link) { Ok(Some((d, path))) => (path.trim(), Some(d)), Ok(None) => (link.trim(), None), - Err(err_msg) => { - disambiguator_error(self.cx, &item, dox, ori_link.range, &err_msg); + Err((err_msg, relative_range)) => { + let disambiguator_range = (no_backticks_range.start + relative_range.start) + ..(no_backticks_range.start + relative_range.end); + disambiguator_error(self.cx, &item, dox, disambiguator_range, &err_msg); return None; } }; @@ -1491,6 +1494,27 @@ impl LinkCollector<'_, '_> { } } +/// Get the section of a link between the backticks, +/// or the whole link if there aren't any backticks. +/// +/// For example: +/// +/// ```text +/// [`Foo`] +/// ^^^ +/// ``` +fn range_between_backticks(ori_link: &MarkdownLink) -> Range { + let after_first_backtick_group = ori_link.link.bytes().position(|b| b != b'`').unwrap_or(0); + let before_second_backtick_group = ori_link + .link + .bytes() + .skip(after_first_backtick_group) + .position(|b| b == b'`') + .unwrap_or(ori_link.link.len()); + (ori_link.range.start + after_first_backtick_group) + ..(ori_link.range.start + before_second_backtick_group) +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] /// Disambiguators for a link. enum Disambiguator { @@ -1522,7 +1546,7 @@ impl Disambiguator { /// This returns `Ok(Some(...))` if a disambiguator was found, /// `Ok(None)` if no disambiguator was found, or `Err(...)` /// if there was a problem with the disambiguator. - fn from_str(link: &str) -> Result, String> { + fn from_str(link: &str) -> Result, (String, Range)> { use Disambiguator::{Kind, Namespace as NS, Primitive}; let find_suffix = || { @@ -1558,7 +1582,7 @@ impl Disambiguator { "value" => NS(Namespace::ValueNS), "macro" => NS(Namespace::MacroNS), "prim" | "primitive" => Primitive, - _ => return Err(format!("unknown disambiguator `{}`", prefix)), + _ => return Err((format!("unknown disambiguator `{}`", prefix), 0..idx)), }; Ok(Some((d, &rest[1..]))) } else { @@ -1994,12 +2018,7 @@ fn disambiguator_error( link_range: Range, msg: &str, ) { - report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, item, dox, &link_range, |diag, _sp| { - diag.note( - "the disambiguator is the part of the link before the `@` sign, \ - or a suffix such as `()` for functions", - ); - }); + report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, item, dox, &link_range, |_diag, _sp| {}); } /// Report an ambiguity error, where there were multiple possible resolutions. diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr index 9e7699eea9a..2904603dfc3 100644 --- a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr +++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr @@ -2,7 +2,7 @@ error: unknown disambiguator `foo` --> $DIR/unknown-disambiguator.rs:1:17 | LL | //! Linking to [foo@banana] and [`bar@banana!()`]. - | ^^^^^^^^^^ + | ^^^ | note: the lint level is defined here --> $DIR/unknown-disambiguator.rs:8:9 @@ -10,31 +10,24 @@ note: the lint level is defined here LL | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]` - = note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions error: unknown disambiguator `bar` - --> $DIR/unknown-disambiguator.rs:1:34 + --> $DIR/unknown-disambiguator.rs:1:35 | LL | //! Linking to [foo@banana] and [`bar@banana!()`]. - | ^^^^^^^^^^^^^^^ - | - = note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions + | ^^^ error: unknown disambiguator `` --> $DIR/unknown-disambiguator.rs:4:31 | LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). - | ^^^^^^^^^^ - | - = note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions + | ^ error: unknown disambiguator `` --> $DIR/unknown-disambiguator.rs:4:57 | LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). - | ^^^^^^^^^^^ - | - = note: the disambiguator is the part of the link before the `@` sign, or a suffix such as `()` for functions + | ^ error: aborting due to 4 previous errors From 5497f158af58bf6420222472bbaeeae78081d26f Mon Sep 17 00:00:00 2001 From: Camelid Date: Sun, 28 Mar 2021 17:16:54 -0700 Subject: [PATCH 180/370] Add test for weird backticks placement --- .../intra-doc/unknown-disambiguator.rs | 7 ++++-- .../intra-doc/unknown-disambiguator.stderr | 24 ++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs index 9222025367d..925fc515a3e 100644 --- a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs +++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs @@ -1,10 +1,13 @@ +#![deny(warnings)] + //! Linking to [foo@banana] and [`bar@banana!()`]. //~^ ERROR unknown disambiguator `foo` //~| ERROR unknown disambiguator `bar` //! And to [no disambiguator](@nectarine) and [another](@apricot!()). //~^ ERROR unknown disambiguator `` //~| ERROR unknown disambiguator `` - -#![deny(warnings)] +//! And with weird backticks: [``foo@hello``] [foo`@`hello]. +//~^ ERROR unknown disambiguator `foo` +//~| ERROR unknown disambiguator `foo` fn main() {} diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr index 2904603dfc3..195aaca32a2 100644 --- a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr +++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr @@ -1,33 +1,45 @@ error: unknown disambiguator `foo` - --> $DIR/unknown-disambiguator.rs:1:17 + --> $DIR/unknown-disambiguator.rs:3:17 | LL | //! Linking to [foo@banana] and [`bar@banana!()`]. | ^^^ | note: the lint level is defined here - --> $DIR/unknown-disambiguator.rs:8:9 + --> $DIR/unknown-disambiguator.rs:1:9 | LL | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]` error: unknown disambiguator `bar` - --> $DIR/unknown-disambiguator.rs:1:35 + --> $DIR/unknown-disambiguator.rs:3:35 | LL | //! Linking to [foo@banana] and [`bar@banana!()`]. | ^^^ +error: unknown disambiguator `foo` + --> $DIR/unknown-disambiguator.rs:9:34 + | +LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello]. + | ^^^ + +error: unknown disambiguator `foo` + --> $DIR/unknown-disambiguator.rs:9:48 + | +LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello]. + | ^^^ + error: unknown disambiguator `` - --> $DIR/unknown-disambiguator.rs:4:31 + --> $DIR/unknown-disambiguator.rs:6:31 | LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). | ^ error: unknown disambiguator `` - --> $DIR/unknown-disambiguator.rs:4:57 + --> $DIR/unknown-disambiguator.rs:6:57 | LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). | ^ -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors From 141df6f60e28c83711db5a2a94d5c4ff5e9aecaa Mon Sep 17 00:00:00 2001 From: Camelid Date: Sun, 28 Mar 2021 17:22:45 -0700 Subject: [PATCH 181/370] Inline `find_suffix` closure that's only used once --- .../passes/collect_intra_doc_links.rs | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 417637d2384..55978ca551b 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1549,23 +1549,6 @@ impl Disambiguator { fn from_str(link: &str) -> Result, (String, Range)> { use Disambiguator::{Kind, Namespace as NS, Primitive}; - let find_suffix = || { - let suffixes = [ - ("!()", DefKind::Macro(MacroKind::Bang)), - ("()", DefKind::Fn), - ("!", DefKind::Macro(MacroKind::Bang)), - ]; - for &(suffix, kind) in &suffixes { - if let Some(link) = link.strip_suffix(suffix) { - // Avoid turning `!` or `()` into an empty string - if !link.is_empty() { - return Some((Kind(kind), link)); - } - } - } - None - }; - if let Some(idx) = link.find('@') { let (prefix, rest) = link.split_at(idx); let d = match prefix { @@ -1586,7 +1569,20 @@ impl Disambiguator { }; Ok(Some((d, &rest[1..]))) } else { - Ok(find_suffix()) + let suffixes = [ + ("!()", DefKind::Macro(MacroKind::Bang)), + ("()", DefKind::Fn), + ("!", DefKind::Macro(MacroKind::Bang)), + ]; + for &(suffix, kind) in &suffixes { + if let Some(link) = link.strip_suffix(suffix) { + // Avoid turning `!` or `()` into an empty string + if !link.is_empty() { + return Ok(Some((Kind(kind), link))); + } + } + } + Ok(None) } } From fa89c0fbcfa8f4d44f153b1195ec5a305540ffc4 Mon Sep 17 00:00:00 2001 From: The8472 Date: Mon, 29 Mar 2021 04:22:34 +0200 Subject: [PATCH 182/370] add testcase for double-drop during Vec in-place collection --- library/alloc/tests/vec.rs | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index c142536cd2d..b926c697d58 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1027,7 +1027,7 @@ fn test_from_iter_specialization_head_tail_drop() { } #[test] -fn test_from_iter_specialization_panic_drop() { +fn test_from_iter_specialization_panic_during_iteration_drops() { let drop_count: Vec<_> = (0..=2).map(|_| Rc::new(())).collect(); let src: Vec<_> = drop_count.iter().cloned().collect(); let iter = src.into_iter(); @@ -1050,6 +1050,42 @@ fn test_from_iter_specialization_panic_drop() { ); } +#[test] +fn test_from_iter_specialization_panic_during_drop_leaks() { + static mut DROP_COUNTER: usize = 0; + + #[derive(Debug)] + enum Droppable { + DroppedTwice(Box), + PanicOnDrop, + } + + impl Drop for Droppable { + fn drop(&mut self) { + match self { + Droppable::DroppedTwice(_) => { + unsafe { + DROP_COUNTER += 1; + } + println!("Dropping!") + } + Droppable::PanicOnDrop => { + if !std::thread::panicking() { + panic!(); + } + } + } + } + } + + let _ = std::panic::catch_unwind(AssertUnwindSafe(|| { + let v = vec![Droppable::DroppedTwice(Box::new(123)), Droppable::PanicOnDrop]; + let _ = v.into_iter().take(0).collect::>(); + })); + + assert_eq!(unsafe { DROP_COUNTER }, 1); +} + #[test] fn test_cow_from() { let borrowed: &[_] = &["borrowed", "(slice)"]; From 421f5d282a51e130d3ca7c4524d8ad6753437da9 Mon Sep 17 00:00:00 2001 From: The8472 Date: Mon, 29 Mar 2021 04:22:48 +0200 Subject: [PATCH 183/370] fix double-drop in in-place collect specialization --- library/alloc/src/vec/into_iter.rs | 27 ++++++++++++++------- library/alloc/src/vec/source_iter_marker.rs | 4 +-- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index bcbdffabc7f..324e894bafd 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -85,20 +85,29 @@ impl IntoIter { ptr::slice_from_raw_parts_mut(self.ptr as *mut T, self.len()) } - pub(super) fn drop_remaining(&mut self) { - unsafe { - ptr::drop_in_place(self.as_mut_slice()); - } - self.ptr = self.end; - } + /// Drops remaining elements and relinquishes the backing allocation. + /// + /// This is roughly equivalent to the following, but more efficient + /// + /// ``` + /// # let mut into_iter = Vec::::with_capacity(10).into_iter(); + /// (&mut into_iter).for_each(core::mem::drop); + /// unsafe { core::ptr::write(&mut into_iter, Vec::new().into_iter()); } + /// ``` + pub(super) fn forget_allocation_drop_remaining(&mut self) { + let remaining = self.as_raw_mut_slice(); - /// Relinquishes the backing allocation, equivalent to - /// `ptr::write(&mut self, Vec::new().into_iter())` - pub(super) fn forget_allocation(&mut self) { + // overwrite the individual fields instead of creating a new + // struct and then overwriting &mut self. + // this creates less assembly self.cap = 0; self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) }; self.ptr = self.buf.as_ptr(); self.end = self.buf.as_ptr(); + + unsafe { + ptr::drop_in_place(remaining); + } } } diff --git a/library/alloc/src/vec/source_iter_marker.rs b/library/alloc/src/vec/source_iter_marker.rs index 50882fc1767..e857d284d3a 100644 --- a/library/alloc/src/vec/source_iter_marker.rs +++ b/library/alloc/src/vec/source_iter_marker.rs @@ -69,9 +69,9 @@ where } // drop any remaining values at the tail of the source - src.drop_remaining(); // but prevent drop of the allocation itself once IntoIter goes out of scope - src.forget_allocation(); + // if the drop panics then we also leak any elements collected into dst_buf + src.forget_allocation_drop_remaining(); let vec = unsafe { Vec::from_raw_parts(dst_buf, len, cap) }; From 0969bc6dde001e01e7e1f58c8ccd7750f8a49ae1 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 29 Mar 2021 10:26:20 +0200 Subject: [PATCH 184/370] Rustup to rustc 1.53.0-nightly (4a20eb6a9 2021-03-28) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index b3de18e5550..2917fc7ee39 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-03-26" +channel = "nightly-2021-03-29" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 29d4a7d3777b1c485e173f423d2dee77df93e953 Mon Sep 17 00:00:00 2001 From: JohnTitor Date: Mon, 29 Mar 2021 17:31:12 +0900 Subject: [PATCH 185/370] Add a regression test for issue-82792 --- .../const-generics/defaults/repr-c-issue-82792.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/test/ui/const-generics/defaults/repr-c-issue-82792.rs diff --git a/src/test/ui/const-generics/defaults/repr-c-issue-82792.rs b/src/test/ui/const-generics/defaults/repr-c-issue-82792.rs new file mode 100644 index 00000000000..18ecf467299 --- /dev/null +++ b/src/test/ui/const-generics/defaults/repr-c-issue-82792.rs @@ -0,0 +1,14 @@ +// Regression test for #82792. + +// run-pass + +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] + +#[repr(C)] +pub struct Loaf { + head: [T; N], + slice: [T], +} + +fn main() {} From c9562fd2d0cac144835e552f299c3a28e0a29ba6 Mon Sep 17 00:00:00 2001 From: JohnTitor Date: Mon, 29 Mar 2021 17:32:27 +0900 Subject: [PATCH 186/370] Prefer 4 spaces --- .../defaults/complex-unord-param.rs | 18 +++---- .../defaults/default-annotation.rs | 4 +- .../ui/const-generics/defaults/mismatch.rs | 24 ++++----- .../const-generics/defaults/mismatch.stderr | 50 +++++++++---------- .../const-generics/defaults/needs-feature.rs | 2 +- .../defaults/simple-defaults.rs | 6 +-- 6 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/test/ui/const-generics/defaults/complex-unord-param.rs b/src/test/ui/const-generics/defaults/complex-unord-param.rs index 82b3627d22f..d24e403e017 100644 --- a/src/test/ui/const-generics/defaults/complex-unord-param.rs +++ b/src/test/ui/const-generics/defaults/complex-unord-param.rs @@ -6,16 +6,16 @@ #![allow(dead_code)] struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> { - //[min]~^ ERROR type parameters must be declared prior to const parameters - args: &'a [&'a [T; M]; N], - specifier: A, + //[min]~^ ERROR type parameters must be declared prior to const parameters + args: &'a [&'a [T; M]; N], + specifier: A, } fn main() { - let array = [1, 2, 3]; - let nest = [&array]; - let _ = NestedArrays { - args: &nest, - specifier: true, - }; + let array = [1, 2, 3]; + let nest = [&array]; + let _ = NestedArrays { + args: &nest, + specifier: true, + }; } diff --git a/src/test/ui/const-generics/defaults/default-annotation.rs b/src/test/ui/const-generics/defaults/default-annotation.rs index e6e8d732bee..3febb7cffbf 100644 --- a/src/test/ui/const-generics/defaults/default-annotation.rs +++ b/src/test/ui/const-generics/defaults/default-annotation.rs @@ -13,8 +13,8 @@ pub struct ConstDefaultUnstable; #[stable(feature = "const_default_unstable", since="none")] pub struct ConstDefaultStable; fn main() {} diff --git a/src/test/ui/const-generics/defaults/mismatch.rs b/src/test/ui/const-generics/defaults/mismatch.rs index bf578468bb6..d85b756f538 100644 --- a/src/test/ui/const-generics/defaults/mismatch.rs +++ b/src/test/ui/const-generics/defaults/mismatch.rs @@ -8,16 +8,16 @@ pub struct Example3(T); pub struct Example4; fn main() { - let e: Example::<13> = (); - //~^ Error: mismatched types - let e: Example2:: = (); - //~^ Error: mismatched types - let e: Example3::<13, u32> = (); - //~^ Error: mismatched types - let e: Example3::<7> = (); - //~^ Error: mismatched types - // FIXME(const_generics_defaults): There should be a note for the error below, but it is - // missing. - let e: Example4::<7> = (); - //~^ Error: mismatched types + let e: Example::<13> = (); + //~^ Error: mismatched types + let e: Example2:: = (); + //~^ Error: mismatched types + let e: Example3::<13, u32> = (); + //~^ Error: mismatched types + let e: Example3::<7> = (); + //~^ Error: mismatched types + // FIXME(const_generics_defaults): There should be a note for the error below, but it is + // missing. + let e: Example4::<7> = (); + //~^ Error: mismatched types } diff --git a/src/test/ui/const-generics/defaults/mismatch.stderr b/src/test/ui/const-generics/defaults/mismatch.stderr index c66eb4cd645..ff72c71c40f 100644 --- a/src/test/ui/const-generics/defaults/mismatch.stderr +++ b/src/test/ui/const-generics/defaults/mismatch.stderr @@ -1,51 +1,51 @@ error[E0308]: mismatched types - --> $DIR/mismatch.rs:11:26 + --> $DIR/mismatch.rs:11:28 | -LL | let e: Example::<13> = (); - | ------------- ^^ expected struct `Example`, found `()` - | | - | expected due to this +LL | let e: Example::<13> = (); + | ------------- ^^ expected struct `Example`, found `()` + | | + | expected due to this error[E0308]: mismatched types - --> $DIR/mismatch.rs:13:32 + --> $DIR/mismatch.rs:13:34 | -LL | let e: Example2:: = (); - | ------------------- ^^ expected struct `Example2`, found `()` - | | - | expected due to this +LL | let e: Example2:: = (); + | ------------------- ^^ expected struct `Example2`, found `()` + | | + | expected due to this | = note: expected struct `Example2` found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:15:32 + --> $DIR/mismatch.rs:15:34 | -LL | let e: Example3::<13, u32> = (); - | ------------------- ^^ expected struct `Example3`, found `()` - | | - | expected due to this +LL | let e: Example3::<13, u32> = (); + | ------------------- ^^ expected struct `Example3`, found `()` + | | + | expected due to this | = note: expected struct `Example3` found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:17:26 + --> $DIR/mismatch.rs:17:28 | -LL | let e: Example3::<7> = (); - | ------------- ^^ expected struct `Example3`, found `()` - | | - | expected due to this +LL | let e: Example3::<7> = (); + | ------------- ^^ expected struct `Example3`, found `()` + | | + | expected due to this | = note: expected struct `Example3<7_usize>` found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:21:26 + --> $DIR/mismatch.rs:21:28 | -LL | let e: Example4::<7> = (); - | ------------- ^^ expected struct `Example4`, found `()` - | | - | expected due to this +LL | let e: Example4::<7> = (); + | ------------- ^^ expected struct `Example4`, found `()` + | | + | expected due to this error: aborting due to 5 previous errors diff --git a/src/test/ui/const-generics/defaults/needs-feature.rs b/src/test/ui/const-generics/defaults/needs-feature.rs index 7eb7764a644..b58dee0712a 100644 --- a/src/test/ui/const-generics/defaults/needs-feature.rs +++ b/src/test/ui/const-generics/defaults/needs-feature.rs @@ -10,5 +10,5 @@ struct A(T); //[min]~^ ERROR type parameters must be declared prior fn main() { - let _: A<3> = A(0); + let _: A<3> = A(0); } diff --git a/src/test/ui/const-generics/defaults/simple-defaults.rs b/src/test/ui/const-generics/defaults/simple-defaults.rs index 1f1b6c2260d..cb66c7769bb 100644 --- a/src/test/ui/const-generics/defaults/simple-defaults.rs +++ b/src/test/ui/const-generics/defaults/simple-defaults.rs @@ -6,12 +6,12 @@ #![allow(dead_code)] struct FixedOutput<'a, const N: usize, T=u32> { - //[min]~^ ERROR type parameters must be declared prior to const parameters - out: &'a [T; N], + //[min]~^ ERROR type parameters must be declared prior to const parameters + out: &'a [T; N], } trait FixedOutputter { - fn out(&self) -> FixedOutput<'_, 10>; + fn out(&self) -> FixedOutput<'_, 10>; } fn main() {} From 8d7432af7bd82ae5a9c06983d51a03438cf1b625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Mon, 29 Mar 2021 12:24:18 +0300 Subject: [PATCH 187/370] Replace tabs in err messages before rendering This is done in other call sites, but was missing in one place. Fixes #83638 --- compiler/rustc_errors/src/emitter.rs | 2 +- src/test/ui/issue-83639.rs | 6 ++++++ src/test/ui/issue-83639.stderr | 8 ++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issue-83639.rs create mode 100644 src/test/ui/issue-83639.stderr diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 633c64af3c5..8ec06feb5bf 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1258,7 +1258,7 @@ impl EmitterWriter { buffer.append(0, ": ", header_style); } for &(ref text, _) in msg.iter() { - buffer.append(0, text, header_style); + buffer.append(0, &replace_tabs(text), header_style); } } diff --git a/src/test/ui/issue-83639.rs b/src/test/ui/issue-83639.rs new file mode 100644 index 00000000000..6ddbedfa0bc --- /dev/null +++ b/src/test/ui/issue-83639.rs @@ -0,0 +1,6 @@ +// check-fail +// ignore-tidy-tab + +fn main() { + """ " //~ ERROR +} diff --git a/src/test/ui/issue-83639.stderr b/src/test/ui/issue-83639.stderr new file mode 100644 index 00000000000..4c10df1917c --- /dev/null +++ b/src/test/ui/issue-83639.stderr @@ -0,0 +1,8 @@ +error: expected one of `.`, `;`, `?`, `}`, or an operator, found `" "` + --> $DIR/issue-83639.rs:5:7 + | +LL | """ " + | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + +error: aborting due to previous error + From 5b6ddd502607076346b47a71e93cee8ffec13a02 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 10 Mar 2021 12:36:12 +0000 Subject: [PATCH 188/370] Convert a closure into a method --- .../src/thir/pattern/const_to_pat.rs | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) 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 ef1419b5b74..c0624c805a6 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 @@ -246,6 +246,18 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { }) } + fn field_pats( + &self, + vals: impl Iterator>, + ) -> Result>, FallbackToConstRef> { + vals.enumerate() + .map(|(idx, val)| { + let field = Field::new(idx); + Ok(FieldPat { field, pattern: self.recur(val, false)? }) + }) + .collect() + } + // Recursive helper for `to_pat`; invoke that (instead of calling this directly). fn recur( &self, @@ -257,16 +269,6 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { let tcx = self.tcx(); let param_env = self.param_env; - let field_pats = |vals: &[&'tcx ty::Const<'tcx>]| -> Result<_, _> { - vals.iter() - .enumerate() - .map(|(idx, val)| { - let field = Field::new(idx); - Ok(FieldPat { field, pattern: self.recur(val, false)? }) - }) - .collect() - }; - let kind = match cv.ty.kind() { ty::Float(_) => { tcx.struct_span_lint_hir( @@ -361,12 +363,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { variant_index: destructured .variant .expect("destructed const of adt without variant id"), - subpatterns: field_pats(destructured.fields)?, + subpatterns: self.field_pats(destructured.fields.iter().copied())?, } } ty::Tuple(_) | ty::Adt(_, _) => { let destructured = tcx.destructure_const(param_env.and(cv)); - PatKind::Leaf { subpatterns: field_pats(destructured.fields)? } + PatKind::Leaf { subpatterns: self.field_pats(destructured.fields.iter().copied())? } } ty::Array(..) => PatKind::Array { prefix: tcx From c0e1191807976548f11f865e40ee5032f6d2862a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 11 Mar 2021 14:51:09 +0000 Subject: [PATCH 189/370] Don't build a ty::Const just to take it apart again --- compiler/rustc_mir/src/interpret/intrinsics.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_mir/src/interpret/intrinsics.rs b/compiler/rustc_mir/src/interpret/intrinsics.rs index 25c3c2c632d..9804421c1fc 100644 --- a/compiler/rustc_mir/src/interpret/intrinsics.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics.rs @@ -171,8 +171,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; let val = self.tcx.const_eval_global_id(self.param_env, gid, Some(self.tcx.span))?; - let const_ = ty::Const { val: ty::ConstKind::Value(val), ty }; - let val = self.const_to_op(&const_, None)?; + let val = self.const_val_to_op(val, ty, None)?; self.copy_op(&val, dest)?; } From 5582b1955961db7480cb0d2df177a0d1d9f8d44b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 15 Mar 2021 13:41:00 +0000 Subject: [PATCH 190/370] Only emit a discrimiant tag for enums --- compiler/rustc_mir/src/const_eval/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir/src/const_eval/mod.rs b/compiler/rustc_mir/src/const_eval/mod.rs index 77531ae2c5f..3f14efc920f 100644 --- a/compiler/rustc_mir/src/const_eval/mod.rs +++ b/compiler/rustc_mir/src/const_eval/mod.rs @@ -110,7 +110,7 @@ fn const_to_valtree_inner<'tcx>( let variant = ecx.read_discriminant(&place.into()).unwrap().1; - branches(def.variants[variant].fields.len(), Some(variant)) + branches(def.variants[variant].fields.len(), def.is_enum().then_some(variant)) } ty::Never From a0ff4612f21e312362a3ffbec0a104b9937d700b Mon Sep 17 00:00:00 2001 From: klensy Date: Sun, 28 Mar 2021 19:55:09 +0300 Subject: [PATCH 191/370] ffi::c_str smaller as_bytes --- library/std/src/ffi/c_str.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs index 687ed61b959..ed4950c57a6 100644 --- a/library/std/src/ffi/c_str.rs +++ b/library/std/src/ffi/c_str.rs @@ -613,7 +613,8 @@ impl CString { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn as_bytes(&self) -> &[u8] { - &self.inner[..self.inner.len() - 1] + // SAFETY: CString has a length at least 1 + unsafe { self.inner.get_unchecked(..self.inner.len() - 1) } } /// Equivalent to [`CString::as_bytes()`] except that the @@ -1322,7 +1323,8 @@ impl CStr { #[stable(feature = "rust1", since = "1.0.0")] pub fn to_bytes(&self) -> &[u8] { let bytes = self.to_bytes_with_nul(); - &bytes[..bytes.len() - 1] + // SAFETY: to_bytes_with_nul returns slice with length at least 1 + unsafe { bytes.get_unchecked(..bytes.len() - 1) } } /// Converts this C string to a byte slice containing the trailing 0 byte. From 48f9f0864b44752e322844f7ae17f8816223499f Mon Sep 17 00:00:00 2001 From: JohnTitor Date: Mon, 29 Mar 2021 21:41:50 +0900 Subject: [PATCH 192/370] Remove a FIXME resolved by #73578 --- compiler/rustc_middle/src/ty/util.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 9926cca2f51..9c7de250c29 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -699,7 +699,6 @@ impl<'tcx> ty::TyS<'tcx> { /// optimization as well as the rules around static values. Note /// that the `Freeze` trait is not exposed to end users and is /// effectively an implementation detail. - // FIXME: use `TyCtxtAt` instead of separate `Span`. pub fn is_freeze(&'tcx self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { self.is_trivially_freeze() || tcx_at.is_freeze_raw(param_env.and(self)) } From 79acd5e318053656b1f700bc020ece460733a36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 29 Mar 2021 16:12:26 +0300 Subject: [PATCH 193/370] :arrow_up: rust-analyzer --- src/tools/rust-analyzer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index 858ad554374..bb1d925dab3 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit 858ad554374a8b1ad67692558a0878391abfdd86 +Subproject commit bb1d925dab36372c6bd1fb5671bb68ce938ff009 From 761296bcb37f4099921c064137353762ae5ddf3f Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Mon, 29 Mar 2021 15:14:14 +0200 Subject: [PATCH 194/370] Change back prelude headline --- library/std/src/prelude/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs index e0f26c3a4cf..c0dc12d7d91 100644 --- a/library/std/src/prelude/mod.rs +++ b/library/std/src/prelude/mod.rs @@ -1,4 +1,4 @@ -//! The Rust Prelude. +//! # The Rust Prelude //! //! Rust comes with a variety of things in its standard library. However, if //! you had to manually import every single thing that you used, it would be From 7d21972579011cf97d9d439699efae6244219835 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Mon, 29 Mar 2021 21:49:58 +0800 Subject: [PATCH 195/370] Wrap non-pre code blocks Fix #83550 regression --- src/librustdoc/html/static/rustdoc.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 6c90fd7c9ee..f5a034a0d24 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -424,7 +424,9 @@ nav.sub { text-overflow: ellipsis; margin: 0; } -.docblock-short code { +/* Wrap non-pre code blocks (`text`) but not (```text```). */ +.docblock > :not(pre) > code, +.docblock-short > :not(pre) > code { white-space: pre-wrap; } From cd7a011f37c51d6cb367e87c37b4d7bc464da09d Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 29 Mar 2021 18:03:07 +0200 Subject: [PATCH 196/370] Don't duplicate the extern providers once for each crate --- compiler/rustc_interface/src/passes.rs | 9 +------- compiler/rustc_query_impl/src/lib.rs | 3 +-- compiler/rustc_query_impl/src/plumbing.rs | 25 +++++++++++------------ 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 94be7a03a93..87d00287828 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -15,7 +15,6 @@ use rustc_expand::base::ExtCtxt; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; use rustc_hir::Crate; -use rustc_index::vec::IndexVec; use rustc_lint::LintStore; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; @@ -788,13 +787,7 @@ pub fn create_global_ctxt<'tcx>( callback(sess, &mut local_providers, &mut extern_providers); } - let queries = { - let crates = resolver_outputs.cstore.crates_untracked(); - let max_cnum = crates.iter().map(|c| c.as_usize()).max().unwrap_or(0); - let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1); - providers[LOCAL_CRATE] = local_providers; - queries.get_or_init(|| TcxQueries::new(providers, extern_providers)) - }; + let queries = queries.get_or_init(|| TcxQueries::new(local_providers, extern_providers)); let gcx = sess.time("setup_global_ctxt", || { global_ctxt.get_or_init(|| { diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index e9314797fbd..00d886000fa 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -19,8 +19,7 @@ extern crate tracing; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_errors::{DiagnosticBuilder, Handler}; -use rustc_hir::def_id::CrateNum; -use rustc_index::vec::IndexVec; +use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::dep_graph; use rustc_middle::ich::StableHashingContext; use rustc_middle::ty::query::{query_keys, query_storage, query_stored, query_values}; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 37a176de941..d958b3c18cd 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -390,13 +390,12 @@ macro_rules! define_queries { #[inline] fn compute(tcx: QueryCtxt<'tcx>, key: Self::Key) -> Self::Value { - let provider = tcx.queries.providers.get(key.query_crate()) - // HACK(eddyb) it's possible crates may be loaded after - // the query engine is created, and because crate loading - // is not yet integrated with the query engine, such crates - // would be missing appropriate entries in `providers`. - .unwrap_or(&tcx.queries.fallback_extern_providers) - .$name; + let is_local = key.query_crate() == LOCAL_CRATE; + let provider = if is_local { + tcx.queries.local_providers.$name + } else { + tcx.queries.extern_providers.$name + }; provider(*tcx, key) } @@ -507,8 +506,8 @@ macro_rules! define_queries_struct { (tcx: $tcx:tt, input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => { pub struct Queries<$tcx> { - providers: IndexVec, - fallback_extern_providers: Box, + local_providers: Box, + extern_providers: Box, $($(#[$attr])* $name: QueryState< crate::dep_graph::DepKind, @@ -518,12 +517,12 @@ macro_rules! define_queries_struct { impl<$tcx> Queries<$tcx> { pub fn new( - providers: IndexVec, - fallback_extern_providers: Providers, + local_providers: Providers, + extern_providers: Providers, ) -> Self { Queries { - providers, - fallback_extern_providers: Box::new(fallback_extern_providers), + local_providers: Box::new(local_providers), + extern_providers: Box::new(extern_providers), $($name: Default::default()),* } } From 526bb10701af099f6812077a57bf64b53e85dd4c Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 29 Mar 2021 13:50:40 -0400 Subject: [PATCH 197/370] Revert changes to sync data structures There isn't currently a good reviewer for these, and I don't want to remove things that will just be added again. I plan to make a separate PR for these changes so the rest of the cleanup can land. --- compiler/rustc_data_structures/src/sync.rs | 110 +++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 357686342be..26706cd2b1b 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -43,6 +43,46 @@ cfg_if! { use std::ops::Add; use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe}; + /// This is a single threaded variant of AtomicCell provided by crossbeam. + /// Unlike `Atomic` this is intended for all `Copy` types, + /// but it lacks the explicit ordering arguments. + #[derive(Debug)] + pub struct AtomicCell(Cell); + + impl AtomicCell { + #[inline] + pub fn new(v: T) -> Self { + AtomicCell(Cell::new(v)) + } + + #[inline] + pub fn get_mut(&mut self) -> &mut T { + self.0.get_mut() + } + } + + impl AtomicCell { + #[inline] + pub fn into_inner(self) -> T { + self.0.into_inner() + } + + #[inline] + pub fn load(&self) -> T { + self.0.get() + } + + #[inline] + pub fn store(&self, val: T) { + self.0.set(val) + } + + #[inline] + pub fn swap(&self, val: T) -> T { + self.0.replace(val) + } + } + /// This is a single threaded variant of `AtomicU64`, `AtomicUsize`, etc. /// It differs from `AtomicCell` in that it has explicit ordering arguments /// and is only intended for use with the native atomic types. @@ -59,6 +99,11 @@ cfg_if! { } impl Atomic { + #[inline] + pub fn into_inner(self) -> T { + self.0.into_inner() + } + #[inline] pub fn load(&self, _: Ordering) -> T { self.0.get() @@ -68,6 +113,11 @@ cfg_if! { pub fn store(&self, val: T, _: Ordering) { self.0.set(val) } + + #[inline] + pub fn swap(&self, val: T, _: Ordering) -> T { + self.0.replace(val) + } } impl Atomic { @@ -109,6 +159,22 @@ cfg_if! { (oper_a(), oper_b()) } + pub struct SerialScope; + + impl SerialScope { + pub fn spawn(&self, f: F) + where F: FnOnce(&SerialScope) + { + f(self) + } + } + + pub fn scope(f: F) -> R + where F: FnOnce(&SerialScope) -> R + { + f(&SerialScope) + } + #[macro_export] macro_rules! parallel { ($($blocks:tt),*) => { @@ -180,6 +246,12 @@ cfg_if! { pub fn new T>(mut f: F) -> WorkerLocal { WorkerLocal(OneThread::new(f(0))) } + + /// Returns the worker-local value for each thread + #[inline] + pub fn into_inner(self) -> Vec { + vec![OneThread::into_inner(self.0)] + } } impl Deref for WorkerLocal { @@ -207,6 +279,16 @@ cfg_if! { self.0 } + #[inline(always)] + pub fn get_mut(&mut self) -> &mut T { + &mut self.0 + } + + #[inline(always)] + pub fn lock(&self) -> &T { + &self.0 + } + #[inline(always)] pub fn lock_mut(&mut self) -> &mut T { &mut self.0 @@ -236,6 +318,8 @@ cfg_if! { pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64}; + pub use crossbeam_utils::atomic::AtomicCell; + pub use std::sync::Arc as Lrc; pub use std::sync::Weak as Weak; @@ -437,6 +521,16 @@ impl RwLock { RwLock(InnerRwLock::new(inner)) } + #[inline(always)] + pub fn into_inner(self) -> T { + self.0.into_inner() + } + + #[inline(always)] + pub fn get_mut(&mut self) -> &mut T { + self.0.get_mut() + } + #[cfg(not(parallel_compiler))] #[inline(always)] pub fn read(&self) -> ReadGuard<'_, T> { @@ -453,6 +547,11 @@ impl RwLock { } } + #[inline(always)] + pub fn with_read_lock R, R>(&self, f: F) -> R { + f(&*self.read()) + } + #[cfg(not(parallel_compiler))] #[inline(always)] pub fn try_write(&self) -> Result, ()> { @@ -481,6 +580,11 @@ impl RwLock { } } + #[inline(always)] + pub fn with_write_lock R, R>(&self, f: F) -> R { + f(&mut *self.write()) + } + #[inline(always)] pub fn borrow(&self) -> ReadGuard<'_, T> { self.read() @@ -529,6 +633,12 @@ impl OneThread { inner, } } + + #[inline(always)] + pub fn into_inner(value: Self) -> T { + value.check(); + value.inner + } } impl Deref for OneThread { From 7e6fd406148b97d9e9af4097b3425d5cfab1b217 Mon Sep 17 00:00:00 2001 From: JohnTitor Date: Tue, 30 Mar 2021 03:00:25 +0900 Subject: [PATCH 198/370] Do not emit a suggestion that causes the E0632 error --- .../infer/error_reporting/need_type_info.rs | 32 +++++++++++++++---- src/test/ui/inference/issue-83606.rs | 10 ++++++ src/test/ui/inference/issue-83606.stderr | 11 +++++++ 3 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/inference/issue-83606.rs create mode 100644 src/test/ui/inference/issue-83606.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index d533e267fd7..d9a1193aac4 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -287,6 +287,7 @@ pub struct InferenceDiagnosticsData { pub struct InferenceDiagnosticsParentData { pub prefix: &'static str, pub name: String, + pub def_id: DefId, } pub enum UnderspecifiedArgKind { @@ -328,6 +329,7 @@ impl InferenceDiagnosticsParentData { Some(InferenceDiagnosticsParentData { prefix: tcx.def_kind(parent_def_id).descr(parent_def_id), name: parent_name, + def_id: parent_def_id, }) } } @@ -754,12 +756,30 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if let (UnderspecifiedArgKind::Const { .. }, Some(parent_data)) = (&arg_data.kind, &arg_data.parent) { - err.span_suggestion_verbose( - span, - "consider specifying the const argument", - format!("{}::<{}>", parent_data.name, arg_data.name), - Applicability::MaybeIncorrect, - ); + let has_impl_trait = + self.tcx.generics_of(parent_data.def_id).params.iter().any(|param| { + matches!( + param.kind, + ty::GenericParamDefKind::Type { + synthetic: Some( + hir::SyntheticTyParamKind::ImplTrait + | hir::SyntheticTyParamKind::FromAttr, + ), + .. + } + ) + }); + + // (#83606): Do not emit a suggestion if the parent has an `impl Trait` + // as an argument otherwise it will cause the E0282 error. + if !has_impl_trait { + err.span_suggestion_verbose( + span, + "consider specifying the const argument", + format!("{}::<{}>", parent_data.name, arg_data.name), + Applicability::MaybeIncorrect, + ); + } } err.span_label( diff --git a/src/test/ui/inference/issue-83606.rs b/src/test/ui/inference/issue-83606.rs new file mode 100644 index 00000000000..be56a3020cc --- /dev/null +++ b/src/test/ui/inference/issue-83606.rs @@ -0,0 +1,10 @@ +// Regression test for #83606. + +fn foo(_: impl std::fmt::Display) -> [usize; N] { + [0; N] +} + +fn main() { + let _ = foo("foo"); //<- Do not suggest `foo::("foo");`! + //~^ ERROR: type annotations needed for `[usize; _]` +} diff --git a/src/test/ui/inference/issue-83606.stderr b/src/test/ui/inference/issue-83606.stderr new file mode 100644 index 00000000000..65f3336b935 --- /dev/null +++ b/src/test/ui/inference/issue-83606.stderr @@ -0,0 +1,11 @@ +error[E0282]: type annotations needed for `[usize; _]` + --> $DIR/issue-83606.rs:8:13 + | +LL | let _ = foo("foo"); //<- Do not suggest `foo::("foo");`! + | - ^^^ cannot infer the value of const parameter `N` declared on the function `foo` + | | + | consider giving this pattern the explicit type `[usize; _]`, where the type parameter `N` is specified + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. From 595f3f25fcc9e11598eb0de2b8bb01022386147c Mon Sep 17 00:00:00 2001 From: Vlad Frolov Date: Mon, 29 Mar 2021 22:44:48 +0300 Subject: [PATCH 199/370] Updated the tracking issue # --- library/alloc/src/collections/binary_heap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index ed32ff496c6..902ef9b123e 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -905,7 +905,7 @@ impl BinaryHeap { /// /// io::sink().write(heap.as_slice()).unwrap(); /// ``` - #[unstable(feature = "binary_heap_as_slice", issue = "82331")] + #[unstable(feature = "binary_heap_as_slice", issue = "83659")] pub fn as_slice(&self) -> &[T] { self.data.as_slice() } From 68dbdfb5bf481790625c5f797a6837c82a1bbefb Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 15 Mar 2021 13:35:47 -0700 Subject: [PATCH 200/370] Simplify Command::spawn (no semantic change) This minimizes the size of an unsafe block, and allows outdenting some complex code. --- .../std/src/sys/unix/process/process_unix.rs | 58 +++++++++---------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 53916cb9abd..ed9044382a8 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -51,41 +51,35 @@ impl Command { // a lock any more because the parent won't do anything and the child is // in its own process. Thus the parent drops the lock guard while the child // forgets it to avoid unlocking it on a new thread, which would be invalid. - let (env_lock, result) = unsafe { (sys::os::env_read_lock(), cvt(libc::fork())?) }; + let (env_lock, pid) = unsafe { (sys::os::env_read_lock(), cvt(libc::fork())?) }; - let pid = unsafe { - match result { - 0 => { - mem::forget(env_lock); - drop(input); - let Err(err) = self.do_exec(theirs, envp.as_ref()); - let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32; - let errno = errno.to_be_bytes(); - let bytes = [ - errno[0], - errno[1], - errno[2], - errno[3], - CLOEXEC_MSG_FOOTER[0], - CLOEXEC_MSG_FOOTER[1], - CLOEXEC_MSG_FOOTER[2], - CLOEXEC_MSG_FOOTER[3], - ]; - // pipe I/O up to PIPE_BUF bytes should be atomic, and then - // we want to be sure we *don't* run at_exit destructors as - // we're being torn down regardless - rtassert!(output.write(&bytes).is_ok()); - libc::_exit(1) - } - n => { - drop(env_lock); - n - } - } - }; + if pid == 0 { + mem::forget(env_lock); + drop(input); + let Err(err) = unsafe { self.do_exec(theirs, envp.as_ref()) }; + let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32; + let errno = errno.to_be_bytes(); + let bytes = [ + errno[0], + errno[1], + errno[2], + errno[3], + CLOEXEC_MSG_FOOTER[0], + CLOEXEC_MSG_FOOTER[1], + CLOEXEC_MSG_FOOTER[2], + CLOEXEC_MSG_FOOTER[3], + ]; + // pipe I/O up to PIPE_BUF bytes should be atomic, and then + // we want to be sure we *don't* run at_exit destructors as + // we're being torn down regardless + rtassert!(output.write(&bytes).is_ok()); + unsafe { libc::_exit(1) } + } + + drop(env_lock); + drop(output); let mut p = Process { pid, status: None }; - drop(output); let mut bytes = [0; 8]; // loop to handle EINTR From 180ac802728c9983bd6e8d1e201a34aa981396d6 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 29 Mar 2021 13:53:10 -0700 Subject: [PATCH 201/370] Update books --- src/doc/book | 2 +- src/doc/embedded-book | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-dev-guide | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/book b/src/doc/book index fc2f690fc16..b54090a99ec 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit fc2f690fc16592abbead2360cfc0a42f5df78052 +Subproject commit b54090a99ec7c4b46a5203a9c927fdbc311bb1f5 diff --git a/src/doc/embedded-book b/src/doc/embedded-book index f61685755fa..d3f2ace94d5 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit f61685755fad7d3b88b4645adfbf461d500563a2 +Subproject commit d3f2ace94d51610cf3e3c265705bb8416d37f8e4 diff --git a/src/doc/reference b/src/doc/reference index d10a0af8dca..fd97729e2d8 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit d10a0af8dca25d9d548ca6a369fd66ad06acb3c9 +Subproject commit fd97729e2d82f8b08d68a31c9bfdf0c37a7fd542 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index eead22c6c03..29d91f591c9 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit eead22c6c030fa4f3a167d1798658c341199e2ae +Subproject commit 29d91f591c90dd18fdca6d23f1a9caf9c139d0d7 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index 67ebd4b55db..0687daac289 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit 67ebd4b55dba44edfc351621cef6e5e758169c55 +Subproject commit 0687daac28939c476df51778f5a1d1aff1a3fddf From edacd0f9814e1cc50d7f91b7bcd4337563f2bd5e Mon Sep 17 00:00:00 2001 From: JohnTitor Date: Tue, 30 Mar 2021 03:31:53 +0900 Subject: [PATCH 202/370] Add a regression test for issue-82865 --- src/test/ui/resolve/issue-82865.rs | 13 +++++++++++++ src/test/ui/resolve/issue-82865.stderr | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/test/ui/resolve/issue-82865.rs create mode 100644 src/test/ui/resolve/issue-82865.stderr diff --git a/src/test/ui/resolve/issue-82865.rs b/src/test/ui/resolve/issue-82865.rs new file mode 100644 index 00000000000..07d88c413bf --- /dev/null +++ b/src/test/ui/resolve/issue-82865.rs @@ -0,0 +1,13 @@ +// Regression test for #82865. + +#![feature(decl_macro)] + +use x::y::z; //~ ERROR: failed to resolve: maybe a missing crate `x`? + +macro mac () { + Box::z //~ ERROR: no function or associated item +} + +fn main() { + mac!(); +} diff --git a/src/test/ui/resolve/issue-82865.stderr b/src/test/ui/resolve/issue-82865.stderr new file mode 100644 index 00000000000..027d7a0e0e4 --- /dev/null +++ b/src/test/ui/resolve/issue-82865.stderr @@ -0,0 +1,21 @@ +error[E0433]: failed to resolve: maybe a missing crate `x`? + --> $DIR/issue-82865.rs:5:5 + | +LL | use x::y::z; + | ^ maybe a missing crate `x`? + +error[E0599]: no function or associated item named `z` found for struct `Box<_, _>` in the current scope + --> $DIR/issue-82865.rs:8:10 + | +LL | Box::z + | ^ function or associated item not found in `Box<_, _>` +... +LL | mac!(); + | ------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0433, E0599. +For more information about an error, try `rustc --explain E0433`. From f2e52fffc28e18c7896f05792843d1cdd18c7ecb Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Mon, 29 Mar 2021 19:52:59 -0400 Subject: [PATCH 203/370] 2229: Produce a rustfix migration suggestion --- compiler/rustc_typeck/src/check/upvar.rs | 32 ++++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 91021b3f6f5..fd4186e8025 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -34,6 +34,7 @@ use super::FnCtxt; use crate::expr_use_visitor as euv; use rustc_data_structures::fx::FxIndexMap; +use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::def_id::LocalDefId; @@ -91,7 +92,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InferBorrowKindVisitor<'a, 'tcx> { if let hir::ExprKind::Closure(cc, _, body_id, _, _) = expr.kind { let body = self.fcx.tcx.hir().body(body_id); self.visit_body(body); - self.fcx.analyze_closure(expr.hir_id, expr.span, body, cc); + self.fcx.analyze_closure(expr.hir_id, expr.span, body_id, body, cc); } intravisit::walk_expr(self, expr); @@ -104,6 +105,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, closure_hir_id: hir::HirId, span: Span, + body_id: hir::BodyId, body: &'tcx hir::Body<'tcx>, capture_clause: hir::CaptureBy, ) { @@ -167,7 +169,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let closure_hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id); if should_do_migration_analysis(self.tcx, closure_hir_id) { - self.perform_2229_migration_anaysis(closure_def_id, capture_clause, span); + self.perform_2229_migration_anaysis(closure_def_id, body_id, capture_clause, span); } // We now fake capture information for all variables that are mentioned within the closure @@ -465,6 +467,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn perform_2229_migration_anaysis( &self, closure_def_id: DefId, + body_id: hir::BodyId, capture_clause: hir::CaptureBy, span: Span, ) { @@ -488,7 +491,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut diagnostics_builder = lint.build( "drop order affected for closure because of `capture_disjoint_fields`", ); - diagnostics_builder.note(&migrations_text); + let closure_body_span = self.tcx.hir().span(body_id.hir_id); + let (sugg, app) = + match self.tcx.sess.source_map().span_to_snippet(closure_body_span) { + Ok(s) => ( + format!("{{ {} {} }}", migrations_text, s), + Applicability::MachineApplicable, + ), + Err(_) => (migrations_text.clone(), Applicability::HasPlaceholders), + }; + + diagnostics_builder.span_suggestion( + closure_body_span, + &format!("You can restore original behavior adding `{}` to the closure/generator", migrations_text), + sugg, + app, + ); diagnostics_builder.emit(); }, ); @@ -1517,10 +1535,14 @@ fn should_do_migration_analysis(tcx: TyCtxt<'_>, closure_id: hir::HirId) -> bool fn migration_suggestion_for_2229(tcx: TyCtxt<'_>, need_migrations: &Vec) -> String { let need_migrations_strings = - need_migrations.iter().map(|v| format!("{}", var_name(tcx, *v))).collect::>(); + need_migrations.iter().map(|v| format!("&{}", var_name(tcx, *v))).collect::>(); let migrations_list_concat = need_migrations_strings.join(", "); - format!("drop(&({}));", migrations_list_concat) + if 1 == need_migrations.len() { + format!("let _ = {};", migrations_list_concat) + } else { + format!("let _ = ({});", migrations_list_concat) + } } /// Helper function to determine if we need to escalate CaptureKind from From 26d260bfa4a31df541ff1d4c24965730660b4114 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sat, 27 Mar 2021 05:04:32 +0000 Subject: [PATCH 204/370] Run LLVM coverage instrumentation passes before optimization passes This matches the behavior of Clang and allows us to remove several hacks which were needed to ensure functions weren't optimized away before reaching the instrumentation pass. --- compiler/rustc_codegen_llvm/src/back/write.rs | 5 + compiler/rustc_middle/src/mir/mono.rs | 9 +- .../src/monomorphize/partitioning/mod.rs | 8 +- compiler/rustc_typeck/src/collect.rs | 12 +- .../coverage-llvmir/Makefile | 2 +- .../expected_show_coverage.generics.txt | 4 +- .../expected_show_coverage.uses_crate.txt | 4 +- ...pected_show_coverage.uses_inline_crate.txt | 179 ++++++++---------- .../coverage/lib/used_inline_crate.rs | 6 - 9 files changed, 91 insertions(+), 138 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 388dd7ce81b..c45d637177e 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -548,6 +548,11 @@ pub(crate) unsafe fn optimize( llvm::LLVMRustAddPass(fpm, find_pass("lint").unwrap()); continue; } + if pass_name == "insert-gcov-profiling" || pass_name == "instrprof" { + // Instrumentation should be inserted before optimization. + llvm::LLVMRustAddPass(mpm, find_pass(pass_name).unwrap()); + continue; + } if let Some(pass) = find_pass(pass_name) { extra_passes.push(pass); diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 0167655bee5..6c2468b9ffe 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -84,14 +84,7 @@ impl<'tcx> MonoItem<'tcx> { .debugging_opts .inline_in_all_cgus .unwrap_or_else(|| tcx.sess.opts.optimize != OptLevel::No) - && !tcx.sess.link_dead_code() - && !tcx.sess.instrument_coverage(); - // Disabled for `-Z instrument-coverage` because some LLVM optimizations can sometimes - // break coverage results. A test that failed at certain optimization levels is now - // validated at that optimization level (via `compile-flags` directive): - // * `src/test/run-make-fulldeps/coverage/closure.rs` broke with `-C opt-level=2`, and - // also required disabling `internalize_symbols` in - // `rustc_mir/monomorphize/partitioning/mod.rs` + && !tcx.sess.link_dead_code(); match *self { MonoItem::Fn(ref instance) => { diff --git a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs index 04f31ec3a33..dc2379fd92b 100644 --- a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs @@ -196,13 +196,7 @@ pub fn partition<'tcx>( // Next we try to make as many symbols "internal" as possible, so LLVM has // more freedom to optimize. - if !tcx.sess.link_dead_code() && !tcx.sess.instrument_coverage() { - // Disabled for `-Z instrument-coverage` because some LLVM optimizations can sometimes - // break coverage results. Tests that failed at certain optimization levels are now - // validated at those optimization levels (via `compile-flags` directive); for example: - // * `src/test/run-make-fulldeps/coverage/async.rs` broke with `-C opt-level=1` - // * `src/test/run-make-fulldeps/coverage/closure.rs` broke with `-C opt-level=2`, and - // also required disabling `generate_gcu_internal_copies` in `rustc_middle/mir/mono.rs` + if !tcx.sess.link_dead_code() { let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols"); partitioner.internalize_symbols(cx, &mut post_inlining); } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 631f2c7a69a..cb0eea1b706 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2889,17 +2889,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { .emit(); InlineAttr::None } else if list_contains_name(&items[..], sym::always) { - if tcx.sess.instrument_coverage() { - // Fixes Issue #82875. Forced inlining allows LLVM to discard functions - // marked with `#[inline(always)]`, which can break coverage reporting if - // that function was referenced from a coverage map. - // - // FIXME(#83429): Is there a better place, e.g., in codegen, to check and - // convert `Always` to `Hint`? - InlineAttr::Hint - } else { - InlineAttr::Always - } + InlineAttr::Always } else if list_contains_name(&items[..], sym::never) { InlineAttr::Never } else { diff --git a/src/test/run-make-fulldeps/coverage-llvmir/Makefile b/src/test/run-make-fulldeps/coverage-llvmir/Makefile index 86af7e41ae1..7d9121ee2f8 100644 --- a/src/test/run-make-fulldeps/coverage-llvmir/Makefile +++ b/src/test/run-make-fulldeps/coverage-llvmir/Makefile @@ -17,7 +17,7 @@ else COMDAT_IF_SUPPORTED=, comdat endif -DEFINE_INTERNAL=define hidden +DEFINE_INTERNAL=define internal ifdef IS_WINDOWS LLVM_FILECHECK_OPTIONS=\ diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.generics.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.generics.txt index 6f28c089093..7b38ffb87cb 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.generics.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.generics.txt @@ -29,12 +29,12 @@ 18| 2| println!("BOOM times {}!!!", self.strength); 19| 2| } ------------------ - | as core::ops::drop::Drop>::drop: + | as core::ops::drop::Drop>::drop: | 17| 1| fn drop(&mut self) { | 18| 1| println!("BOOM times {}!!!", self.strength); | 19| 1| } ------------------ - | as core::ops::drop::Drop>::drop: + | as core::ops::drop::Drop>::drop: | 17| 1| fn drop(&mut self) { | 18| 1| println!("BOOM times {}!!!", self.strength); | 19| 1| } diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt index 380869d62a8..cdcbd8fca94 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt @@ -36,12 +36,12 @@ 22| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); 23| 2|} ------------------ - | used_crate::used_only_from_this_lib_crate_generic_function::>: + | used_crate::used_only_from_this_lib_crate_generic_function::<&str>: | 21| 1|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { | 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); | 23| 1|} ------------------ - | used_crate::used_only_from_this_lib_crate_generic_function::<&str>: + | used_crate::used_only_from_this_lib_crate_generic_function::>: | 21| 1|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { | 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); | 23| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt index 0853dc9c014..c38d2f87ace 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt @@ -30,127 +30,104 @@ ^0 29| 1| use_this_lib_crate(); 30| 1|} - ------------------ - | used_inline_crate::used_inline_function: - | 20| 1|pub fn used_inline_function() { - | 21| | // Initialize test constants in a way that cannot be determined at compile time, to ensure - | 22| | // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - | 23| | // dependent conditions. - | 24| 1| let is_true = std::env::args().len() == 1; - | 25| 1| let mut countdown = 0; - | 26| 1| if is_true { - | 27| 1| countdown = 10; - | 28| 1| } - | ^0 - | 29| 1| use_this_lib_crate(); - | 30| 1|} - ------------------ - | Unexecuted instantiation: used_inline_crate::used_inline_function - ------------------ - 31| |// Expect for above function: - 32| |// - 33| |// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_> - 34| |// - 35| |// With `#[inline(always)]` this function is instantiated twice, in both the library crate (which - 36| |// does not use it) and the `uses_inline_crate` binary (which does use/call it). - 37| | - 38| |#[inline(always)] - 39| 2|pub fn used_only_from_bin_crate_generic_function(arg: T) { - 40| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg); - 41| 2|} + 31| | + 32| |#[inline(always)] + 33| 2|pub fn used_only_from_bin_crate_generic_function(arg: T) { + 34| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg); + 35| 2|} ------------------ | used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec>: - | 39| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { - | 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); - | 41| 1|} + | 33| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { + | 34| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); + | 35| 1|} ------------------ | used_inline_crate::used_only_from_bin_crate_generic_function::<&str>: - | 39| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { - | 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); - | 41| 1|} + | 33| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { + | 34| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); + | 35| 1|} ------------------ | Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_> ------------------ - 42| |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`) - 43| | - 44| |#[inline(always)] - 45| 4|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { - 46| 4| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); - 47| 4|} + 36| |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`) + 37| | + 38| |#[inline(always)] + 39| 4|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { + 40| 4| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); + 41| 4|} ------------------ | used_inline_crate::used_only_from_this_lib_crate_generic_function::>: - | 45| 2|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { - | 46| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); - | 47| 2|} + | 39| 2|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { + | 40| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); + | 41| 2|} ------------------ | used_inline_crate::used_only_from_this_lib_crate_generic_function::<&str>: - | 45| 2|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { - | 46| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); - | 47| 2|} + | 39| 2|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { + | 40| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); + | 41| 2|} ------------------ - 48| | - 49| |#[inline(always)] - 50| 3|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { - 51| 3| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - 52| 3|} + 42| | + 43| |#[inline(always)] + 44| 3|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { + 45| 3| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + 46| 3|} ------------------ | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::>: - | 50| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { - | 51| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - | 52| 1|} + | 44| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { + | 45| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + | 46| 1|} ------------------ | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>: - | 50| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { - | 51| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - | 52| 2|} + | 44| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { + | 45| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + | 46| 2|} ------------------ - 53| | - 54| |#[inline(always)] - 55| 3|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { - 56| 3| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - 57| 3|} + 47| | + 48| |#[inline(always)] + 49| 3|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { + 50| 3| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + 51| 3|} ------------------ | used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>: - | 55| 1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { - | 56| 1| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - | 57| 1|} + | 49| 1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { + | 50| 1| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + | 51| 1|} ------------------ | used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>: - | 55| 2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { - | 56| 2| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - | 57| 2|} + | 49| 2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { + | 50| 2| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + | 51| 2|} ------------------ - 58| | - 59| |#[inline(always)] - 60| 0|pub fn unused_generic_function(arg: T) { - 61| 0| println!("unused_generic_function with {:?}", arg); - 62| 0|} - 63| | - 64| |#[inline(always)] - 65| 0|pub fn unused_function() { - 66| 0| let is_true = std::env::args().len() == 1; - 67| 0| let mut countdown = 2; - 68| 0| if !is_true { - 69| 0| countdown = 20; - 70| 0| } - 71| 0|} - 72| | - 73| |#[inline(always)] - 74| 0|fn unused_private_function() { - 75| 0| let is_true = std::env::args().len() == 1; - 76| 0| let mut countdown = 2; - 77| 0| if !is_true { - 78| 0| countdown = 20; - 79| 0| } - 80| 0|} - 81| | - 82| 2|fn use_this_lib_crate() { - 83| 2| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs"); - 84| 2| used_with_same_type_from_bin_crate_and_lib_crate_generic_function( - 85| 2| "used from library used_crate.rs", - 86| 2| ); - 87| 2| let some_vec = vec![5, 6, 7, 8]; - 88| 2| used_only_from_this_lib_crate_generic_function(some_vec); - 89| 2| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs"); - 90| 2|} + 52| | + 53| |#[inline(always)] + 54| 0|pub fn unused_generic_function(arg: T) { + 55| 0| println!("unused_generic_function with {:?}", arg); + 56| 0|} + 57| | + 58| |#[inline(always)] + 59| 0|pub fn unused_function() { + 60| 0| let is_true = std::env::args().len() == 1; + 61| 0| let mut countdown = 2; + 62| 0| if !is_true { + 63| 0| countdown = 20; + 64| 0| } + 65| 0|} + 66| | + 67| |#[inline(always)] + 68| 0|fn unused_private_function() { + 69| 0| let is_true = std::env::args().len() == 1; + 70| 0| let mut countdown = 2; + 71| 0| if !is_true { + 72| 0| countdown = 20; + 73| 0| } + 74| 0|} + 75| | + 76| 2|fn use_this_lib_crate() { + 77| 2| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs"); + 78| 2| used_with_same_type_from_bin_crate_and_lib_crate_generic_function( + 79| 2| "used from library used_crate.rs", + 80| 2| ); + 81| 2| let some_vec = vec![5, 6, 7, 8]; + 82| 2| used_only_from_this_lib_crate_generic_function(some_vec); + 83| 2| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs"); + 84| 2|} diff --git a/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs b/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs index f4c3dd46f76..249e99fccb8 100644 --- a/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs +++ b/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs @@ -28,12 +28,6 @@ pub fn used_inline_function() { } use_this_lib_crate(); } -// Expect for above function: -// -// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_> -// -// With `#[inline(always)]` this function is instantiated twice, in both the library crate (which -// does not use it) and the `uses_inline_crate` binary (which does use/call it). #[inline(always)] pub fn used_only_from_bin_crate_generic_function(arg: T) { From 6f2d8a018e4ff062032608a30615129230490b0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 29 Mar 2021 18:14:44 -0700 Subject: [PATCH 205/370] Suggest box/pin/arc ing receiver on method calls --- compiler/rustc_typeck/src/check/expr.rs | 35 +++++++++++--- compiler/rustc_typeck/src/check/method/mod.rs | 2 + src/test/ui/async-await/pin-needed-to-poll.rs | 47 +++++++++++++++++++ .../ui/async-await/pin-needed-to-poll.stderr | 25 ++++++++++ src/test/ui/copy-a-resource.stderr | 8 ---- .../derives/derive-assoc-type-not-impl.stderr | 8 ---- src/test/ui/issues/issue-2823.stderr | 8 ---- src/test/ui/issues/issue-69725.stderr | 8 ---- src/test/ui/non-copyable-void.stderr | 8 ---- src/test/ui/noncopyable-class.stderr | 8 ---- ...point-at-arbitrary-self-type-method.stderr | 5 ++ ...at-arbitrary-self-type-trait-method.stderr | 5 ++ .../missing-lifetimes-in-signature.nll.stderr | 11 ----- ...licitly-unimplemented-error-message.stderr | 8 ---- src/test/ui/union/union-derive-clone.stderr | 8 ---- src/test/ui/unique-object-noncopyable.stderr | 8 ---- src/test/ui/unique-pinned-nocopy.stderr | 8 ---- 17 files changed, 113 insertions(+), 97 deletions(-) create mode 100644 src/test/ui/async-await/pin-needed-to-poll.rs create mode 100644 src/test/ui/async-await/pin-needed-to-poll.stderr delete mode 100644 src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 8951c08bd33..9a2e933eb0b 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -973,7 +973,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error: MethodError<'tcx>, ) { let rcvr = &args[0]; - let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t| { + let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t, pre: &str, post: &str| { if let Some(new_rcvr_t) = new_rcvr_t { if let Ok(pick) = self.lookup_probe( span, @@ -986,11 +986,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Make sure the method is defined for the *actual* receiver: // we don't want to treat `Box` as a receiver if // it only works because of an autoderef to `&self` - if pick.autoderefs == 0 { + if pick.autoderefs == 0 + // We don't want to suggest a container type when the missing method is + // `.clone()`, otherwise we'd suggest `Arc::new(foo).clone()`, which is + // far from what the user really wants. + && Some(pick.item.container.id()) != self.tcx.lang_items().clone_trait() + { err.span_label( pick.item.ident.span, &format!("the method is available for `{}` here", new_rcvr_t), ); + err.multipart_suggestion( + "consider wrapping the receiver expression with the appropriate type", + vec![ + (rcvr.span.shrink_to_lo(), format!("{}({}", pre, post)), + (rcvr.span.shrink_to_hi(), ")".to_string()), + ], + Applicability::MaybeIncorrect, + ); } } } @@ -1008,10 +1021,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Try alternative arbitrary self types that could fulfill this call. // FIXME: probe for all types that *could* be arbitrary self-types, not // just this list. - try_alt_rcvr(&mut err, self.tcx.mk_lang_item(rcvr_t, LangItem::OwnedBox)); - try_alt_rcvr(&mut err, self.tcx.mk_lang_item(rcvr_t, LangItem::Pin)); - try_alt_rcvr(&mut err, self.tcx.mk_diagnostic_item(rcvr_t, sym::Arc)); - try_alt_rcvr(&mut err, self.tcx.mk_diagnostic_item(rcvr_t, sym::Rc)); + for (rcvr_t, post) in &[ + (rcvr_t, ""), + (self.tcx.mk_mut_ref(&ty::ReErased, rcvr_t), "&mut "), + (self.tcx.mk_imm_ref(&ty::ReErased, rcvr_t), "&"), + ] { + for (rcvr_t, pre) in &[ + (self.tcx.mk_lang_item(rcvr_t, LangItem::OwnedBox), "Box::new"), + (self.tcx.mk_lang_item(rcvr_t, LangItem::Pin), "Pin::new"), + (self.tcx.mk_diagnostic_item(rcvr_t, sym::Arc), "Arc::new"), + (self.tcx.mk_diagnostic_item(rcvr_t, sym::Rc), "Rc::new"), + ] { + try_alt_rcvr(&mut err, *rcvr_t, pre, post); + } + } } err.emit(); } diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index d6fa6bf0067..c74fd25f76d 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -45,6 +45,7 @@ pub struct MethodCallee<'tcx> { pub sig: ty::FnSig<'tcx>, } +#[derive(Debug)] pub enum MethodError<'tcx> { // Did not find an applicable method, but we did find various near-misses that may work. NoMatch(NoMatchData<'tcx>), @@ -66,6 +67,7 @@ pub enum MethodError<'tcx> { // Contains a list of static methods that may apply, a list of unsatisfied trait predicates which // could lead to matches if satisfied, and a list of not-in-scope traits which may work. +#[derive(Debug)] pub struct NoMatchData<'tcx> { pub static_candidates: Vec, pub unsatisfied_predicates: Vec<(ty::Predicate<'tcx>, Option>)>, diff --git a/src/test/ui/async-await/pin-needed-to-poll.rs b/src/test/ui/async-await/pin-needed-to-poll.rs new file mode 100644 index 00000000000..0d1fe684f60 --- /dev/null +++ b/src/test/ui/async-await/pin-needed-to-poll.rs @@ -0,0 +1,47 @@ +use std::{ + future::Future, + pin::Pin, + task::{Context, Poll}, +}; + +struct Sleep; + +impl Future for Sleep { + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Poll::Ready(()) + } +} + +impl Drop for Sleep { + fn drop(&mut self) {} +} + +fn sleep() -> Sleep { + Sleep +} + + +struct MyFuture { + sleep: Sleep, +} + +impl MyFuture { + fn new() -> Self { + Self { + sleep: sleep(), + } + } +} + +impl Future for MyFuture { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.sleep.poll(cx) + //~^ ERROR no method named `poll` found for struct `Sleep` in the current scope + } +} + +fn main() {} diff --git a/src/test/ui/async-await/pin-needed-to-poll.stderr b/src/test/ui/async-await/pin-needed-to-poll.stderr new file mode 100644 index 00000000000..0e3716d6156 --- /dev/null +++ b/src/test/ui/async-await/pin-needed-to-poll.stderr @@ -0,0 +1,25 @@ +error[E0599]: no method named `poll` found for struct `Sleep` in the current scope + --> $DIR/pin-needed-to-poll.rs:42:20 + | +LL | struct Sleep; + | ------------- method `poll` not found for this +... +LL | self.sleep.poll(cx) + | ^^^^ method not found in `Sleep` + | + ::: $SRC_DIR/core/src/future/future.rs:LL:COL + | +LL | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll; + | ---- the method is available for `Pin<&mut Sleep>` here + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `poll`, perhaps you need to implement it: + candidate #1: `Future` +help: consider wrapping the receiver expression with the appropriate type + | +LL | Pin::new(&mut self.sleep).poll(cx) + | ^^^^^^^^^^^^^ ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/copy-a-resource.stderr b/src/test/ui/copy-a-resource.stderr index 36cf57bd3c5..79095452f9d 100644 --- a/src/test/ui/copy-a-resource.stderr +++ b/src/test/ui/copy-a-resource.stderr @@ -6,14 +6,6 @@ LL | struct Foo { ... LL | let _y = x.clone(); | ^^^^^ method not found in `Foo` - | - ::: $SRC_DIR/core/src/clone.rs:LL:COL - | -LL | fn clone(&self) -> Self; - | ----- - | | - | the method is available for `Arc` here - | the method is available for `Rc` here | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: diff --git a/src/test/ui/derives/derive-assoc-type-not-impl.stderr b/src/test/ui/derives/derive-assoc-type-not-impl.stderr index ffee7004f8f..fd993d0f9d8 100644 --- a/src/test/ui/derives/derive-assoc-type-not-impl.stderr +++ b/src/test/ui/derives/derive-assoc-type-not-impl.stderr @@ -12,14 +12,6 @@ LL | struct NotClone; ... LL | Bar:: { x: 1 }.clone(); | ^^^^^ method cannot be called on `Bar` due to unsatisfied trait bounds - | - ::: $SRC_DIR/core/src/clone.rs:LL:COL - | -LL | fn clone(&self) -> Self; - | ----- - | | - | the method is available for `Arc>` here - | the method is available for `Rc>` here | = note: the following trait bounds were not satisfied: `NotClone: Clone` diff --git a/src/test/ui/issues/issue-2823.stderr b/src/test/ui/issues/issue-2823.stderr index e044352e954..b3bc946292f 100644 --- a/src/test/ui/issues/issue-2823.stderr +++ b/src/test/ui/issues/issue-2823.stderr @@ -6,14 +6,6 @@ LL | struct C { ... LL | let _d = c.clone(); | ^^^^^ method not found in `C` - | - ::: $SRC_DIR/core/src/clone.rs:LL:COL - | -LL | fn clone(&self) -> Self; - | ----- - | | - | the method is available for `Arc` here - | the method is available for `Rc` here | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: diff --git a/src/test/ui/issues/issue-69725.stderr b/src/test/ui/issues/issue-69725.stderr index 48c71d76af0..4dd6b4bbb68 100644 --- a/src/test/ui/issues/issue-69725.stderr +++ b/src/test/ui/issues/issue-69725.stderr @@ -8,14 +8,6 @@ LL | let _ = Struct::::new().clone(); | LL | pub struct Struct(A); | ------------------------ doesn't satisfy `Struct: Clone` - | - ::: $SRC_DIR/core/src/clone.rs:LL:COL - | -LL | fn clone(&self) -> Self; - | ----- - | | - | the method is available for `Arc>` here - | the method is available for `Rc>` here | = note: the following trait bounds were not satisfied: `A: Clone` diff --git a/src/test/ui/non-copyable-void.stderr b/src/test/ui/non-copyable-void.stderr index 8395a3a0563..99af04e7cd9 100644 --- a/src/test/ui/non-copyable-void.stderr +++ b/src/test/ui/non-copyable-void.stderr @@ -3,14 +3,6 @@ error[E0599]: no method named `clone` found for enum `c_void` in the current sco | LL | let _z = (*y).clone(); | ^^^^^ method not found in `c_void` - | - ::: $SRC_DIR/core/src/clone.rs:LL:COL - | -LL | fn clone(&self) -> Self; - | ----- - | | - | the method is available for `Arc` here - | the method is available for `Rc` here error: aborting due to previous error diff --git a/src/test/ui/noncopyable-class.stderr b/src/test/ui/noncopyable-class.stderr index b8e467d8402..4674c16eb43 100644 --- a/src/test/ui/noncopyable-class.stderr +++ b/src/test/ui/noncopyable-class.stderr @@ -6,14 +6,6 @@ LL | struct Foo { ... LL | let _y = x.clone(); | ^^^^^ method not found in `Foo` - | - ::: $SRC_DIR/core/src/clone.rs:LL:COL - | -LL | fn clone(&self) -> Self; - | ----- - | | - | the method is available for `Arc` here - | the method is available for `Rc` here | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: diff --git a/src/test/ui/self/point-at-arbitrary-self-type-method.stderr b/src/test/ui/self/point-at-arbitrary-self-type-method.stderr index 2954a499c18..b804ddfb024 100644 --- a/src/test/ui/self/point-at-arbitrary-self-type-method.stderr +++ b/src/test/ui/self/point-at-arbitrary-self-type-method.stderr @@ -9,6 +9,11 @@ LL | fn foo(self: Box) {} ... LL | A.foo(); | ^^^ method not found in `A` + | +help: consider wrapping the receiver expression with the appropriate type + | +LL | Box::new(A).foo(); + | ^^^^^^^^^ ^ error: aborting due to previous error diff --git a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr index 89fe84c0d2d..e1ed0e42f98 100644 --- a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr +++ b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr @@ -10,6 +10,11 @@ LL | struct A; ... LL | A.foo() | ^^^ method not found in `A` + | +help: consider wrapping the receiver expression with the appropriate type + | +LL | Box::new(A).foo() + | ^^^^^^^^^ ^ error: aborting due to previous error diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr deleted file mode 100644 index 916a6c2bf12..00000000000 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/missing-lifetimes-in-signature.rs:36:11 - | -LL | fn baz(g: G, dest: &mut T) -> impl FnOnce() + '_ - | - ^^ undeclared lifetime - | | - | help: consider introducing lifetime `'a` here: `'a,` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0261`. diff --git a/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.stderr b/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.stderr index d39daaba206..01e36a4a62a 100644 --- a/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.stderr +++ b/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.stderr @@ -6,14 +6,6 @@ LL | struct Qux; ... LL | Qux.clone(); | ^^^^^ method not found in `Qux` - | - ::: $SRC_DIR/core/src/clone.rs:LL:COL - | -LL | fn clone(&self) -> Self; - | ----- - | | - | the method is available for `Arc` here - | the method is available for `Rc` here | = help: items from traits can only be used if the trait is implemented and in scope = note: the trait `Clone` defines an item `clone`, but is explicitely unimplemented diff --git a/src/test/ui/union/union-derive-clone.stderr b/src/test/ui/union/union-derive-clone.stderr index a793bf58d23..546394664df 100644 --- a/src/test/ui/union/union-derive-clone.stderr +++ b/src/test/ui/union/union-derive-clone.stderr @@ -25,14 +25,6 @@ LL | struct CloneNoCopy; ... LL | let w = u.clone(); | ^^^^^ method cannot be called on `U5` due to unsatisfied trait bounds - | - ::: $SRC_DIR/core/src/clone.rs:LL:COL - | -LL | fn clone(&self) -> Self; - | ----- - | | - | the method is available for `Arc>` here - | the method is available for `Rc>` here | = note: the following trait bounds were not satisfied: `CloneNoCopy: Copy` diff --git a/src/test/ui/unique-object-noncopyable.stderr b/src/test/ui/unique-object-noncopyable.stderr index 4bbacfc0a8b..6a355dd2562 100644 --- a/src/test/ui/unique-object-noncopyable.stderr +++ b/src/test/ui/unique-object-noncopyable.stderr @@ -10,14 +10,6 @@ LL | trait Foo { LL | let _z = y.clone(); | ^^^^^ method cannot be called on `Box` due to unsatisfied trait bounds | - ::: $SRC_DIR/core/src/clone.rs:LL:COL - | -LL | fn clone(&self) -> Self; - | ----- - | | - | the method is available for `Arc>` here - | the method is available for `Rc>` here - | ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL | LL | / pub struct Box< diff --git a/src/test/ui/unique-pinned-nocopy.stderr b/src/test/ui/unique-pinned-nocopy.stderr index dd0b7fc5489..a4421bcf809 100644 --- a/src/test/ui/unique-pinned-nocopy.stderr +++ b/src/test/ui/unique-pinned-nocopy.stderr @@ -7,14 +7,6 @@ LL | struct R { LL | let _j = i.clone(); | ^^^^^ method cannot be called on `Box` due to unsatisfied trait bounds | - ::: $SRC_DIR/core/src/clone.rs:LL:COL - | -LL | fn clone(&self) -> Self; - | ----- - | | - | the method is available for `Arc>` here - | the method is available for `Rc>` here - | ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL | LL | / pub struct Box< From 974192cd98b3efca8e5cd293f641f561e7487b30 Mon Sep 17 00:00:00 2001 From: Cheng XU Date: Tue, 30 Mar 2021 10:24:23 +0800 Subject: [PATCH 206/370] Disallow octal format in Ipv4 string In its original specification, leading zero in Ipv4 string is interpreted as octal literals. So a IP address 0127.0.0.1 actually means 87.0.0.1. This confusion can lead to many security vulnerabilities. Therefore, in [IETF RFC 6943], it suggests to disallow octal/hexadecimal format in Ipv4 string all together. Existing implementation already disallows hexadecimal numbers. This commit makes Parser reject octal numbers. Fixes #83648. [IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1 --- library/std/src/net/ip.rs | 2 ++ library/std/src/net/parser.rs | 14 +++++++++++++- library/std/src/net/parser/tests.rs | 8 ++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index 2aa305d7f83..7f8c33dac56 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -67,7 +67,9 @@ pub enum IpAddr { /// /// `Ipv4Addr` provides a [`FromStr`] implementation. The four octets are in decimal /// notation, divided by `.` (this is called "dot-decimal notation"). +/// Notably, octal numbers and hexadecimal numbers are not allowed per [IETF RFC 6943]. /// +/// [IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1 /// [`FromStr`]: crate::str::FromStr /// /// # Examples diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs index 7064ed3ed23..88a8cb76bef 100644 --- a/library/std/src/net/parser.rs +++ b/library/std/src/net/parser.rs @@ -67,6 +67,11 @@ impl<'a> Parser<'a> { if self.state.is_empty() { result } else { None }.ok_or(AddrParseError(())) } + /// Peek the next character from the input + fn peek_char(&self) -> Option { + self.state.first().map(|&b| char::from(b)) + } + /// Read the next character from the input fn read_char(&mut self) -> Option { self.state.split_first().map(|(&b, tail)| { @@ -132,7 +137,14 @@ impl<'a> Parser<'a> { let mut groups = [0; 4]; for (i, slot) in groups.iter_mut().enumerate() { - *slot = p.read_separator('.', i, |p| p.read_number(10, None))?; + *slot = p.read_separator('.', i, |p| { + // Disallow octal number in IP string. + // https://tools.ietf.org/html/rfc6943#section-3.1.1 + match (p.peek_char(), p.read_number(10, None)) { + (Some('0'), Some(number)) if number != 0 => None, + (_, number) => number, + } + })?; } Some(groups.into()) diff --git a/library/std/src/net/parser/tests.rs b/library/std/src/net/parser/tests.rs index 8d8889cd19d..6d2d48ecad0 100644 --- a/library/std/src/net/parser/tests.rs +++ b/library/std/src/net/parser/tests.rs @@ -8,11 +8,15 @@ const SCOPE_ID: u32 = 1337; const IPV4: Ipv4Addr = Ipv4Addr::new(192, 168, 0, 1); const IPV4_STR: &str = "192.168.0.1"; const IPV4_STR_PORT: &str = "192.168.0.1:8080"; +const IPV4_STR_WITH_OCTAL: &str = "0127.0.0.1"; +const IPV4_STR_WITH_HEX: &str = "0x10.0.0.1"; const IPV6: Ipv6Addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0xc0a8, 0x1); const IPV6_STR_FULL: &str = "2001:db8:0:0:0:0:c0a8:1"; const IPV6_STR_COMPRESS: &str = "2001:db8::c0a8:1"; const IPV6_STR_V4: &str = "2001:db8::192.168.0.1"; +const IPV6_STR_V4_WITH_OCTAL: &str = "2001:db8::0127.0.0.1"; +const IPV6_STR_V4_WITH_HEX: &str = "2001:db8::0x10.0.0.1"; const IPV6_STR_PORT: &str = "[2001:db8::c0a8:1]:8080"; const IPV6_STR_PORT_SCOPE_ID: &str = "[2001:db8::c0a8:1%1337]:8080"; @@ -22,6 +26,8 @@ fn parse_ipv4() { assert_eq!(result, IPV4); assert!(Ipv4Addr::from_str(IPV4_STR_PORT).is_err()); + assert!(Ipv4Addr::from_str(IPV4_STR_WITH_OCTAL).is_err()); + assert!(Ipv4Addr::from_str(IPV4_STR_WITH_HEX).is_err()); assert!(Ipv4Addr::from_str(IPV6_STR_FULL).is_err()); assert!(Ipv4Addr::from_str(IPV6_STR_COMPRESS).is_err()); assert!(Ipv4Addr::from_str(IPV6_STR_V4).is_err()); @@ -39,6 +45,8 @@ fn parse_ipv6() { let result: Ipv6Addr = IPV6_STR_V4.parse().unwrap(); assert_eq!(result, IPV6); + assert!(Ipv6Addr::from_str(IPV6_STR_V4_WITH_OCTAL).is_err()); + assert!(Ipv6Addr::from_str(IPV6_STR_V4_WITH_HEX).is_err()); assert!(Ipv6Addr::from_str(IPV4_STR).is_err()); assert!(Ipv6Addr::from_str(IPV4_STR_PORT).is_err()); assert!(Ipv6Addr::from_str(IPV6_STR_PORT).is_err()); From 0195f8d3751ed2c14c405686c41064c4c41baa39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 29 Mar 2021 19:53:48 -0700 Subject: [PATCH 207/370] Hide unnecessary reference to trait When the problem for a method not being found in its receiver is due to arbitrary self-types, we don't want to mention importing or implementing the trait, instead we suggest wrapping. --- compiler/rustc_typeck/src/check/expr.rs | 96 ++++--------------- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 6 +- .../rustc_typeck/src/check/method/suggest.rs | 87 +++++++++++++++-- compiler/rustc_typeck/src/check/pat.rs | 2 +- .../ui/async-await/pin-needed-to-poll.stderr | 3 - 5 files changed, 98 insertions(+), 96 deletions(-) diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 9a2e933eb0b..30d60514063 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -6,7 +6,7 @@ use crate::astconv::AstConv as _; use crate::check::cast; use crate::check::coercion::CoerceMany; use crate::check::fatally_break_rust; -use crate::check::method::{probe, MethodError, SelfSource}; +use crate::check::method::SelfSource; use crate::check::report_unexpected_variant_res; use crate::check::BreakableCtxt; use crate::check::Diverges; @@ -30,7 +30,6 @@ use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, QPath}; use rustc_infer::infer; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; @@ -461,7 +460,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.resolve_lang_item_path(lang_item, expr.span, expr.hir_id).1 } - fn check_expr_path(&self, qpath: &hir::QPath<'_>, expr: &'tcx hir::Expr<'tcx>) -> Ty<'tcx> { + fn check_expr_path( + &self, + qpath: &'tcx hir::QPath<'tcx>, + expr: &'tcx hir::Expr<'tcx>, + ) -> Ty<'tcx> { let tcx = self.tcx; let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id, expr.span); let ty = match res { @@ -947,7 +950,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } Err(error) => { if segment.ident.name != kw::Empty { - self.report_extended_method_error(segment, span, args, rcvr_t, error); + if let Some(mut err) = self.report_method_error( + span, + rcvr_t, + segment.ident, + SelfSource::MethodCall(&args[0]), + error, + Some(args), + ) { + err.emit(); + } } Err(()) } @@ -964,82 +976,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } - fn report_extended_method_error( - &self, - segment: &hir::PathSegment<'_>, - span: Span, - args: &'tcx [hir::Expr<'tcx>], - rcvr_t: Ty<'tcx>, - error: MethodError<'tcx>, - ) { - let rcvr = &args[0]; - let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t, pre: &str, post: &str| { - if let Some(new_rcvr_t) = new_rcvr_t { - if let Ok(pick) = self.lookup_probe( - span, - segment.ident, - new_rcvr_t, - rcvr, - probe::ProbeScope::AllTraits, - ) { - debug!("try_alt_rcvr: pick candidate {:?}", pick); - // Make sure the method is defined for the *actual* receiver: - // we don't want to treat `Box` as a receiver if - // it only works because of an autoderef to `&self` - if pick.autoderefs == 0 - // We don't want to suggest a container type when the missing method is - // `.clone()`, otherwise we'd suggest `Arc::new(foo).clone()`, which is - // far from what the user really wants. - && Some(pick.item.container.id()) != self.tcx.lang_items().clone_trait() - { - err.span_label( - pick.item.ident.span, - &format!("the method is available for `{}` here", new_rcvr_t), - ); - err.multipart_suggestion( - "consider wrapping the receiver expression with the appropriate type", - vec![ - (rcvr.span.shrink_to_lo(), format!("{}({}", pre, post)), - (rcvr.span.shrink_to_hi(), ")".to_string()), - ], - Applicability::MaybeIncorrect, - ); - } - } - } - }; - - if let Some(mut err) = self.report_method_error( - span, - rcvr_t, - segment.ident, - SelfSource::MethodCall(rcvr), - error, - Some(args), - ) { - if let ty::Adt(..) = rcvr_t.kind() { - // Try alternative arbitrary self types that could fulfill this call. - // FIXME: probe for all types that *could* be arbitrary self-types, not - // just this list. - for (rcvr_t, post) in &[ - (rcvr_t, ""), - (self.tcx.mk_mut_ref(&ty::ReErased, rcvr_t), "&mut "), - (self.tcx.mk_imm_ref(&ty::ReErased, rcvr_t), "&"), - ] { - for (rcvr_t, pre) in &[ - (self.tcx.mk_lang_item(rcvr_t, LangItem::OwnedBox), "Box::new"), - (self.tcx.mk_lang_item(rcvr_t, LangItem::Pin), "Pin::new"), - (self.tcx.mk_diagnostic_item(rcvr_t, sym::Arc), "Arc::new"), - (self.tcx.mk_diagnostic_item(rcvr_t, sym::Rc), "Rc::new"), - ] { - try_alt_rcvr(&mut err, *rcvr_t, pre, post); - } - } - } - err.emit(); - } - } - fn check_expr_cast( &self, e: &'tcx hir::Expr<'tcx>, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index e64d8367676..a7a412f06be 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -905,12 +905,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Resolves an associated value path into a base type and associated constant, or method /// resolution. The newly resolved definition is written into `type_dependent_defs`. - pub fn resolve_ty_and_res_ufcs<'b>( + pub fn resolve_ty_and_res_ufcs( &self, - qpath: &'b QPath<'b>, + qpath: &'tcx QPath<'tcx>, hir_id: hir::HirId, span: Span, - ) -> (Res, Option>, &'b [hir::PathSegment<'b>]) { + ) -> (Res, Option>, &'tcx [hir::PathSegment<'tcx>]) { debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span); let (ty, qself, item_segment) = match *qpath { QPath::Resolved(ref opt_qself, ref path) => { diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 13757ac4132..72eff009473 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -68,12 +68,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn report_method_error<'b>( + pub fn report_method_error( &self, span: Span, rcvr_ty: Ty<'tcx>, item_name: Ident, - source: SelfSource<'b>, + source: SelfSource<'tcx>, error: MethodError<'tcx>, args: Option<&'tcx [hir::Expr<'tcx>]>, ) -> Option> { @@ -323,8 +323,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( lit.span, &format!( - "you must specify a concrete type for \ - this numeric value, like `{}`", + "you must specify a concrete type for this numeric value, \ + like `{}`", concrete_type ), format!("{}_{}", snippet, concrete_type), @@ -975,17 +975,78 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn suggest_traits_to_import<'b>( + fn suggest_traits_to_import( &self, err: &mut DiagnosticBuilder<'_>, span: Span, rcvr_ty: Ty<'tcx>, item_name: Ident, - source: SelfSource<'b>, + source: SelfSource<'tcx>, valid_out_of_scope_traits: Vec, unsatisfied_predicates: &[(ty::Predicate<'tcx>, Option>)], ) { - if self.suggest_valid_traits(err, valid_out_of_scope_traits) { + let mut alt_rcvr_sugg = false; + if let SelfSource::MethodCall(rcvr) = source { + info!(?span, ?item_name, ?rcvr_ty, ?rcvr); + if let ty::Adt(..) = rcvr_ty.kind() { + // Try alternative arbitrary self types that could fulfill this call. + // FIXME: probe for all types that *could* be arbitrary self-types, not + // just this list. + for (rcvr_ty, post) in &[ + (rcvr_ty, ""), + (self.tcx.mk_mut_ref(&ty::ReErased, rcvr_ty), "&mut "), + (self.tcx.mk_imm_ref(&ty::ReErased, rcvr_ty), "&"), + ] { + for (rcvr_ty, pre) in &[ + (self.tcx.mk_lang_item(rcvr_ty, LangItem::OwnedBox), "Box::new"), + (self.tcx.mk_lang_item(rcvr_ty, LangItem::Pin), "Pin::new"), + (self.tcx.mk_diagnostic_item(rcvr_ty, sym::Arc), "Arc::new"), + (self.tcx.mk_diagnostic_item(rcvr_ty, sym::Rc), "Rc::new"), + ] { + if let Some(new_rcvr_t) = *rcvr_ty { + if let Ok(pick) = self.lookup_probe( + span, + item_name, + new_rcvr_t, + rcvr, + crate::check::method::probe::ProbeScope::AllTraits, + ) { + debug!("try_alt_rcvr: pick candidate {:?}", pick); + // Make sure the method is defined for the *actual* receiver: + // we don't want to treat `Box` as a receiver if + // it only works because of an autoderef to `&self` + if pick.autoderefs == 0 + // We don't want to suggest a container type when the missing method is + // `.clone()`, otherwise we'd suggest `Arc::new(foo).clone()`, which is + // far from what the user really wants. + && Some(pick.item.container.id()) != self.tcx.lang_items().clone_trait() + { + err.span_label( + pick.item.ident.span, + &format!( + "the method is available for `{}` here", + new_rcvr_t + ), + ); + err.multipart_suggestion( + "consider wrapping the receiver expression with the \ + appropriate type", + vec![ + (rcvr.span.shrink_to_lo(), format!("{}({}", pre, post)), + (rcvr.span.shrink_to_hi(), ")".to_string()), + ], + Applicability::MaybeIncorrect, + ); + // We don't care about the other suggestions. + alt_rcvr_sugg = true; + } + } + } + } + } + } + } + if !alt_rcvr_sugg && self.suggest_valid_traits(err, valid_out_of_scope_traits) { return; } @@ -1075,6 +1136,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "the method might not be found because of this arbitrary self type", ); } + if alt_rcvr_sugg { + return; + } if !candidates.is_empty() { // Sort from most relevant to least relevant. @@ -1284,7 +1348,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Checks whether there is a local type somewhere in the chain of /// autoderefs of `rcvr_ty`. - fn type_derefs_to_local(&self, span: Span, rcvr_ty: Ty<'tcx>, source: SelfSource<'_>) -> bool { + fn type_derefs_to_local( + &self, + span: Span, + rcvr_ty: Ty<'tcx>, + source: SelfSource<'tcx>, + ) -> bool { fn is_local(ty: Ty<'_>) -> bool { match ty.kind() { ty::Adt(def, _) => def.did.is_local(), @@ -1310,7 +1379,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub enum SelfSource<'a> { QPath(&'a hir::Ty<'a>), MethodCall(&'a hir::Expr<'a> /* rcvr */), diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 79c544bd386..53593b9bab4 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -861,7 +861,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_pat_tuple_struct( &self, pat: &'tcx Pat<'tcx>, - qpath: &hir::QPath<'_>, + qpath: &'tcx hir::QPath<'tcx>, subpats: &'tcx [&'tcx Pat<'tcx>], ddpos: Option, expected: Ty<'tcx>, diff --git a/src/test/ui/async-await/pin-needed-to-poll.stderr b/src/test/ui/async-await/pin-needed-to-poll.stderr index 0e3716d6156..0756a4d59c1 100644 --- a/src/test/ui/async-await/pin-needed-to-poll.stderr +++ b/src/test/ui/async-await/pin-needed-to-poll.stderr @@ -12,9 +12,6 @@ LL | self.sleep.poll(cx) LL | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll; | ---- the method is available for `Pin<&mut Sleep>` here | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `poll`, perhaps you need to implement it: - candidate #1: `Future` help: consider wrapping the receiver expression with the appropriate type | LL | Pin::new(&mut self.sleep).poll(cx) From cad9b6b695e86c7c23482876d2f6fefd64451ab3 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Tue, 30 Mar 2021 07:03:41 +0100 Subject: [PATCH 208/370] Apply review feedback --- compiler/rustc_codegen_llvm/src/back/write.rs | 6 +- ...pected_show_coverage.uses_inline_crate.txt | 160 +++++++++--------- .../coverage/lib/used_inline_crate.rs | 6 + 3 files changed, 94 insertions(+), 78 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index c45d637177e..085935b94df 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -549,7 +549,11 @@ pub(crate) unsafe fn optimize( continue; } if pass_name == "insert-gcov-profiling" || pass_name == "instrprof" { - // Instrumentation should be inserted before optimization. + // Instrumentation must be inserted before optimization, + // otherwise LLVM may optimize some functions away which + // breaks llvm-cov. + // + // This mirrors what Clang does in lib/CodeGen/BackendUtil.cpp. llvm::LLVMRustAddPass(mpm, find_pass(pass_name).unwrap()); continue; } diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt index c38d2f87ace..cc98956e307 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt @@ -31,103 +31,109 @@ 29| 1| use_this_lib_crate(); 30| 1|} 31| | - 32| |#[inline(always)] - 33| 2|pub fn used_only_from_bin_crate_generic_function(arg: T) { - 34| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg); - 35| 2|} + 32| | + 33| | + 34| | + 35| | + 36| | + 37| | + 38| |#[inline(always)] + 39| 2|pub fn used_only_from_bin_crate_generic_function(arg: T) { + 40| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg); + 41| 2|} ------------------ | used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec>: - | 33| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { - | 34| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); - | 35| 1|} + | 39| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { + | 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); + | 41| 1|} ------------------ | used_inline_crate::used_only_from_bin_crate_generic_function::<&str>: - | 33| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { - | 34| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); - | 35| 1|} + | 39| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { + | 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); + | 41| 1|} ------------------ | Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_> ------------------ - 36| |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`) - 37| | - 38| |#[inline(always)] - 39| 4|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { - 40| 4| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); - 41| 4|} + 42| |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`) + 43| | + 44| |#[inline(always)] + 45| 4|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { + 46| 4| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); + 47| 4|} ------------------ | used_inline_crate::used_only_from_this_lib_crate_generic_function::>: - | 39| 2|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { - | 40| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); - | 41| 2|} + | 45| 2|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { + | 46| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); + | 47| 2|} ------------------ | used_inline_crate::used_only_from_this_lib_crate_generic_function::<&str>: - | 39| 2|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { - | 40| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); - | 41| 2|} + | 45| 2|pub fn used_only_from_this_lib_crate_generic_function(arg: T) { + | 46| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); + | 47| 2|} ------------------ - 42| | - 43| |#[inline(always)] - 44| 3|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { - 45| 3| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - 46| 3|} + 48| | + 49| |#[inline(always)] + 50| 3|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { + 51| 3| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + 52| 3|} ------------------ | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::>: - | 44| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { - | 45| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - | 46| 1|} + | 50| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { + | 51| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + | 52| 1|} ------------------ | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>: - | 44| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { - | 45| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - | 46| 2|} + | 50| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function(arg: T) { + | 51| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + | 52| 2|} ------------------ - 47| | - 48| |#[inline(always)] - 49| 3|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { - 50| 3| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - 51| 3|} + 53| | + 54| |#[inline(always)] + 55| 3|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { + 56| 3| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + 57| 3|} ------------------ | used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>: - | 49| 1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { - | 50| 1| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - | 51| 1|} + | 55| 1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { + | 56| 1| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + | 57| 1|} ------------------ | used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>: - | 49| 2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { - | 50| 2| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - | 51| 2|} + | 55| 2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function(arg: T) { + | 56| 2| println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + | 57| 2|} ------------------ - 52| | - 53| |#[inline(always)] - 54| 0|pub fn unused_generic_function(arg: T) { - 55| 0| println!("unused_generic_function with {:?}", arg); - 56| 0|} - 57| | - 58| |#[inline(always)] - 59| 0|pub fn unused_function() { - 60| 0| let is_true = std::env::args().len() == 1; - 61| 0| let mut countdown = 2; - 62| 0| if !is_true { - 63| 0| countdown = 20; - 64| 0| } - 65| 0|} - 66| | - 67| |#[inline(always)] - 68| 0|fn unused_private_function() { - 69| 0| let is_true = std::env::args().len() == 1; - 70| 0| let mut countdown = 2; - 71| 0| if !is_true { - 72| 0| countdown = 20; - 73| 0| } - 74| 0|} - 75| | - 76| 2|fn use_this_lib_crate() { - 77| 2| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs"); - 78| 2| used_with_same_type_from_bin_crate_and_lib_crate_generic_function( - 79| 2| "used from library used_crate.rs", - 80| 2| ); - 81| 2| let some_vec = vec![5, 6, 7, 8]; - 82| 2| used_only_from_this_lib_crate_generic_function(some_vec); - 83| 2| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs"); - 84| 2|} + 58| | + 59| |#[inline(always)] + 60| 0|pub fn unused_generic_function(arg: T) { + 61| 0| println!("unused_generic_function with {:?}", arg); + 62| 0|} + 63| | + 64| |#[inline(always)] + 65| 0|pub fn unused_function() { + 66| 0| let is_true = std::env::args().len() == 1; + 67| 0| let mut countdown = 2; + 68| 0| if !is_true { + 69| 0| countdown = 20; + 70| 0| } + 71| 0|} + 72| | + 73| |#[inline(always)] + 74| 0|fn unused_private_function() { + 75| 0| let is_true = std::env::args().len() == 1; + 76| 0| let mut countdown = 2; + 77| 0| if !is_true { + 78| 0| countdown = 20; + 79| 0| } + 80| 0|} + 81| | + 82| 2|fn use_this_lib_crate() { + 83| 2| used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs"); + 84| 2| used_with_same_type_from_bin_crate_and_lib_crate_generic_function( + 85| 2| "used from library used_crate.rs", + 86| 2| ); + 87| 2| let some_vec = vec![5, 6, 7, 8]; + 88| 2| used_only_from_this_lib_crate_generic_function(some_vec); + 89| 2| used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs"); + 90| 2|} diff --git a/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs b/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs index 249e99fccb8..4a052756d4e 100644 --- a/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs +++ b/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs @@ -29,6 +29,12 @@ pub fn used_inline_function() { use_this_lib_crate(); } + + + + + + #[inline(always)] pub fn used_only_from_bin_crate_generic_function(arg: T) { println!("used_only_from_bin_crate_generic_function with {:?}", arg); From 4f2c25a998ec39a86871d228342fa2ea7a2e6270 Mon Sep 17 00:00:00 2001 From: JohnTitor Date: Tue, 30 Mar 2021 17:02:23 +0900 Subject: [PATCH 209/370] Add a regression test for issue-75801 --- .../ui/proc-macro/auxiliary/issue-75801.rs | 13 +++++++++++++ src/test/ui/proc-macro/issue-75801.rs | 19 +++++++++++++++++++ src/test/ui/proc-macro/issue-75801.stderr | 12 ++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 src/test/ui/proc-macro/auxiliary/issue-75801.rs create mode 100644 src/test/ui/proc-macro/issue-75801.rs create mode 100644 src/test/ui/proc-macro/issue-75801.stderr diff --git a/src/test/ui/proc-macro/auxiliary/issue-75801.rs b/src/test/ui/proc-macro/auxiliary/issue-75801.rs new file mode 100644 index 00000000000..d6c031d7d4f --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/issue-75801.rs @@ -0,0 +1,13 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn foo(_args: TokenStream, item: TokenStream) -> TokenStream { + item +} diff --git a/src/test/ui/proc-macro/issue-75801.rs b/src/test/ui/proc-macro/issue-75801.rs new file mode 100644 index 00000000000..b07cde0fabd --- /dev/null +++ b/src/test/ui/proc-macro/issue-75801.rs @@ -0,0 +1,19 @@ +// aux-build: issue-75801.rs + +// Regression test for #75801. + +#[macro_use] +extern crate issue_75801; + +macro_rules! foo { + ($arg:expr) => { + #[foo] + fn bar() { + let _bar: u32 = $arg; + } + }; +} + +foo!("baz"); //~ ERROR: mismatched types [E0308] + +fn main() {} diff --git a/src/test/ui/proc-macro/issue-75801.stderr b/src/test/ui/proc-macro/issue-75801.stderr new file mode 100644 index 00000000000..ee0a9bd7783 --- /dev/null +++ b/src/test/ui/proc-macro/issue-75801.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/issue-75801.rs:17:6 + | +LL | let _bar: u32 = $arg; + | --- expected due to this +... +LL | foo!("baz"); + | ^^^^^ expected `u32`, found `&str` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From f35e587db4039fc255c876e5568b5db407977411 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 30 Mar 2021 16:13:11 +0200 Subject: [PATCH 210/370] Fix Self keyword doc URL conflict on case insensitive file systems --- library/std/src/keyword_docs.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index e64cbc18bf7..890fa132bea 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -1310,7 +1310,11 @@ mod return_keyword {} /// [Reference]: ../reference/items/associated-items.html#methods mod self_keyword {} -#[doc(keyword = "Self")] +// FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we can remove the +// three next lines and put back: `#[doc(keyword = "Self")]`. +#[doc(alias = "Self")] +#[allow(rustc::existing_doc_keyword)] +#[doc(keyword = "SelfTy")] // /// The implementing type within a [`trait`] or [`impl`] block, or the current type within a type /// definition. From 29fe5930a3452ec6b46bf969153825e99c56b6e1 Mon Sep 17 00:00:00 2001 From: Ibraheem Ahmed Date: Tue, 30 Mar 2021 12:03:58 -0400 Subject: [PATCH 211/370] update for loop desugaring docs --- library/std/src/keyword_docs.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index e64cbc18bf7..262d24e72c7 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -547,15 +547,18 @@ mod fn_keyword {} /// # fn code() { } /// # let iterator = 0..2; /// { -/// let mut _iter = std::iter::IntoIterator::into_iter(iterator); -/// loop { -/// match _iter.next() { -/// Some(loop_variable) => { -/// code() -/// }, -/// None => break, -/// } -/// } +/// let result = match IntoIterator::into_iter(iterator) { +/// mut iter => loop { +/// let next; +/// match iter.next() { +/// Some(val) => next = val, +/// None => break, +/// }; +/// let loop_variable = next; +/// let () = { code(); }; +/// }, +/// }; +/// result /// } /// ``` /// From 6bfaf3a9cb7b601e3c4ed2e661ed213b8bc4d639 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 2 Mar 2021 22:38:49 +0100 Subject: [PATCH 212/370] Stream the dep-graph to a file. --- .../rustc_incremental/src/assert_dep_graph.rs | 43 +- compiler/rustc_incremental/src/lib.rs | 4 +- .../src/persist/dirty_clean.rs | 24 +- compiler/rustc_incremental/src/persist/fs.rs | 4 + .../rustc_incremental/src/persist/load.rs | 4 +- compiler/rustc_incremental/src/persist/mod.rs | 1 + .../rustc_incremental/src/persist/save.rs | 107 +- compiler/rustc_interface/src/passes.rs | 3 - compiler/rustc_interface/src/queries.rs | 11 +- compiler/rustc_middle/src/dep_graph/mod.rs | 5 +- compiler/rustc_query_impl/src/plumbing.rs | 5 +- .../rustc_query_system/src/dep_graph/debug.rs | 14 +- .../rustc_query_system/src/dep_graph/graph.rs | 926 ++++-------------- .../rustc_query_system/src/dep_graph/mod.rs | 3 +- .../rustc_query_system/src/dep_graph/query.rs | 35 +- .../src/dep_graph/serialized.rs | 420 ++++++-- compiler/rustc_query_system/src/lib.rs | 1 + .../rustc_query_system/src/query/plumbing.rs | 18 +- 18 files changed, 710 insertions(+), 918 deletions(-) diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index a080b0ce339..b5680beae14 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -40,8 +40,9 @@ use rustc_graphviz as dot; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; -use rustc_middle::dep_graph::debug::{DepNodeFilter, EdgeFilter}; -use rustc_middle::dep_graph::{DepGraphQuery, DepKind, DepNode, DepNodeExt}; +use rustc_middle::dep_graph::{ + DepGraphQuery, DepKind, DepNode, DepNodeExt, DepNodeFilter, EdgeFilter, +}; use rustc_middle::hir::map::Map; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::{sym, Symbol}; @@ -54,7 +55,7 @@ use std::io::{BufWriter, Write}; pub fn assert_dep_graph(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { if tcx.sess.opts.debugging_opts.dump_dep_graph { - dump_graph(tcx); + tcx.dep_graph.with_query(dump_graph); } if !tcx.sess.opts.debugging_opts.query_dep_graph { @@ -200,29 +201,29 @@ fn check_paths<'tcx>(tcx: TyCtxt<'tcx>, if_this_changed: &Sources, then_this_wou } return; } - let query = tcx.dep_graph.query(); - for &(_, source_def_id, ref source_dep_node) in if_this_changed { - let dependents = query.transitive_predecessors(source_dep_node); - for &(target_span, ref target_pass, _, ref target_dep_node) in then_this_would_need { - if !dependents.contains(&target_dep_node) { - tcx.sess.span_err( - target_span, - &format!( - "no path from `{}` to `{}`", - tcx.def_path_str(source_def_id), - target_pass - ), - ); - } else { - tcx.sess.span_err(target_span, "OK"); + tcx.dep_graph.with_query(|query| { + for &(_, source_def_id, ref source_dep_node) in if_this_changed { + let dependents = query.transitive_predecessors(source_dep_node); + for &(target_span, ref target_pass, _, ref target_dep_node) in then_this_would_need { + if !dependents.contains(&target_dep_node) { + tcx.sess.span_err( + target_span, + &format!( + "no path from `{}` to `{}`", + tcx.def_path_str(source_def_id), + target_pass + ), + ); + } else { + tcx.sess.span_err(target_span, "OK"); + } } } - } + }); } -fn dump_graph(tcx: TyCtxt<'_>) { +fn dump_graph(query: &DepGraphQuery) { let path: String = env::var("RUST_DEP_GRAPH").unwrap_or_else(|_| "dep_graph".to_string()); - let query = tcx.dep_graph.query(); let nodes = match env::var("RUST_DEP_GRAPH_FILTER") { Ok(string) => { diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 95456c07b10..f089cbcfca6 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -14,7 +14,7 @@ mod assert_dep_graph; pub mod assert_module_sources; mod persist; -pub use assert_dep_graph::assert_dep_graph; +use assert_dep_graph::assert_dep_graph; pub use persist::copy_cgu_workproduct_to_incr_comp_cache_dir; pub use persist::delete_workproduct_files; pub use persist::finalize_session_directory; @@ -26,4 +26,4 @@ pub use persist::prepare_session_directory; pub use persist::save_dep_graph; pub use persist::save_work_product_index; pub use persist::LoadResult; -pub use persist::{load_dep_graph, DepGraphFuture}; +pub use persist::{build_dep_graph, load_dep_graph, DepGraphFuture}; diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index 91b7221f205..145c168f8c4 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -14,7 +14,6 @@ //! the required condition is not met. use rustc_ast::{self as ast, Attribute, NestedMetaItem}; -use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -381,10 +380,7 @@ impl DirtyCleanVisitor<'tcx> { fn assert_dirty(&self, item_span: Span, dep_node: DepNode) { debug!("assert_dirty({:?})", dep_node); - let current_fingerprint = self.get_fingerprint(&dep_node); - let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node); - - if current_fingerprint == prev_fingerprint { + if self.tcx.dep_graph.is_green(&dep_node) { let dep_node_str = self.dep_node_str(&dep_node); self.tcx .sess @@ -392,28 +388,12 @@ impl DirtyCleanVisitor<'tcx> { } } - fn get_fingerprint(&self, dep_node: &DepNode) -> Option { - if self.tcx.dep_graph.dep_node_exists(dep_node) { - let dep_node_index = self.tcx.dep_graph.dep_node_index_of(dep_node); - Some(self.tcx.dep_graph.fingerprint_of(dep_node_index)) - } else { - None - } - } - fn assert_clean(&self, item_span: Span, dep_node: DepNode) { debug!("assert_clean({:?})", dep_node); - let current_fingerprint = self.get_fingerprint(&dep_node); - let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node); - // if the node wasn't previously evaluated and now is (or vice versa), // then the node isn't actually clean or dirty. - if (current_fingerprint == None) ^ (prev_fingerprint == None) { - return; - } - - if current_fingerprint != prev_fingerprint { + if self.tcx.dep_graph.is_red(&dep_node) { let dep_node_str = self.dep_node_str(&dep_node); self.tcx .sess diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index c7a6c1195c5..30c6c408bc7 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -122,6 +122,7 @@ mod tests; const LOCK_FILE_EXT: &str = ".lock"; const DEP_GRAPH_FILENAME: &str = "dep-graph.bin"; +const STAGING_DEP_GRAPH_FILENAME: &str = "dep-graph.part.bin"; const WORK_PRODUCTS_FILENAME: &str = "work-products.bin"; const QUERY_CACHE_FILENAME: &str = "query-cache.bin"; @@ -134,6 +135,9 @@ const INT_ENCODE_BASE: usize = base_n::CASE_INSENSITIVE; pub fn dep_graph_path(sess: &Session) -> PathBuf { in_incr_comp_dir_sess(sess, DEP_GRAPH_FILENAME) } +pub fn staging_dep_graph_path(sess: &Session) -> PathBuf { + in_incr_comp_dir_sess(sess, STAGING_DEP_GRAPH_FILENAME) +} pub fn dep_graph_path_from(incr_comp_session_dir: &Path) -> PathBuf { in_incr_comp_dir(incr_comp_session_dir, DEP_GRAPH_FILENAME) } diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 2b5649bb059..259e540c612 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -5,7 +5,7 @@ use rustc_hir::definitions::Definitions; use rustc_middle::dep_graph::{PreviousDepGraph, SerializedDepGraph, WorkProduct, WorkProductId}; use rustc_middle::ty::query::OnDiskCache; use rustc_serialize::opaque::Decoder; -use rustc_serialize::Decodable as RustcDecodable; +use rustc_serialize::Decodable; use rustc_session::Session; use std::path::Path; @@ -120,7 +120,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { // Decode the list of work_products let mut work_product_decoder = Decoder::new(&work_products_data[..], start_pos); let work_products: Vec = - RustcDecodable::decode(&mut work_product_decoder).unwrap_or_else(|e| { + Decodable::decode(&mut work_product_decoder).unwrap_or_else(|e| { let msg = format!( "Error decoding `work-products` from incremental \ compilation session directory: {}", diff --git a/compiler/rustc_incremental/src/persist/mod.rs b/compiler/rustc_incremental/src/persist/mod.rs index 8821b34b502..1336189bc0d 100644 --- a/compiler/rustc_incremental/src/persist/mod.rs +++ b/compiler/rustc_incremental/src/persist/mod.rs @@ -18,6 +18,7 @@ pub use fs::prepare_session_directory; pub use load::load_query_result_cache; pub use load::LoadResult; pub use load::{load_dep_graph, DepGraphFuture}; +pub use save::build_dep_graph; pub use save::save_dep_graph; pub use save::save_work_product_index; pub use work_product::copy_cgu_workproduct_to_incr_comp_cache_dir; diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 45d474b89b8..d80397970ac 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -1,6 +1,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::join; -use rustc_middle::dep_graph::{DepGraph, WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::{DepGraph, PreviousDepGraph, WorkProduct, WorkProductId}; use rustc_middle::ty::TyCtxt; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use rustc_serialize::Encodable as RustcEncodable; @@ -15,6 +15,9 @@ use super::file_format; use super::fs::*; use super::work_product; +/// Save and dump the DepGraph. +/// +/// No query must be invoked after this function. pub fn save_dep_graph(tcx: TyCtxt<'_>) { debug!("save_dep_graph()"); tcx.dep_graph.with_ignore(|| { @@ -29,6 +32,16 @@ pub fn save_dep_graph(tcx: TyCtxt<'_>) { let query_cache_path = query_cache_path(sess); let dep_graph_path = dep_graph_path(sess); + let staging_dep_graph_path = staging_dep_graph_path(sess); + + join( + || sess.time("assert_dep_graph", || crate::assert_dep_graph(tcx)), + || sess.time("check_dirty_clean", || dirty_clean::check_dirty_clean_annotations(tcx)), + ); + + if sess.opts.debugging_opts.incremental_info { + tcx.dep_graph.print_incremental_info() + } join( move || { @@ -36,16 +49,26 @@ pub fn save_dep_graph(tcx: TyCtxt<'_>) { save_in(sess, query_cache_path, "query cache", |e| encode_query_cache(tcx, e)); }); }, - || { + move || { sess.time("incr_comp_persist_dep_graph", || { - save_in(sess, dep_graph_path, "dependency graph", |e| { - sess.time("incr_comp_encode_dep_graph", || encode_dep_graph(tcx, e)) - }); + if let Err(err) = tcx.dep_graph.encode() { + sess.err(&format!( + "failed to write dependency graph to `{}`: {}", + staging_dep_graph_path.display(), + err + )); + } + if let Err(err) = fs::rename(&staging_dep_graph_path, &dep_graph_path) { + sess.err(&format!( + "failed to move dependency graph from `{}` to `{}`: {}", + staging_dep_graph_path.display(), + dep_graph_path.display(), + err + )); + } }); }, ); - - dirty_clean::check_dirty_clean_annotations(tcx); }) } @@ -92,7 +115,7 @@ pub fn save_work_product_index( }); } -fn save_in(sess: &Session, path_buf: PathBuf, name: &str, encode: F) +pub(crate) fn save_in(sess: &Session, path_buf: PathBuf, name: &str, encode: F) where F: FnOnce(&mut FileEncoder) -> FileEncodeResult, { @@ -144,21 +167,6 @@ where debug!("save: data written to disk successfully"); } -fn encode_dep_graph(tcx: TyCtxt<'_>, encoder: &mut FileEncoder) -> FileEncodeResult { - // First encode the commandline arguments hash - tcx.sess.opts.dep_tracking_hash().encode(encoder)?; - - if tcx.sess.opts.debugging_opts.incremental_info { - tcx.dep_graph.print_incremental_info(); - } - - // There is a tiny window between printing the incremental info above and encoding the dep - // graph below in which the dep graph could change, thus making the printed incremental info - // slightly out of date. If this matters to you, please feel free to submit a patch. :) - - tcx.sess.time("incr_comp_encode_serialized_dep_graph", || tcx.dep_graph.encode(encoder)) -} - fn encode_work_product_index( work_products: &FxHashMap, encoder: &mut FileEncoder, @@ -177,3 +185,56 @@ fn encode_work_product_index( fn encode_query_cache(tcx: TyCtxt<'_>, encoder: &mut FileEncoder) -> FileEncodeResult { tcx.sess.time("incr_comp_serialize_result_cache", || tcx.serialize_query_result_cache(encoder)) } + +pub fn build_dep_graph( + sess: &Session, + prev_graph: PreviousDepGraph, + prev_work_products: FxHashMap, +) -> Option { + if sess.opts.incremental.is_none() { + // No incremental compilation. + return None; + } + + // Stream the dep-graph to an alternate file, to avoid overwriting anything in case of errors. + let path_buf = staging_dep_graph_path(sess); + + let mut encoder = match FileEncoder::new(&path_buf) { + Ok(encoder) => encoder, + Err(err) => { + sess.err(&format!( + "failed to create dependency graph at `{}`: {}", + path_buf.display(), + err + )); + return None; + } + }; + + if let Err(err) = file_format::write_file_header(&mut encoder, sess.is_nightly_build()) { + sess.err(&format!( + "failed to write dependency graph header to `{}`: {}", + path_buf.display(), + err + )); + return None; + } + + // First encode the commandline arguments hash + if let Err(err) = sess.opts.dep_tracking_hash().encode(&mut encoder) { + sess.err(&format!( + "failed to write dependency graph hash `{}`: {}", + path_buf.display(), + err + )); + return None; + } + + Some(DepGraph::new( + prev_graph, + prev_work_products, + encoder, + sess.opts.debugging_opts.query_dep_graph, + sess.opts.debugging_opts.incremental_info, + )) +} diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 87d00287828..c693155994f 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1021,9 +1021,6 @@ pub fn start_codegen<'tcx>( rustc_symbol_mangling::test::report_symbol_names(tcx); } - tcx.sess.time("assert_dep_graph", || rustc_incremental::assert_dep_graph(tcx)); - tcx.sess.time("serialize_dep_graph", || rustc_incremental::save_dep_graph(tcx)); - info!("Post-codegen\n{:?}", tcx.debug_stats()); if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) { diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 9c38d2b91ab..01853eab530 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -207,7 +207,13 @@ impl<'tcx> Queries<'tcx> { }) .open(self.session()) }); - DepGraph::new(prev_graph, prev_work_products) + + rustc_incremental::build_dep_graph( + self.session(), + prev_graph, + prev_work_products, + ) + .unwrap_or_else(DepGraph::new_disabled) } }) }) @@ -435,6 +441,9 @@ impl Compiler { if self.session().opts.debugging_opts.query_stats { gcx.enter(rustc_query_impl::print_stats); } + + self.session() + .time("serialize_dep_graph", || gcx.enter(rustc_incremental::save_dep_graph)); } _timer = Some(self.session().timer("free_global_ctxt")); diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index c688b23be1d..d2fe9af34fb 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -8,8 +8,8 @@ use rustc_session::Session; mod dep_node; pub use rustc_query_system::dep_graph::{ - debug, hash_result, DepContext, DepNodeColor, DepNodeIndex, SerializedDepNodeIndex, - WorkProduct, WorkProductId, + debug::DepNodeFilter, hash_result, DepContext, DepNodeColor, DepNodeIndex, + SerializedDepNodeIndex, WorkProduct, WorkProductId, }; crate use dep_node::make_compile_codegen_unit; @@ -20,6 +20,7 @@ pub type TaskDeps = rustc_query_system::dep_graph::TaskDeps; pub type DepGraphQuery = rustc_query_system::dep_graph::DepGraphQuery; pub type PreviousDepGraph = rustc_query_system::dep_graph::PreviousDepGraph; pub type SerializedDepGraph = rustc_query_system::dep_graph::SerializedDepGraph; +pub type EdgeFilter = rustc_query_system::dep_graph::debug::EdgeFilter; impl rustc_query_system::dep_graph::DepKind for DepKind { const NULL: Self = DepKind::Null; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index d958b3c18cd..4194b28dc7d 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -477,10 +477,7 @@ macro_rules! define_queries { return } - debug_assert!(tcx.dep_graph - .node_color(dep_node) - .map(|c| c.is_green()) - .unwrap_or(false)); + debug_assert!(tcx.dep_graph.is_green(dep_node)); let key = recover(*tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)); if queries::$name::cache_on_disk(tcx, &key, None) { diff --git a/compiler/rustc_query_system/src/dep_graph/debug.rs b/compiler/rustc_query_system/src/dep_graph/debug.rs index 43429cd11a2..a544ac2c343 100644 --- a/compiler/rustc_query_system/src/dep_graph/debug.rs +++ b/compiler/rustc_query_system/src/dep_graph/debug.rs @@ -1,6 +1,8 @@ //! Code for debugging the dep-graph. -use super::{DepKind, DepNode}; +use super::{DepKind, DepNode, DepNodeIndex}; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::Lock; use std::error::Error; /// A dep-node filter goes from a user-defined string to a query over @@ -34,13 +36,14 @@ impl DepNodeFilter { /// A filter like `F -> G` where `F` and `G` are valid dep-node /// filters. This can be used to test the source/target independently. -pub struct EdgeFilter { +pub struct EdgeFilter { pub source: DepNodeFilter, pub target: DepNodeFilter, + pub index_to_node: Lock>>, } -impl EdgeFilter { - pub fn new(test: &str) -> Result> { +impl EdgeFilter { + pub fn new(test: &str) -> Result, Box> { let parts: Vec<_> = test.split("->").collect(); if parts.len() != 2 { Err(format!("expected a filter like `a&b -> c&d`, not `{}`", test).into()) @@ -48,12 +51,13 @@ impl EdgeFilter { Ok(EdgeFilter { source: DepNodeFilter::new(parts[0]), target: DepNodeFilter::new(parts[1]), + index_to_node: Lock::new(FxHashMap::default()), }) } } #[cfg(debug_assertions)] - pub fn test(&self, source: &DepNode, target: &DepNode) -> bool { + pub fn test(&self, source: &DepNode, target: &DepNode) -> bool { self.source.test(source) && self.target.test(target) } } diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 9fe2497a57b..295b2a97e4c 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -3,29 +3,30 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::QueryInvocationId; use rustc_data_structures::sharded::{self, Sharded}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, LockGuard, Lrc, Ordering}; +use rustc_data_structures::steal::Steal; +use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering}; use rustc_data_structures::unlikely; use rustc_errors::Diagnostic; -use rustc_index::vec::{Idx, IndexVec}; -use rustc_serialize::{Encodable, Encoder}; +use rustc_index::vec::IndexVec; +use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use parking_lot::{Condvar, Mutex}; use smallvec::{smallvec, SmallVec}; use std::collections::hash_map::Entry; -use std::env; use std::hash::Hash; use std::marker::PhantomData; use std::mem; -use std::ops::Range; use std::sync::atomic::Ordering::Relaxed; -use super::debug::EdgeFilter; use super::prev::PreviousDepGraph; use super::query::DepGraphQuery; -use super::serialized::SerializedDepNodeIndex; +use super::serialized::{GraphEncoder, SerializedDepNodeIndex}; use super::{DepContext, DepKind, DepNode, HasDepContext, WorkProductId}; use crate::query::QueryContext; +#[cfg(debug_assertions)] +use {super::debug::EdgeFilter, std::env}; + #[derive(Clone)] pub struct DepGraph { data: Option>>, @@ -109,6 +110,9 @@ impl DepGraph { pub fn new( prev_graph: PreviousDepGraph, prev_work_products: FxHashMap, + encoder: FileEncoder, + record_graph: bool, + record_stats: bool, ) -> DepGraph { let prev_graph_node_count = prev_graph.node_count(); @@ -116,7 +120,12 @@ impl DepGraph { data: Some(Lrc::new(DepGraphData { previous_work_products: prev_work_products, dep_node_debug: Default::default(), - current: CurrentDepGraph::new(prev_graph_node_count), + current: CurrentDepGraph::new( + prev_graph_node_count, + encoder, + record_graph, + record_stats, + ), emitting_diagnostics: Default::default(), emitting_diagnostics_cond_var: Condvar::new(), previous: prev_graph, @@ -136,62 +145,10 @@ impl DepGraph { self.data.is_some() } - pub fn query(&self) -> DepGraphQuery { - let data = self.data.as_ref().unwrap(); - let previous = &data.previous; - - // Note locking order: `prev_index_to_index`, then `data`. - let prev_index_to_index = data.current.prev_index_to_index.lock(); - let data = data.current.data.lock(); - let node_count = data.hybrid_indices.len(); - let edge_count = self.edge_count(&data); - - let mut nodes = Vec::with_capacity(node_count); - let mut edge_list_indices = Vec::with_capacity(node_count); - let mut edge_list_data = Vec::with_capacity(edge_count); - - // See `DepGraph`'s `Encodable` implementation for notes on the approach used here. - - edge_list_data.extend(data.unshared_edges.iter().map(|i| i.index())); - - for &hybrid_index in data.hybrid_indices.iter() { - match hybrid_index.into() { - HybridIndex::New(new_index) => { - nodes.push(data.new.nodes[new_index]); - let edges = &data.new.edges[new_index]; - edge_list_indices.push((edges.start.index(), edges.end.index())); - } - HybridIndex::Red(red_index) => { - nodes.push(previous.index_to_node(data.red.node_indices[red_index])); - let edges = &data.red.edges[red_index]; - edge_list_indices.push((edges.start.index(), edges.end.index())); - } - HybridIndex::LightGreen(lg_index) => { - nodes.push(previous.index_to_node(data.light_green.node_indices[lg_index])); - let edges = &data.light_green.edges[lg_index]; - edge_list_indices.push((edges.start.index(), edges.end.index())); - } - HybridIndex::DarkGreen(prev_index) => { - nodes.push(previous.index_to_node(prev_index)); - - let edges_iter = previous - .edge_targets_from(prev_index) - .iter() - .map(|&dst| prev_index_to_index[dst].unwrap().index()); - - let start = edge_list_data.len(); - edge_list_data.extend(edges_iter); - let end = edge_list_data.len(); - edge_list_indices.push((start, end)); - } - } + pub fn with_query(&self, f: impl Fn(&DepGraphQuery)) { + if let Some(data) = &self.data { + data.current.encoder.borrow().with_query(f) } - - debug_assert_eq!(nodes.len(), node_count); - debug_assert_eq!(edge_list_indices.len(), node_count); - debug_assert_eq!(edge_list_data.len(), edge_count); - - DepGraphQuery::new(&nodes[..], &edge_list_indices[..], &edge_list_data[..]) } pub fn assert_ignored(&self) { @@ -283,56 +240,15 @@ impl DepGraph { let print_status = cfg!(debug_assertions) && dcx.sess().opts.debugging_opts.dep_tasks; // Intern the new `DepNode`. - let dep_node_index = if let Some(prev_index) = data.previous.node_to_index_opt(&key) { - // Determine the color and index of the new `DepNode`. - let (color, dep_node_index) = if let Some(current_fingerprint) = current_fingerprint - { - if current_fingerprint == data.previous.fingerprint_by_index(prev_index) { - if print_status { - eprintln!("[task::green] {:?}", key); - } - - // This is a light green node: it existed in the previous compilation, - // its query was re-executed, and it has the same result as before. - let dep_node_index = - data.current.intern_light_green_node(&data.previous, prev_index, edges); - - (DepNodeColor::Green(dep_node_index), dep_node_index) - } else { - if print_status { - eprintln!("[task::red] {:?}", key); - } - - // This is a red node: it existed in the previous compilation, its query - // was re-executed, but it has a different result from before. - let dep_node_index = data.current.intern_red_node( - &data.previous, - prev_index, - edges, - current_fingerprint, - ); - - (DepNodeColor::Red, dep_node_index) - } - } else { - if print_status { - eprintln!("[task::unknown] {:?}", key); - } - - // This is a red node, effectively: it existed in the previous compilation - // session, its query was re-executed, but it doesn't compute a result hash - // (i.e. it represents a `no_hash` query), so we have no way of determining - // whether or not the result was the same as before. - let dep_node_index = data.current.intern_red_node( - &data.previous, - prev_index, - edges, - Fingerprint::ZERO, - ); - - (DepNodeColor::Red, dep_node_index) - }; + let (dep_node_index, prev_and_color) = data.current.intern_node( + &data.previous, + key, + edges, + current_fingerprint, + print_status, + ); + if let Some((prev_index, color)) = prev_and_color { debug_assert!( data.colors.get(prev_index).is_none(), "DepGraph::with_task() - Duplicate DepNodeColor \ @@ -341,20 +257,7 @@ impl DepGraph { ); data.colors.insert(prev_index, color); - dep_node_index - } else { - if print_status { - eprintln!("[task::new] {:?}", key); - } - - // This is a new node: it didn't exist in the previous compilation session. - data.current.intern_new_node( - &data.previous, - key, - edges, - current_fingerprint.unwrap_or(Fingerprint::ZERO), - ) - }; + } (result, dep_node_index) } else { @@ -395,12 +298,8 @@ impl DepGraph { hash: data.current.anon_id_seed.combine(hasher.finish()).into(), }; - let dep_node_index = data.current.intern_new_node( - &data.previous, - target_dep_node, - task_deps.reads, - Fingerprint::ZERO, - ); + let dep_node_index = + data.current.intern_new_node(target_dep_node, task_deps.reads, Fingerprint::ZERO); (result, dep_node_index) } else { @@ -451,7 +350,7 @@ impl DepGraph { { if let Some(target) = task_deps.node { if let Some(ref forbidden_edge) = data.current.forbidden_edge { - let src = self.dep_node_of(dep_node_index); + let src = forbidden_edge.index_to_node.lock()[&dep_node_index]; if forbidden_edge.test(&src, &target) { panic!("forbidden edge {:?} -> {:?} created", src, target) } @@ -488,38 +387,6 @@ impl DepGraph { self.data.is_some() && self.dep_node_index_of_opt(dep_node).is_some() } - #[cfg(debug_assertions)] - fn dep_node_of(&self, dep_node_index: DepNodeIndex) -> DepNode { - let data = self.data.as_ref().unwrap(); - let previous = &data.previous; - let data = data.current.data.lock(); - - match data.hybrid_indices[dep_node_index].into() { - HybridIndex::New(new_index) => data.new.nodes[new_index], - HybridIndex::Red(red_index) => previous.index_to_node(data.red.node_indices[red_index]), - HybridIndex::LightGreen(light_green_index) => { - previous.index_to_node(data.light_green.node_indices[light_green_index]) - } - HybridIndex::DarkGreen(prev_index) => previous.index_to_node(prev_index), - } - } - - #[inline] - pub fn fingerprint_of(&self, dep_node_index: DepNodeIndex) -> Fingerprint { - let data = self.data.as_ref().unwrap(); - let previous = &data.previous; - let data = data.current.data.lock(); - - match data.hybrid_indices[dep_node_index].into() { - HybridIndex::New(new_index) => data.new.fingerprints[new_index], - HybridIndex::Red(red_index) => data.red.fingerprints[red_index], - HybridIndex::LightGreen(light_green_index) => { - previous.fingerprint_by_index(data.light_green.node_indices[light_green_index]) - } - HybridIndex::DarkGreen(prev_index) => previous.fingerprint_by_index(prev_index), - } - } - pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Option { self.data.as_ref().unwrap().previous.fingerprint_of(dep_node) } @@ -554,29 +421,13 @@ impl DepGraph { self.data.as_ref()?.dep_node_debug.borrow().get(&dep_node).cloned() } - fn edge_count(&self, node_data: &LockGuard<'_, DepNodeData>) -> usize { - let data = self.data.as_ref().unwrap(); - let previous = &data.previous; - - let mut edge_count = node_data.unshared_edges.len(); - - for &hybrid_index in node_data.hybrid_indices.iter() { - if let HybridIndex::DarkGreen(prev_index) = hybrid_index.into() { - edge_count += previous.edge_targets_from(prev_index).len() - } - } - - edge_count - } - - pub fn node_color(&self, dep_node: &DepNode) -> Option { + fn node_color(&self, dep_node: &DepNode) -> Option { if let Some(ref data) = self.data { if let Some(prev_index) = data.previous.node_to_index_opt(dep_node) { return data.colors.get(prev_index); } else { - // This is a node that did not exist in the previous compilation - // session, so we consider it to be red. - return Some(DepNodeColor::Red); + // This is a node that did not exist in the previous compilation session. + return None; } } @@ -862,6 +713,12 @@ impl DepGraph { } } + // Returns true if the given node has been marked as green during the + // current compilation session. Used in various assertions + pub fn is_red(&self, dep_node: &DepNode) -> bool { + self.node_color(dep_node) == Some(DepNodeColor::Red) + } + // 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 { @@ -911,106 +768,16 @@ impl DepGraph { } pub fn print_incremental_info(&self) { - #[derive(Clone)] - struct Stat { - kind: Kind, - node_counter: u64, - edge_counter: u64, + if let Some(data) = &self.data { + data.current.encoder.borrow().print_incremental_info( + data.current.total_read_count.load(Relaxed), + data.current.total_duplicate_read_count.load(Relaxed), + ) } + } - let data = self.data.as_ref().unwrap(); - let prev = &data.previous; - let current = &data.current; - let data = current.data.lock(); - - let mut stats: FxHashMap<_, Stat> = FxHashMap::with_hasher(Default::default()); - - for &hybrid_index in data.hybrid_indices.iter() { - let (kind, edge_count) = match hybrid_index.into() { - HybridIndex::New(new_index) => { - let kind = data.new.nodes[new_index].kind; - let edge_range = &data.new.edges[new_index]; - (kind, edge_range.end.as_usize() - edge_range.start.as_usize()) - } - HybridIndex::Red(red_index) => { - let kind = prev.index_to_node(data.red.node_indices[red_index]).kind; - let edge_range = &data.red.edges[red_index]; - (kind, edge_range.end.as_usize() - edge_range.start.as_usize()) - } - HybridIndex::LightGreen(lg_index) => { - let kind = prev.index_to_node(data.light_green.node_indices[lg_index]).kind; - let edge_range = &data.light_green.edges[lg_index]; - (kind, edge_range.end.as_usize() - edge_range.start.as_usize()) - } - HybridIndex::DarkGreen(prev_index) => { - let kind = prev.index_to_node(prev_index).kind; - let edge_count = prev.edge_targets_from(prev_index).len(); - (kind, edge_count) - } - }; - - let stat = stats.entry(kind).or_insert(Stat { kind, node_counter: 0, edge_counter: 0 }); - stat.node_counter += 1; - stat.edge_counter += edge_count as u64; - } - - let total_node_count = data.hybrid_indices.len(); - let total_edge_count = self.edge_count(&data); - - // Drop the lock guard. - std::mem::drop(data); - - let mut stats: Vec<_> = stats.values().cloned().collect(); - stats.sort_by_key(|s| -(s.node_counter as i64)); - - const SEPARATOR: &str = "[incremental] --------------------------------\ - ----------------------------------------------\ - ------------"; - - eprintln!("[incremental]"); - eprintln!("[incremental] DepGraph Statistics"); - eprintln!("{}", SEPARATOR); - eprintln!("[incremental]"); - eprintln!("[incremental] Total Node Count: {}", total_node_count); - eprintln!("[incremental] Total Edge Count: {}", total_edge_count); - - if cfg!(debug_assertions) { - let total_edge_reads = current.total_read_count.load(Relaxed); - let total_duplicate_edge_reads = current.total_duplicate_read_count.load(Relaxed); - - eprintln!("[incremental] Total Edge Reads: {}", total_edge_reads); - eprintln!("[incremental] Total Duplicate Edge Reads: {}", total_duplicate_edge_reads); - } - - eprintln!("[incremental]"); - - eprintln!( - "[incremental] {:<36}| {:<17}| {:<12}| {:<17}|", - "Node Kind", "Node Frequency", "Node Count", "Avg. Edge Count" - ); - - eprintln!( - "[incremental] -------------------------------------\ - |------------------\ - |-------------\ - |------------------|" - ); - - for stat in stats { - let node_kind_ratio = (100.0 * (stat.node_counter as f64)) / (total_node_count as f64); - let node_kind_avg_edges = (stat.edge_counter as f64) / (stat.node_counter as f64); - - eprintln!( - "[incremental] {:<36}|{:>16.1}% |{:>12} |{:>17.1} |", - format!("{:?}", stat.kind), - node_kind_ratio, - stat.node_counter, - node_kind_avg_edges, - ); - } - - eprintln!("{}", SEPARATOR); - eprintln!("[incremental]"); + pub fn encode(&self) -> FileEncodeResult { + if let Some(data) = &self.data { data.current.encoder.steal().finish() } else { Ok(()) } } fn next_virtual_depnode_index(&self) -> DepNodeIndex { @@ -1019,142 +786,6 @@ impl DepGraph { } } -impl> Encodable for DepGraph { - fn encode(&self, e: &mut E) -> Result<(), E::Error> { - // We used to serialize the dep graph by creating and serializing a `SerializedDepGraph` - // using data copied from the `DepGraph`. But copying created a large memory spike, so we - // now serialize directly from the `DepGraph` as if it's a `SerializedDepGraph`. Because we - // deserialize that data into a `SerializedDepGraph` in the next compilation session, we - // need `DepGraph`'s `Encodable` and `SerializedDepGraph`'s `Decodable` implementations to - // be in sync. If you update this encoding, be sure to update the decoding, and vice-versa. - - let data = self.data.as_ref().unwrap(); - let prev = &data.previous; - - // Note locking order: `prev_index_to_index`, then `data`. - let prev_index_to_index = data.current.prev_index_to_index.lock(); - let data = data.current.data.lock(); - let new = &data.new; - let red = &data.red; - let lg = &data.light_green; - - let node_count = data.hybrid_indices.len(); - let edge_count = self.edge_count(&data); - - // `rustc_middle::ty::query::OnDiskCache` expects nodes to be encoded in `DepNodeIndex` - // order. The edges in `edge_list_data` don't need to be in a particular order, as long as - // each node references its edges as a contiguous range within it. Therefore, we can encode - // `edge_list_data` directly from `unshared_edges`. It meets the above requirements, as - // each non-dark-green node already knows the range of edges to reference within it, which - // they'll encode in `edge_list_indices`. Dark green nodes, however, don't have their edges - // in `unshared_edges`, so need to add them to `edge_list_data`. - - use HybridIndex::*; - - // Encoded values (nodes, etc.) are explicitly typed below to avoid inadvertently - // serializing data in the wrong format (i.e. one incompatible with `SerializedDepGraph`). - e.emit_struct("SerializedDepGraph", 4, |e| { - e.emit_struct_field("nodes", 0, |e| { - // `SerializedDepGraph` expects this to be encoded as a sequence of `DepNode`s. - e.emit_seq(node_count, |e| { - for (seq_index, &hybrid_index) in data.hybrid_indices.iter().enumerate() { - let node: DepNode = match hybrid_index.into() { - New(i) => new.nodes[i], - Red(i) => prev.index_to_node(red.node_indices[i]), - LightGreen(i) => prev.index_to_node(lg.node_indices[i]), - DarkGreen(prev_index) => prev.index_to_node(prev_index), - }; - - e.emit_seq_elt(seq_index, |e| node.encode(e))?; - } - - Ok(()) - }) - })?; - - e.emit_struct_field("fingerprints", 1, |e| { - // `SerializedDepGraph` expects this to be encoded as a sequence of `Fingerprints`s. - e.emit_seq(node_count, |e| { - for (seq_index, &hybrid_index) in data.hybrid_indices.iter().enumerate() { - let fingerprint: Fingerprint = match hybrid_index.into() { - New(i) => new.fingerprints[i], - Red(i) => red.fingerprints[i], - LightGreen(i) => prev.fingerprint_by_index(lg.node_indices[i]), - DarkGreen(prev_index) => prev.fingerprint_by_index(prev_index), - }; - - e.emit_seq_elt(seq_index, |e| fingerprint.encode(e))?; - } - - Ok(()) - }) - })?; - - e.emit_struct_field("edge_list_indices", 2, |e| { - // `SerializedDepGraph` expects this to be encoded as a sequence of `(u32, u32)`s. - e.emit_seq(node_count, |e| { - // Dark green node edges start after the unshared (all other nodes') edges. - let mut dark_green_edge_index = data.unshared_edges.len(); - - for (seq_index, &hybrid_index) in data.hybrid_indices.iter().enumerate() { - let edge_indices: (u32, u32) = match hybrid_index.into() { - New(i) => (new.edges[i].start.as_u32(), new.edges[i].end.as_u32()), - Red(i) => (red.edges[i].start.as_u32(), red.edges[i].end.as_u32()), - LightGreen(i) => (lg.edges[i].start.as_u32(), lg.edges[i].end.as_u32()), - DarkGreen(prev_index) => { - let edge_count = prev.edge_targets_from(prev_index).len(); - let start = dark_green_edge_index as u32; - dark_green_edge_index += edge_count; - let end = dark_green_edge_index as u32; - (start, end) - } - }; - - e.emit_seq_elt(seq_index, |e| edge_indices.encode(e))?; - } - - assert_eq!(dark_green_edge_index, edge_count); - - Ok(()) - }) - })?; - - e.emit_struct_field("edge_list_data", 3, |e| { - // `SerializedDepGraph` expects this to be encoded as a sequence of - // `SerializedDepNodeIndex`. - e.emit_seq(edge_count, |e| { - for (seq_index, &edge) in data.unshared_edges.iter().enumerate() { - let serialized_edge = SerializedDepNodeIndex::new(edge.index()); - e.emit_seq_elt(seq_index, |e| serialized_edge.encode(e))?; - } - - let mut seq_index = data.unshared_edges.len(); - - for &hybrid_index in data.hybrid_indices.iter() { - if let DarkGreen(prev_index) = hybrid_index.into() { - for &edge in prev.edge_targets_from(prev_index) { - // Dark green node edges are stored in the previous graph - // and must be converted to edges in the current graph, - // and then serialized as `SerializedDepNodeIndex`. - let serialized_edge = SerializedDepNodeIndex::new( - prev_index_to_index[edge].as_ref().unwrap().index(), - ); - - e.emit_seq_elt(seq_index, |e| serialized_edge.encode(e))?; - seq_index += 1; - } - } - } - - assert_eq!(seq_index, edge_count); - - Ok(()) - }) - }) - }) - } -} - /// A "work product" is an intermediate result that we save into the /// incremental directory for later re-use. The primary example are /// the object files that we save for each partition at code @@ -1193,201 +824,11 @@ pub struct WorkProduct { pub saved_file: Option, } -// The maximum value of the follow index types leaves the upper two bits unused -// so that we can store multiple index types in `CompressedHybridIndex`, and use -// those bits to encode which index type it contains. - -// Index type for `NewDepNodeData`. -rustc_index::newtype_index! { - struct NewDepNodeIndex { - MAX = 0x7FFF_FFFF - } -} - -// Index type for `RedDepNodeData`. -rustc_index::newtype_index! { - struct RedDepNodeIndex { - MAX = 0x7FFF_FFFF - } -} - -// Index type for `LightGreenDepNodeData`. -rustc_index::newtype_index! { - struct LightGreenDepNodeIndex { - MAX = 0x7FFF_FFFF - } -} - -/// Compressed representation of `HybridIndex` enum. Bits unused by the -/// contained index types are used to encode which index type it contains. -#[derive(Copy, Clone)] -struct CompressedHybridIndex(u32); - -impl CompressedHybridIndex { - const NEW_TAG: u32 = 0b0000_0000_0000_0000_0000_0000_0000_0000; - const RED_TAG: u32 = 0b0100_0000_0000_0000_0000_0000_0000_0000; - const LIGHT_GREEN_TAG: u32 = 0b1000_0000_0000_0000_0000_0000_0000_0000; - const DARK_GREEN_TAG: u32 = 0b1100_0000_0000_0000_0000_0000_0000_0000; - - const TAG_MASK: u32 = 0b1100_0000_0000_0000_0000_0000_0000_0000; - const INDEX_MASK: u32 = !Self::TAG_MASK; -} - -impl From for CompressedHybridIndex { - #[inline] - fn from(index: NewDepNodeIndex) -> Self { - CompressedHybridIndex(Self::NEW_TAG | index.as_u32()) - } -} - -impl From for CompressedHybridIndex { - #[inline] - fn from(index: RedDepNodeIndex) -> Self { - CompressedHybridIndex(Self::RED_TAG | index.as_u32()) - } -} - -impl From for CompressedHybridIndex { - #[inline] - fn from(index: LightGreenDepNodeIndex) -> Self { - CompressedHybridIndex(Self::LIGHT_GREEN_TAG | index.as_u32()) - } -} - -impl From for CompressedHybridIndex { - #[inline] - fn from(index: SerializedDepNodeIndex) -> Self { - CompressedHybridIndex(Self::DARK_GREEN_TAG | index.as_u32()) - } -} - -/// Contains an index into one of several node data collections. Elsewhere, we -/// store `CompressedHyridIndex` instead of this to save space, but convert to -/// this type during processing to take advantage of the enum match ergonomics. -enum HybridIndex { - New(NewDepNodeIndex), - Red(RedDepNodeIndex), - LightGreen(LightGreenDepNodeIndex), - DarkGreen(SerializedDepNodeIndex), -} - -impl From for HybridIndex { - #[inline] - fn from(hybrid_index: CompressedHybridIndex) -> Self { - let index = hybrid_index.0 & CompressedHybridIndex::INDEX_MASK; - - match hybrid_index.0 & CompressedHybridIndex::TAG_MASK { - CompressedHybridIndex::NEW_TAG => HybridIndex::New(NewDepNodeIndex::from_u32(index)), - CompressedHybridIndex::RED_TAG => HybridIndex::Red(RedDepNodeIndex::from_u32(index)), - CompressedHybridIndex::LIGHT_GREEN_TAG => { - HybridIndex::LightGreen(LightGreenDepNodeIndex::from_u32(index)) - } - CompressedHybridIndex::DARK_GREEN_TAG => { - HybridIndex::DarkGreen(SerializedDepNodeIndex::from_u32(index)) - } - _ => unreachable!(), - } - } -} - // Index type for `DepNodeData`'s edges. rustc_index::newtype_index! { struct EdgeIndex { .. } } -/// Data for nodes in the current graph, divided into different collections -/// based on their presence in the previous graph, and if present, their color. -/// We divide nodes this way because different types of nodes are able to share -/// more or less data with the previous graph. -/// -/// To enable more sharing, we distinguish between two kinds of green nodes. -/// Light green nodes are nodes in the previous graph that have been marked -/// green because we re-executed their queries and the results were the same as -/// in the previous session. Dark green nodes are nodes in the previous graph -/// that have been marked green because we were able to mark all of their -/// dependencies green. -/// -/// Both light and dark green nodes can share the dep node and fingerprint with -/// the previous graph, but for light green nodes, we can't be sure that the -/// edges may be shared without comparing them against the previous edges, so we -/// store them directly (an approach in which we compare edges with the previous -/// edges to see if they can be shared was evaluated, but was not found to be -/// very profitable). -/// -/// For dark green nodes, we can share everything with the previous graph, which -/// is why the `HybridIndex::DarkGreen` enum variant contains the index of the -/// node in the previous graph, and why we don't have a separate collection for -/// dark green node data--the collection is the `PreviousDepGraph` itself. -/// -/// (Note that for dark green nodes, the edges in the previous graph -/// (`SerializedDepNodeIndex`s) must be converted to edges in the current graph -/// (`DepNodeIndex`s). `CurrentDepGraph` contains `prev_index_to_index`, which -/// can perform this conversion. It should always be possible, as by definition, -/// a dark green node is one whose dependencies from the previous session have -/// all been marked green--which means `prev_index_to_index` contains them.) -/// -/// Node data is stored in parallel vectors to eliminate the padding between -/// elements that would be needed to satisfy alignment requirements of the -/// structure that would contain all of a node's data. We could group tightly -/// packing subsets of node data together and use fewer vectors, but for -/// consistency's sake, we use separate vectors for each piece of data. -struct DepNodeData { - /// Data for nodes not in previous graph. - new: NewDepNodeData, - - /// Data for nodes in previous graph that have been marked red. - red: RedDepNodeData, - - /// Data for nodes in previous graph that have been marked light green. - light_green: LightGreenDepNodeData, - - // Edges for all nodes other than dark-green ones. Edges for each node - // occupy a contiguous region of this collection, which a node can reference - // using two indices. Storing edges this way rather than using an `EdgesVec` - // for each node reduces memory consumption by a not insignificant amount - // when compiling large crates. The downside is that we have to copy into - // this collection the edges from the `EdgesVec`s that are built up during - // query execution. But this is mostly balanced out by the more efficient - // implementation of `DepGraph::serialize` enabled by this representation. - unshared_edges: IndexVec, - - /// Mapping from `DepNodeIndex` to an index into a collection above. - /// Indicates which of the above collections contains a node's data. - /// - /// This collection is wasteful in time and space during incr-full builds, - /// because for those, all nodes are new. However, the waste is relatively - /// small, and the maintenance cost of avoiding using this for incr-full - /// builds is somewhat high and prone to bugginess. It does not seem worth - /// it at the time of this writing, but we may want to revisit the idea. - hybrid_indices: IndexVec, -} - -/// Data for nodes not in previous graph. Since we cannot share any data with -/// the previous graph, so we must store all of such a node's data here. -struct NewDepNodeData { - nodes: IndexVec>, - edges: IndexVec>, - fingerprints: IndexVec, -} - -/// Data for nodes in previous graph that have been marked red. We can share the -/// dep node with the previous graph, but the edges may be different, and the -/// fingerprint is known to be different, so we store the latter two directly. -struct RedDepNodeData { - node_indices: IndexVec, - edges: IndexVec>, - fingerprints: IndexVec, -} - -/// Data for nodes in previous graph that have been marked green because we -/// re-executed their queries and the results were the same as in the previous -/// session. We can share the dep node and the fingerprint with the previous -/// graph, but the edges may be different, so we store them directly. -struct LightGreenDepNodeData { - node_indices: IndexVec, - edges: IndexVec>, -} - /// `CurrentDepGraph` stores the dependency graph for the current session. It /// will be populated as we run queries or tasks. We never remove nodes from the /// graph: they are only added. @@ -1417,15 +858,15 @@ struct LightGreenDepNodeData { /// `new_node_to_index` and `data`, or `prev_index_to_index` and `data`. When /// manipulating both, we acquire `new_node_to_index` or `prev_index_to_index` /// first, and `data` second. -pub(super) struct CurrentDepGraph { - data: Lock>, +pub(super) struct CurrentDepGraph { + encoder: Steal>, new_node_to_index: Sharded, DepNodeIndex>>, prev_index_to_index: 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`. - #[allow(dead_code)] - forbidden_edge: Option, + #[cfg(debug_assertions)] + forbidden_edge: Option>, /// Anonymous `DepNode`s are nodes whose IDs we compute from the list of /// their edges. This has the beneficial side-effect that multiple anonymous @@ -1447,7 +888,12 @@ pub(super) struct CurrentDepGraph { } impl CurrentDepGraph { - fn new(prev_graph_node_count: usize) -> CurrentDepGraph { + fn new( + prev_graph_node_count: usize, + encoder: FileEncoder, + record_graph: bool, + record_stats: bool, + ) -> CurrentDepGraph { use std::time::{SystemTime, UNIX_EPOCH}; let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); @@ -1455,70 +901,29 @@ impl CurrentDepGraph { let mut stable_hasher = StableHasher::new(); nanos.hash(&mut stable_hasher); - let forbidden_edge = if cfg!(debug_assertions) { - match env::var("RUST_FORBID_DEP_GRAPH_EDGE") { - Ok(s) => match EdgeFilter::new(&s) { - Ok(f) => Some(f), - Err(err) => panic!("RUST_FORBID_DEP_GRAPH_EDGE invalid: {}", err), - }, - Err(_) => None, - } - } else { - None + #[cfg(debug_assertions)] + let forbidden_edge = match env::var("RUST_FORBID_DEP_GRAPH_EDGE") { + Ok(s) => match EdgeFilter::new(&s) { + Ok(f) => Some(f), + Err(err) => panic!("RUST_FORBID_DEP_GRAPH_EDGE invalid: {}", err), + }, + Err(_) => None, }; - // Pre-allocate the dep node structures. We over-allocate a little so - // that we hopefully don't have to re-allocate during this compilation - // session. The over-allocation for new nodes is 2% plus a small - // constant to account for the fact that in very small crates 2% might - // not be enough. The allocation for red and green node data doesn't - // include a constant, as we don't want to allocate anything for these - // structures during full incremental builds, where they aren't used. - // - // These estimates are based on the distribution of node and edge counts - // seen in rustc-perf benchmarks, adjusted somewhat to account for the - // fact that these benchmarks aren't perfectly representative. - // - // FIXME Use a collection type that doesn't copy node and edge data and - // grow multiplicatively on reallocation. Without such a collection or - // solution having the same effect, there is a performance hazard here - // in both time and space, as growing these collections means copying a - // large amount of data and doubling already large buffer capacities. A - // solution for this will also mean that it's less important to get - // these estimates right. - let new_node_count_estimate = (prev_graph_node_count * 2) / 100 + 200; - let red_node_count_estimate = (prev_graph_node_count * 3) / 100; - let light_green_node_count_estimate = (prev_graph_node_count * 25) / 100; - let total_node_count_estimate = prev_graph_node_count + new_node_count_estimate; - - let average_edges_per_node_estimate = 6; - let unshared_edge_count_estimate = average_edges_per_node_estimate - * (new_node_count_estimate + red_node_count_estimate + light_green_node_count_estimate); - // We store a large collection of these in `prev_index_to_index` during // non-full incremental builds, and want to ensure that the element size // doesn't inadvertently increase. static_assert_size!(Option, 4); + let new_node_count_estimate = 102 * prev_graph_node_count / 100 + 200; + CurrentDepGraph { - data: Lock::new(DepNodeData { - new: NewDepNodeData { - nodes: IndexVec::with_capacity(new_node_count_estimate), - edges: IndexVec::with_capacity(new_node_count_estimate), - fingerprints: IndexVec::with_capacity(new_node_count_estimate), - }, - red: RedDepNodeData { - node_indices: IndexVec::with_capacity(red_node_count_estimate), - edges: IndexVec::with_capacity(red_node_count_estimate), - fingerprints: IndexVec::with_capacity(red_node_count_estimate), - }, - light_green: LightGreenDepNodeData { - node_indices: IndexVec::with_capacity(light_green_node_count_estimate), - edges: IndexVec::with_capacity(light_green_node_count_estimate), - }, - unshared_edges: IndexVec::with_capacity(unshared_edge_count_estimate), - hybrid_indices: IndexVec::with_capacity(total_node_count_estimate), - }), + encoder: Steal::new(GraphEncoder::new( + encoder, + prev_graph_node_count, + record_graph, + record_stats, + )), new_node_to_index: Sharded::new(|| { FxHashMap::with_capacity_and_hasher( new_node_count_estimate / sharded::SHARDS, @@ -1527,6 +932,7 @@ impl CurrentDepGraph { }), prev_index_to_index: Lock::new(IndexVec::from_elem_n(None, prev_graph_node_count)), anon_id_seed: stable_hasher.finish(), + #[cfg(debug_assertions)] forbidden_edge, total_read_count: AtomicU64::new(0), total_duplicate_read_count: AtomicU64::new(0), @@ -1535,76 +941,124 @@ impl CurrentDepGraph { fn intern_new_node( &self, - prev_graph: &PreviousDepGraph, - dep_node: DepNode, + key: DepNode, edges: EdgesVec, - fingerprint: Fingerprint, + current_fingerprint: Fingerprint, ) -> DepNodeIndex { - debug_assert!( - prev_graph.node_to_index_opt(&dep_node).is_none(), - "node in previous graph should be interned using one \ - of `intern_red_node`, `intern_light_green_node`, etc." - ); - - match self.new_node_to_index.get_shard_by_value(&dep_node).lock().entry(dep_node) { + match self.new_node_to_index.get_shard_by_value(&key).lock().entry(key) { Entry::Occupied(entry) => *entry.get(), Entry::Vacant(entry) => { - let data = &mut *self.data.lock(); - let new_index = data.new.nodes.push(dep_node); - add_edges(&mut data.unshared_edges, &mut data.new.edges, edges); - data.new.fingerprints.push(fingerprint); - let dep_node_index = data.hybrid_indices.push(new_index.into()); + let dep_node_index = self.encoder.borrow().send(key, current_fingerprint, edges); entry.insert(dep_node_index); + #[cfg(debug_assertions)] + if let Some(forbidden_edge) = &self.forbidden_edge { + forbidden_edge.index_to_node.lock().insert(dep_node_index, key); + } dep_node_index } } } - fn intern_red_node( + fn intern_node( &self, prev_graph: &PreviousDepGraph, - prev_index: SerializedDepNodeIndex, + key: DepNode, edges: EdgesVec, - fingerprint: Fingerprint, - ) -> DepNodeIndex { - self.debug_assert_not_in_new_nodes(prev_graph, prev_index); + current_fingerprint: Option, + print_status: bool, + ) -> (DepNodeIndex, Option<(SerializedDepNodeIndex, DepNodeColor)>) { + let print_status = cfg!(debug_assertions) && print_status; - let mut prev_index_to_index = self.prev_index_to_index.lock(); + if let Some(prev_index) = prev_graph.node_to_index_opt(&key) { + // Determine the color and index of the new `DepNode`. + if let Some(current_fingerprint) = current_fingerprint { + if current_fingerprint == prev_graph.fingerprint_by_index(prev_index) { + if print_status { + eprintln!("[task::green] {:?}", key); + } - match prev_index_to_index[prev_index] { - Some(dep_node_index) => dep_node_index, - None => { - let data = &mut *self.data.lock(); - let red_index = data.red.node_indices.push(prev_index); - add_edges(&mut data.unshared_edges, &mut data.red.edges, edges); - data.red.fingerprints.push(fingerprint); - let dep_node_index = data.hybrid_indices.push(red_index.into()); - prev_index_to_index[prev_index] = Some(dep_node_index); - dep_node_index + // This is a light green node: it existed in the previous compilation, + // its query was re-executed, and it has the same result as before. + let mut prev_index_to_index = self.prev_index_to_index.lock(); + + let dep_node_index = match prev_index_to_index[prev_index] { + Some(dep_node_index) => dep_node_index, + None => { + let dep_node_index = + self.encoder.borrow().send(key, current_fingerprint, edges); + prev_index_to_index[prev_index] = Some(dep_node_index); + dep_node_index + } + }; + + #[cfg(debug_assertions)] + if let Some(forbidden_edge) = &self.forbidden_edge { + forbidden_edge.index_to_node.lock().insert(dep_node_index, key); + } + (dep_node_index, Some((prev_index, DepNodeColor::Green(dep_node_index)))) + } else { + if print_status { + eprintln!("[task::red] {:?}", key); + } + + // This is a red node: it existed in the previous compilation, its query + // was re-executed, but it has a different result from before. + let mut prev_index_to_index = self.prev_index_to_index.lock(); + + let dep_node_index = match prev_index_to_index[prev_index] { + Some(dep_node_index) => dep_node_index, + None => { + let dep_node_index = + self.encoder.borrow().send(key, current_fingerprint, edges); + prev_index_to_index[prev_index] = Some(dep_node_index); + dep_node_index + } + }; + + #[cfg(debug_assertions)] + if let Some(forbidden_edge) = &self.forbidden_edge { + forbidden_edge.index_to_node.lock().insert(dep_node_index, key); + } + (dep_node_index, Some((prev_index, DepNodeColor::Red))) + } + } else { + if print_status { + eprintln!("[task::unknown] {:?}", key); + } + + // This is a red node, effectively: it existed in the previous compilation + // session, its query was re-executed, but it doesn't compute a result hash + // (i.e. it represents a `no_hash` query), so we have no way of determining + // whether or not the result was the same as before. + let mut prev_index_to_index = self.prev_index_to_index.lock(); + + let dep_node_index = match prev_index_to_index[prev_index] { + Some(dep_node_index) => dep_node_index, + None => { + let dep_node_index = + self.encoder.borrow().send(key, Fingerprint::ZERO, edges); + prev_index_to_index[prev_index] = Some(dep_node_index); + dep_node_index + } + }; + + #[cfg(debug_assertions)] + if let Some(forbidden_edge) = &self.forbidden_edge { + forbidden_edge.index_to_node.lock().insert(dep_node_index, key); + } + (dep_node_index, Some((prev_index, DepNodeColor::Red))) } - } - } - - fn intern_light_green_node( - &self, - prev_graph: &PreviousDepGraph, - prev_index: SerializedDepNodeIndex, - edges: EdgesVec, - ) -> DepNodeIndex { - self.debug_assert_not_in_new_nodes(prev_graph, prev_index); - - let mut prev_index_to_index = self.prev_index_to_index.lock(); - - match prev_index_to_index[prev_index] { - Some(dep_node_index) => dep_node_index, - None => { - let data = &mut *self.data.lock(); - let light_green_index = data.light_green.node_indices.push(prev_index); - add_edges(&mut data.unshared_edges, &mut data.light_green.edges, edges); - let dep_node_index = data.hybrid_indices.push(light_green_index.into()); - prev_index_to_index[prev_index] = Some(dep_node_index); - dep_node_index + } else { + if print_status { + eprintln!("[task::new] {:?}", key); } + + let current_fingerprint = current_fingerprint.unwrap_or(Fingerprint::ZERO); + + // This is a new node: it didn't exist in the previous compilation session. + let dep_node_index = self.intern_new_node(key, edges, current_fingerprint); + + (dep_node_index, None) } } @@ -1620,9 +1074,21 @@ impl CurrentDepGraph { match prev_index_to_index[prev_index] { Some(dep_node_index) => dep_node_index, None => { - let mut data = self.data.lock(); - let dep_node_index = data.hybrid_indices.push(prev_index.into()); + let key = prev_graph.index_to_node(prev_index); + let dep_node_index = self.encoder.borrow().send( + key, + prev_graph.fingerprint_by_index(prev_index), + prev_graph + .edge_targets_from(prev_index) + .iter() + .map(|i| prev_index_to_index[*i].unwrap()) + .collect(), + ); prev_index_to_index[prev_index] = Some(dep_node_index); + #[cfg(debug_assertions)] + if let Some(forbidden_edge) = &self.forbidden_edge { + forbidden_edge.index_to_node.lock().insert(dep_node_index, key); + } dep_node_index } } @@ -1642,18 +1108,6 @@ impl CurrentDepGraph { } } -#[inline] -fn add_edges( - edges: &mut IndexVec, - edge_indices: &mut IndexVec>, - new_edges: EdgesVec, -) { - let start = edges.next_index(); - edges.extend(new_edges); - let end = edges.next_index(); - edge_indices.push(start..end); -} - /// The capacity of the `reads` field `SmallVec` const TASK_DEPS_READS_CAP: usize = 8; type EdgesVec = SmallVec<[DepNodeIndex; TASK_DEPS_READS_CAP]>; diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index e8fb71be3e0..1b6ecf3e637 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -13,6 +13,7 @@ pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::Lock; +use rustc_serialize::{opaque::FileEncoder, Encodable}; use rustc_session::Session; use std::fmt; @@ -59,7 +60,7 @@ impl HasDepContext for T { } /// Describe the different families of dependency nodes. -pub trait DepKind: Copy + fmt::Debug + Eq + Hash { +pub trait DepKind: Copy + fmt::Debug + Eq + Hash + Send + Encodable + 'static { const NULL: Self; /// Return whether this kind always require evaluation. diff --git a/compiler/rustc_query_system/src/dep_graph/query.rs b/compiler/rustc_query_system/src/dep_graph/query.rs index e678a16249b..9c85cdd59d9 100644 --- a/compiler/rustc_query_system/src/dep_graph/query.rs +++ b/compiler/rustc_query_system/src/dep_graph/query.rs @@ -1,7 +1,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::implementation::{Direction, Graph, NodeIndex, INCOMING}; -use super::{DepKind, DepNode}; +use super::{DepKind, DepNode, DepNodeIndex}; pub struct DepGraphQuery { pub graph: Graph, ()>, @@ -9,28 +9,27 @@ pub struct DepGraphQuery { } impl DepGraphQuery { - pub fn new( - nodes: &[DepNode], - edge_list_indices: &[(usize, usize)], - edge_list_data: &[usize], - ) -> DepGraphQuery { - let mut graph = Graph::with_capacity(nodes.len(), edge_list_data.len()); - let mut indices = FxHashMap::default(); - for node in nodes { - indices.insert(*node, graph.add_node(*node)); - } + pub fn new(prev_node_count: usize) -> DepGraphQuery { + let node_count = prev_node_count + prev_node_count / 4; + let edge_count = 6 * node_count; - for (source, &(start, end)) in edge_list_indices.iter().enumerate() { - for &target in &edge_list_data[start..end] { - let source = indices[&nodes[source]]; - let target = indices[&nodes[target]]; - graph.add_edge(source, target, ()); - } - } + let graph = Graph::with_capacity(node_count, edge_count); + let indices = FxHashMap::default(); DepGraphQuery { graph, indices } } + pub fn push(&mut self, index: DepNodeIndex, node: DepNode, edges: &[DepNodeIndex]) { + let source = self.graph.add_node(node); + debug_assert_eq!(index.index(), source.0); + self.indices.insert(node, source); + + for &target in edges.iter() { + let target = NodeIndex(target.index()); + self.graph.add_edge(source, target, ()); + } + } + pub fn nodes(&self) -> Vec<&DepNode> { self.graph.all_nodes().iter().map(|n| &n.data).collect() } diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 9bb922b0a90..a76100cc228 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -1,9 +1,18 @@ //! The data that we will serialize and deserialize. -use super::{DepKind, DepNode}; +use super::query::DepGraphQuery; +use super::{DepKind, DepNode, DepNodeIndex}; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_index::vec::IndexVec; -use rustc_serialize::{Decodable, Decoder}; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::{AtomicU32, Lock, Lrc, Ordering}; +use rustc_index::vec::{Idx, IndexVec}; +use rustc_serialize::opaque::{self, FileEncodeResult, FileEncoder, IntEncodedWithFixedSize}; +use rustc_serialize::{Decodable, Encodable}; +use smallvec::SmallVec; +use std::convert::TryInto; + +#[cfg(parallel_compiler)] +use {rustc_data_structures::sync::WorkerLocal, std::sync::mpsc, std::thread}; // The maximum value of `SerializedDepNodeIndex` leaves the upper two bits // unused so that we can store multiple index types in `CompressedHybridIndex`, @@ -50,78 +59,347 @@ impl SerializedDepGraph { } } -impl> Decodable for SerializedDepGraph { - fn decode(d: &mut D) -> Result, D::Error> { - // We used to serialize the dep graph by creating and serializing a `SerializedDepGraph` - // using data copied from the `DepGraph`. But copying created a large memory spike, so we - // now serialize directly from the `DepGraph` as if it's a `SerializedDepGraph`. Because we - // deserialize that data into a `SerializedDepGraph` in the next compilation session, we - // need `DepGraph`'s `Encodable` and `SerializedDepGraph`'s `Decodable` implementations to - // be in sync. If you update this decoding, be sure to update the encoding, and vice-versa. - // - // We mimic the sequence of `Encode` and `Encodable` method calls used by the `DepGraph`'s - // `Encodable` implementation with the corresponding sequence of `Decode` and `Decodable` - // method calls. E.g. `Decode::read_struct` pairs with `Encode::emit_struct`, `DepNode`'s - // `decode` pairs with `DepNode`'s `encode`, and so on. Any decoding methods not associated - // with corresponding encoding methods called in `DepGraph`'s `Encodable` implementation - // are off limits, because we'd be relying on their implementation details. - // - // For example, because we know it happens to do the right thing, its tempting to just use - // `IndexVec`'s `Decodable` implementation to decode into some of the collections below, - // even though `DepGraph` doesn't use its `Encodable` implementation. But the `IndexVec` - // implementation could change, and we'd have a bug. - // - // Variables below are explicitly typed so that anyone who changes the `SerializedDepGraph` - // representation without updating this function will encounter a compilation error, and - // know to update this and possibly the `DepGraph` `Encodable` implementation accordingly - // (the latter should serialize data in a format compatible with our representation). +impl<'a, K: DepKind + Decodable>> Decodable> + for SerializedDepGraph +{ + #[instrument(skip(d))] + fn decode(d: &mut opaque::Decoder<'a>) -> Result, String> { + let position = d.position(); - d.read_struct("SerializedDepGraph", 4, |d| { - let nodes: IndexVec> = - d.read_struct_field("nodes", 0, |d| { - d.read_seq(|d, len| { - let mut v = IndexVec::with_capacity(len); - for i in 0..len { - v.push(d.read_seq_elt(i, |d| Decodable::decode(d))?); - } - Ok(v) - }) - })?; + // The last 16 bytes are the node count and edge count. + debug!("position: {:?}", d.position()); + d.set_position(d.data.len() - 2 * IntEncodedWithFixedSize::ENCODED_SIZE); + debug!("position: {:?}", d.position()); - let fingerprints: IndexVec = - d.read_struct_field("fingerprints", 1, |d| { - d.read_seq(|d, len| { - let mut v = IndexVec::with_capacity(len); - for i in 0..len { - v.push(d.read_seq_elt(i, |d| Decodable::decode(d))?); - } - Ok(v) - }) - })?; + let node_count = IntEncodedWithFixedSize::decode(d)?.0 as usize; + let edge_count = IntEncodedWithFixedSize::decode(d)?.0 as usize; + debug!(?node_count, ?edge_count); - let edge_list_indices: IndexVec = d - .read_struct_field("edge_list_indices", 2, |d| { - d.read_seq(|d, len| { - let mut v = IndexVec::with_capacity(len); - for i in 0..len { - v.push(d.read_seq_elt(i, |d| Decodable::decode(d))?); - } - Ok(v) - }) - })?; + debug!("position: {:?}", d.position()); + d.set_position(position); + debug!("position: {:?}", d.position()); - let edge_list_data: Vec = - d.read_struct_field("edge_list_data", 3, |d| { - d.read_seq(|d, len| { - let mut v = Vec::with_capacity(len); - for i in 0..len { - v.push(d.read_seq_elt(i, |d| Decodable::decode(d))?); - } - Ok(v) - }) - })?; + let mut nodes = IndexVec::with_capacity(node_count); + let mut fingerprints = IndexVec::with_capacity(node_count); + let mut edge_list_indices = IndexVec::with_capacity(node_count); + let mut edge_list_data = Vec::with_capacity(edge_count); - Ok(SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data }) - }) + for _index in 0..node_count { + let node = NodeInfo::::decode(d)?; + debug!(?_index, ?node); + + let _i: SerializedDepNodeIndex = nodes.push(node.node); + debug_assert_eq!(_i.index(), _index); + let _i: SerializedDepNodeIndex = fingerprints.push(node.fingerprint); + debug_assert_eq!(_i.index(), _index); + + let start = edge_list_data.len().try_into().unwrap(); + edge_list_data.extend(node.edges.into_iter()); + let end = edge_list_data.len().try_into().unwrap(); + + let _i: SerializedDepNodeIndex = edge_list_indices.push((start, end)); + debug_assert_eq!(_i.index(), _index); + } + + Ok(SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data }) } } + +#[derive(Debug, Encodable, Decodable)] +pub struct NodeInfo { + node: DepNode, + fingerprint: Fingerprint, + edges: SmallVec<[I; 8]>, +} + +struct Stat { + kind: K, + node_counter: u64, + edge_counter: u64, +} + +struct Stats { + stats: FxHashMap>, + total_node_count: usize, + total_edge_count: usize, +} + +#[instrument(skip(encoder, _record_graph, record_stats))] +fn encode_node( + encoder: &mut FileEncoder, + _index: DepNodeIndex, + node: &NodeInfo, + _record_graph: &Option>>>, + record_stats: &Option>>>, +) -> FileEncodeResult { + #[cfg(debug_assertions)] + if let Some(record_graph) = &_record_graph { + record_graph.lock().push(_index, node.node, &node.edges); + } + + if let Some(record_stats) = &record_stats { + let mut stats = record_stats.lock(); + let kind = node.node.kind; + let edge_count = node.edges.len(); + + let stat = + stats.stats.entry(kind).or_insert(Stat { kind, node_counter: 0, edge_counter: 0 }); + stat.node_counter += 1; + stat.edge_counter += edge_count as u64; + stats.total_node_count += 1; + stats.total_edge_count += edge_count; + } + + debug!(?_index, ?node); + node.encode(encoder) +} + +fn encode_counts( + mut encoder: FileEncoder, + node_count: usize, + edge_count: usize, +) -> FileEncodeResult { + let node_count = node_count.try_into().unwrap(); + let edge_count = edge_count.try_into().unwrap(); + + debug!(?node_count, ?edge_count); + debug!("position: {:?}", encoder.position()); + IntEncodedWithFixedSize(node_count).encode(&mut encoder)?; + IntEncodedWithFixedSize(edge_count).encode(&mut encoder)?; + debug!("position: {:?}", encoder.position()); + // Drop the encoder so that nothing is written after the counts. + encoder.flush() +} + +#[cfg(not(parallel_compiler))] +pub struct GraphEncoder { + status: Lock<(FileEncoder, usize, FileEncodeResult)>, + counter: AtomicU32, + record_graph: Option>>>, + record_stats: Option>>>, +} + +#[cfg(parallel_compiler)] +pub struct GraphEncoder { + send: WorkerLocal)>>, + thread: thread::JoinHandle, + counter: AtomicU32, + record_graph: Option>>>, + record_stats: Option>>>, +} + +impl> GraphEncoder { + pub fn new( + encoder: FileEncoder, + prev_node_count: usize, + record_graph: bool, + record_stats: bool, + ) -> Self { + let record_graph = if cfg!(debug_assertions) && record_graph { + Some(Lrc::new(Lock::new(DepGraphQuery::new(prev_node_count)))) + } else { + None + }; + let record_stats = if record_stats { + Some(Lrc::new(Lock::new(Stats { + stats: FxHashMap::default(), + total_node_count: 0, + total_edge_count: 0, + }))) + } else { + None + }; + let counter = AtomicU32::new(0); + + #[cfg(not(parallel_compiler))] + { + let status = Lock::new((encoder, 0, Ok(()))); + GraphEncoder { status, counter, record_graph, record_stats } + } + #[cfg(parallel_compiler)] + { + let (send, recv) = mpsc::channel(); + let thread = { + let record_graph = record_graph.clone(); + let record_stats = record_stats.clone(); + thread::spawn(move || { + encode_graph(encoder, recv, |encoder, index, node| { + encode_node(encoder, index, node, &record_graph, &record_stats) + }) + }) + }; + let send = WorkerLocal::new(move |_| send.clone()); + + GraphEncoder { send, thread, counter, record_graph, record_stats } + } + } + + pub(crate) fn with_query(&self, f: impl Fn(&DepGraphQuery)) { + if let Some(record_graph) = &self.record_graph { + f(&record_graph.lock()) + } + } + + pub(crate) fn print_incremental_info( + &self, + total_read_count: u64, + total_duplicate_read_count: u64, + ) { + if let Some(record_stats) = &self.record_stats { + let record_stats = record_stats.lock(); + + let mut stats: Vec<_> = record_stats.stats.values().collect(); + stats.sort_by_key(|s| -(s.node_counter as i64)); + + const SEPARATOR: &str = "[incremental] --------------------------------\ + ----------------------------------------------\ + ------------"; + + eprintln!("[incremental]"); + eprintln!("[incremental] DepGraph Statistics"); + eprintln!("{}", SEPARATOR); + eprintln!("[incremental]"); + eprintln!("[incremental] Total Node Count: {}", record_stats.total_node_count); + eprintln!("[incremental] Total Edge Count: {}", record_stats.total_edge_count); + + if cfg!(debug_assertions) { + eprintln!("[incremental] Total Edge Reads: {}", total_read_count); + eprintln!( + "[incremental] Total Duplicate Edge Reads: {}", + total_duplicate_read_count + ); + } + + eprintln!("[incremental]"); + eprintln!( + "[incremental] {:<36}| {:<17}| {:<12}| {:<17}|", + "Node Kind", "Node Frequency", "Node Count", "Avg. Edge Count" + ); + eprintln!("{}", SEPARATOR); + + for stat in stats { + let node_kind_ratio = + (100.0 * (stat.node_counter as f64)) / (record_stats.total_node_count as f64); + let node_kind_avg_edges = (stat.edge_counter as f64) / (stat.node_counter as f64); + + eprintln!( + "[incremental] {:<36}|{:>16.1}% |{:>12} |{:>17.1} |", + format!("{:?}", stat.kind), + node_kind_ratio, + stat.node_counter, + node_kind_avg_edges, + ); + } + + eprintln!("{}", SEPARATOR); + eprintln!("[incremental]"); + } + } +} + +#[cfg(not(parallel_compiler))] +impl> GraphEncoder { + pub(crate) fn send( + &self, + node: DepNode, + fingerprint: Fingerprint, + edges: SmallVec<[DepNodeIndex; 8]>, + ) -> DepNodeIndex { + let index = self.counter.fetch_add(1, Ordering::SeqCst); + let index = DepNodeIndex::from_u32(index); + let &mut (ref mut encoder, ref mut edge_count, ref mut result) = &mut *self.status.lock(); + *edge_count += edges.len(); + *result = std::mem::replace(result, Ok(())).and_then(|()| { + let node = NodeInfo { node, fingerprint, edges }; + encode_node(encoder, index, &node, &self.record_graph, &self.record_stats) + }); + index + } + + pub fn finish(self) -> FileEncodeResult { + let (encoder, edge_count, result) = self.status.into_inner(); + let () = result?; + let node_count = self.counter.into_inner() as usize; + + encode_counts(encoder, node_count, edge_count) + } +} + +#[cfg(parallel_compiler)] +impl> GraphEncoder { + pub(crate) fn send( + &self, + node: DepNode, + fingerprint: Fingerprint, + edges: SmallVec<[DepNodeIndex; 8]>, + ) -> DepNodeIndex { + let node = NodeInfo { node, fingerprint, edges }; + let index = self.counter.fetch_add(1, Ordering::SeqCst); + let index = DepNodeIndex::from_u32(index); + self.send.send((index, node)).unwrap(); + index + } + + pub fn finish(self) -> FileEncodeResult { + std::mem::drop(self.send); + self.thread.join().unwrap() + } +} + +#[cfg(parallel_compiler)] +#[instrument(skip(encoder, recv, process))] +fn encode_graph>( + mut encoder: FileEncoder, + recv: mpsc::Receiver<(DepNodeIndex, NodeInfo)>, + process: impl Fn(&mut FileEncoder, DepNodeIndex, &NodeInfo) -> FileEncodeResult, +) -> FileEncodeResult { + let mut edge_count: usize = 0; + let node_count: usize = ordered_recv(recv, |index, node| { + edge_count += node.edges.len(); + process(&mut encoder, index, node) + })?; + + encode_counts(encoder, node_count, edge_count) +} + +/// Since there are multiple producers assigning the DepNodeIndex using an atomic, +/// the messages may not arrive in order. This function sorts them as they come. +#[cfg(parallel_compiler)] +fn ordered_recv>( + recv: mpsc::Receiver<(DepNodeIndex, NodeInfo)>, + mut f: impl FnMut(DepNodeIndex, &NodeInfo) -> FileEncodeResult, +) -> Result { + let mut pending = Vec::<(DepNodeIndex, _)>::new(); + let mut expected = DepNodeIndex::new(0); + + // INVARIANT: No message can arrive with an index less than `expected`. + 'outer: loop { + pending.sort_by_key(|n| n.0); + for (index, node) in pending.drain_filter(|(index, _)| { + if *index == expected { + expected.increment_by(1); + true + } else { + false + } + }) { + f(index, &node)?; + } + + while let Ok((index, node)) = recv.recv() { + if index > expected { + pending.push((index, node)); + } else if index == expected { + f(index, &node)?; + expected.increment_by(1); + continue 'outer; + } else { + panic!("Unexpected index {:?} while waiting for {:?}", index, expected); + } + } + + break; + } + + Ok(expected.as_u32() as usize) +} diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index 3db57c0ab3a..071144f38e7 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -2,6 +2,7 @@ #![feature(const_fn)] #![feature(const_panic)] #![feature(core_intrinsics)] +#![feature(drain_filter)] #![feature(hash_raw_entry)] #![feature(iter_zip)] #![feature(min_specialization)] diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 77267489a75..b5880247475 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -537,7 +537,7 @@ where // If `-Zincremental-verify-ich` is specified, re-hash results from // the cache and make sure that they have the expected fingerprint. if unlikely!(tcx.dep_context().sess().opts.debugging_opts.incremental_verify_ich) { - incremental_verify_ich(*tcx.dep_context(), &result, dep_node, dep_node_index, query); + incremental_verify_ich(*tcx.dep_context(), &result, dep_node, query); } result @@ -560,7 +560,7 @@ where // // See issue #82920 for an example of a miscompilation that would get turned into // an ICE by this check - incremental_verify_ich(*tcx.dep_context(), &result, dep_node, dep_node_index, query); + incremental_verify_ich(*tcx.dep_context(), &result, dep_node, query); result } @@ -570,14 +570,12 @@ fn incremental_verify_ich( tcx: CTX::DepContext, result: &V, dep_node: &DepNode, - dep_node_index: DepNodeIndex, query: &QueryVtable, ) where CTX: QueryContext, { assert!( - Some(tcx.dep_graph().fingerprint_of(dep_node_index)) - == tcx.dep_graph().prev_fingerprint_of(dep_node), + tcx.dep_graph().is_green(dep_node), "fingerprint for green query instance not loaded from cache: {:?}", dep_node, ); @@ -588,9 +586,15 @@ fn incremental_verify_ich( let new_hash = query.hash_result(&mut hcx, result).unwrap_or(Fingerprint::ZERO); debug!("END verify_ich({:?})", dep_node); - let old_hash = tcx.dep_graph().fingerprint_of(dep_node_index); + let old_hash = tcx.dep_graph().prev_fingerprint_of(dep_node); - assert!(new_hash == old_hash, "found unstable fingerprints for {:?}: {:?}", dep_node, result); + assert_eq!( + Some(new_hash), + old_hash, + "found unstable fingerprints for {:?}: {:?}", + dep_node, + result + ); } fn force_query_with_job( From 39b306a53db513c754d5e8d60fc2691829209131 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 6 Mar 2021 11:17:56 +0100 Subject: [PATCH 213/370] Do not allocate in decoder. --- .../src/dep_graph/serialized.rs | 54 +++++++++++-------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index a76100cc228..3067da9436d 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -5,9 +5,9 @@ use super::{DepKind, DepNode, DepNodeIndex}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{AtomicU32, Lock, Lrc, Ordering}; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::IndexVec; use rustc_serialize::opaque::{self, FileEncodeResult, FileEncoder, IntEncodedWithFixedSize}; -use rustc_serialize::{Decodable, Encodable}; +use rustc_serialize::{Decodable, Decoder, Encodable}; use smallvec::SmallVec; use std::convert::TryInto; @@ -85,20 +85,30 @@ impl<'a, K: DepKind + Decodable>> Decodable::decode(d)?; - debug!(?_index, ?node); + d.read_struct("NodeInfo", 3, |d| { + let dep_node: DepNode = d.read_struct_field("node", 0, Decodable::decode)?; + let _i: SerializedDepNodeIndex = nodes.push(dep_node); + debug_assert_eq!(_i.index(), _index); - let _i: SerializedDepNodeIndex = nodes.push(node.node); - debug_assert_eq!(_i.index(), _index); - let _i: SerializedDepNodeIndex = fingerprints.push(node.fingerprint); - debug_assert_eq!(_i.index(), _index); + let fingerprint: Fingerprint = + d.read_struct_field("fingerprint", 1, Decodable::decode)?; + let _i: SerializedDepNodeIndex = fingerprints.push(fingerprint); + debug_assert_eq!(_i.index(), _index); - let start = edge_list_data.len().try_into().unwrap(); - edge_list_data.extend(node.edges.into_iter()); - let end = edge_list_data.len().try_into().unwrap(); - - let _i: SerializedDepNodeIndex = edge_list_indices.push((start, end)); - debug_assert_eq!(_i.index(), _index); + d.read_struct_field("edges", 2, |d| { + d.read_seq(|d, len| { + let start = edge_list_data.len().try_into().unwrap(); + for e in 0..len { + let edge = d.read_seq_elt(e, Decodable::decode)?; + edge_list_data.push(edge); + } + let end = edge_list_data.len().try_into().unwrap(); + let _i: SerializedDepNodeIndex = edge_list_indices.push((start, end)); + debug_assert_eq!(_i.index(), _index); + Ok(()) + }) + }) + })?; } Ok(SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data }) @@ -106,10 +116,10 @@ impl<'a, K: DepKind + Decodable>> Decodable { +pub struct NodeInfo { node: DepNode, fingerprint: Fingerprint, - edges: SmallVec<[I; 8]>, + edges: SmallVec<[DepNodeIndex; 8]>, } struct Stat { @@ -128,7 +138,7 @@ struct Stats { fn encode_node( encoder: &mut FileEncoder, _index: DepNodeIndex, - node: &NodeInfo, + node: &NodeInfo, _record_graph: &Option>>>, record_stats: &Option>>>, ) -> FileEncodeResult { @@ -181,7 +191,7 @@ pub struct GraphEncoder { #[cfg(parallel_compiler)] pub struct GraphEncoder { - send: WorkerLocal)>>, + send: WorkerLocal)>>, thread: thread::JoinHandle, counter: AtomicU32, record_graph: Option>>>, @@ -350,8 +360,8 @@ impl> GraphEncoder { #[instrument(skip(encoder, recv, process))] fn encode_graph>( mut encoder: FileEncoder, - recv: mpsc::Receiver<(DepNodeIndex, NodeInfo)>, - process: impl Fn(&mut FileEncoder, DepNodeIndex, &NodeInfo) -> FileEncodeResult, + recv: mpsc::Receiver<(DepNodeIndex, NodeInfo)>, + process: impl Fn(&mut FileEncoder, DepNodeIndex, &NodeInfo) -> FileEncodeResult, ) -> FileEncodeResult { let mut edge_count: usize = 0; let node_count: usize = ordered_recv(recv, |index, node| { @@ -366,8 +376,8 @@ fn encode_graph>( /// the messages may not arrive in order. This function sorts them as they come. #[cfg(parallel_compiler)] fn ordered_recv>( - recv: mpsc::Receiver<(DepNodeIndex, NodeInfo)>, - mut f: impl FnMut(DepNodeIndex, &NodeInfo) -> FileEncodeResult, + recv: mpsc::Receiver<(DepNodeIndex, NodeInfo)>, + mut f: impl FnMut(DepNodeIndex, &NodeInfo) -> FileEncodeResult, ) -> Result { let mut pending = Vec::<(DepNodeIndex, _)>::new(); let mut expected = DepNodeIndex::new(0); From cfe786e5e00316fb70b48fc6e324b72acf069df4 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 6 Mar 2021 13:55:20 +0100 Subject: [PATCH 214/370] Fix tests. Avoid invoking queries inside `check_paths`, since we are holding a lock to the reconstructed graph. --- .../rustc_query_system/src/dep_graph/query.rs | 17 +++++++++++++---- .../src/dep_graph/serialized.rs | 9 ++++++++- src/test/ui/async-await/issues/issue-64964.rs | 2 +- .../dep-graph/dep-graph-assoc-type-codegen.rs | 2 +- .../ui/dep-graph/dep-graph-caller-callee.rs | 2 +- .../ui/dep-graph/dep-graph-struct-signature.rs | 2 +- ...p-graph-trait-impl-two-traits-same-method.rs | 2 +- .../dep-graph-trait-impl-two-traits.rs | 2 +- src/test/ui/dep-graph/dep-graph-trait-impl.rs | 2 +- src/test/ui/dep-graph/dep-graph-type-alias.rs | 2 +- .../ui/dep-graph/dep-graph-variance-alias.rs | 2 +- 11 files changed, 30 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/query.rs b/compiler/rustc_query_system/src/dep_graph/query.rs index 9c85cdd59d9..0fe3748e386 100644 --- a/compiler/rustc_query_system/src/dep_graph/query.rs +++ b/compiler/rustc_query_system/src/dep_graph/query.rs @@ -1,11 +1,13 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::implementation::{Direction, Graph, NodeIndex, INCOMING}; +use rustc_index::vec::IndexVec; use super::{DepKind, DepNode, DepNodeIndex}; pub struct DepGraphQuery { pub graph: Graph, ()>, pub indices: FxHashMap, NodeIndex>, + pub dep_index_to_index: IndexVec>, } impl DepGraphQuery { @@ -15,18 +17,25 @@ impl DepGraphQuery { let graph = Graph::with_capacity(node_count, edge_count); let indices = FxHashMap::default(); + let dep_index_to_index = IndexVec::new(); - DepGraphQuery { graph, indices } + DepGraphQuery { graph, indices, dep_index_to_index } } pub fn push(&mut self, index: DepNodeIndex, node: DepNode, edges: &[DepNodeIndex]) { let source = self.graph.add_node(node); - debug_assert_eq!(index.index(), source.0); + if index.index() >= self.dep_index_to_index.len() { + self.dep_index_to_index.resize(index.index() + 1, None); + } + self.dep_index_to_index[index] = Some(source); self.indices.insert(node, source); for &target in edges.iter() { - let target = NodeIndex(target.index()); - self.graph.add_edge(source, target, ()); + let target = self.dep_index_to_index[target]; + // Skip missing edges. + if let Some(target) = target { + self.graph.add_edge(source, target, ()); + } } } diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 3067da9436d..6a3cc215a0b 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -144,7 +144,14 @@ fn encode_node( ) -> FileEncodeResult { #[cfg(debug_assertions)] if let Some(record_graph) = &_record_graph { - record_graph.lock().push(_index, node.node, &node.edges); + if let Some(record_graph) = &mut if cfg!(parallel_compiler) { + Some(record_graph.lock()) + } else { + // Do not ICE when a query is called from within `with_query`. + record_graph.try_lock() + } { + record_graph.push(_index, node.node, &node.edges); + } } if let Some(record_stats) = &record_stats { diff --git a/src/test/ui/async-await/issues/issue-64964.rs b/src/test/ui/async-await/issues/issue-64964.rs index 11f6cb6af9c..5313d1715c4 100644 --- a/src/test/ui/async-await/issues/issue-64964.rs +++ b/src/test/ui/async-await/issues/issue-64964.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Z query-dep-graph +// compile-flags: -Z query-dep-graph -C incremental=tmp/issue-64964 // edition:2018 // Regression test for ICE related to `await`ing in a method + incr. comp. (#64964) diff --git a/src/test/ui/dep-graph/dep-graph-assoc-type-codegen.rs b/src/test/ui/dep-graph/dep-graph-assoc-type-codegen.rs index 0d11d933af0..a0ee3ad31e6 100644 --- a/src/test/ui/dep-graph/dep-graph-assoc-type-codegen.rs +++ b/src/test/ui/dep-graph/dep-graph-assoc-type-codegen.rs @@ -1,7 +1,7 @@ // Test that when a trait impl changes, fns whose body uses that trait // must also be recompiled. -// compile-flags: -Z query-dep-graph +// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-assoc-type-codegen #![feature(rustc_attrs)] #![allow(warnings)] diff --git a/src/test/ui/dep-graph/dep-graph-caller-callee.rs b/src/test/ui/dep-graph/dep-graph-caller-callee.rs index b12c635d2e7..c95ea53650b 100644 --- a/src/test/ui/dep-graph/dep-graph-caller-callee.rs +++ b/src/test/ui/dep-graph/dep-graph-caller-callee.rs @@ -1,7 +1,7 @@ // Test that immediate callers have to change when callee changes, but // not callers' callers. -// compile-flags: -Z query-dep-graph +// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-caller-callee #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/dep-graph/dep-graph-struct-signature.rs b/src/test/ui/dep-graph/dep-graph-struct-signature.rs index 7ef6fac48c3..50a670b8772 100644 --- a/src/test/ui/dep-graph/dep-graph-struct-signature.rs +++ b/src/test/ui/dep-graph/dep-graph-struct-signature.rs @@ -1,7 +1,7 @@ // Test cases where a changing struct appears in the signature of fns // and methods. -// compile-flags: -Z query-dep-graph +// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-struct-signature #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs b/src/test/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs index 1b3bf5a3933..c0a6617316b 100644 --- a/src/test/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs +++ b/src/test/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs @@ -1,7 +1,7 @@ // Test that adding an impl to a trait `Foo` DOES affect functions // that only use `Bar` if they have methods in common. -// compile-flags: -Z query-dep-graph +// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-trait-impl-two-traits-same-method #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/dep-graph/dep-graph-trait-impl-two-traits.rs b/src/test/ui/dep-graph/dep-graph-trait-impl-two-traits.rs index ebfe8ccc3df..56e9762ddb2 100644 --- a/src/test/ui/dep-graph/dep-graph-trait-impl-two-traits.rs +++ b/src/test/ui/dep-graph/dep-graph-trait-impl-two-traits.rs @@ -1,7 +1,7 @@ // Test that adding an impl to a trait `Foo` does not affect functions // that only use `Bar`, so long as they do not have methods in common. -// compile-flags: -Z query-dep-graph +// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-trait-impl-two-traits #![feature(rustc_attrs)] #![allow(warnings)] diff --git a/src/test/ui/dep-graph/dep-graph-trait-impl.rs b/src/test/ui/dep-graph/dep-graph-trait-impl.rs index 9dd201e2a1f..3bbe3e745ca 100644 --- a/src/test/ui/dep-graph/dep-graph-trait-impl.rs +++ b/src/test/ui/dep-graph/dep-graph-trait-impl.rs @@ -1,7 +1,7 @@ // Test that when a trait impl changes, fns whose body uses that trait // must also be recompiled. -// compile-flags: -Z query-dep-graph +// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-trait-impl #![feature(rustc_attrs)] #![allow(warnings)] diff --git a/src/test/ui/dep-graph/dep-graph-type-alias.rs b/src/test/ui/dep-graph/dep-graph-type-alias.rs index c9151ce79c5..5c5e24693a4 100644 --- a/src/test/ui/dep-graph/dep-graph-type-alias.rs +++ b/src/test/ui/dep-graph/dep-graph-type-alias.rs @@ -1,6 +1,6 @@ // Test that changing what a `type` points to does not go unnoticed. -// compile-flags: -Z query-dep-graph +// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-type-alias #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/dep-graph/dep-graph-variance-alias.rs b/src/test/ui/dep-graph/dep-graph-variance-alias.rs index 927ea559778..6cc1f44104a 100644 --- a/src/test/ui/dep-graph/dep-graph-variance-alias.rs +++ b/src/test/ui/dep-graph/dep-graph-variance-alias.rs @@ -1,7 +1,7 @@ // Test that changing what a `type` points to does not go unnoticed // by the variance analysis. -// compile-flags: -Z query-dep-graph +// compile-flags: -Z query-dep-graph -C incremental=tmp/dep-graph-variance-alias #![feature(rustc_attrs)] #![allow(dead_code)] From 8208872fa28550068e9e30075af09da1a8144fb4 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 6 Mar 2021 15:58:32 +0100 Subject: [PATCH 215/370] Fix parallel compiler. --- compiler/rustc_query_system/src/dep_graph/serialized.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 6a3cc215a0b..7b6ee721eba 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -12,7 +12,9 @@ use smallvec::SmallVec; use std::convert::TryInto; #[cfg(parallel_compiler)] -use {rustc_data_structures::sync::WorkerLocal, std::sync::mpsc, std::thread}; +use { + rustc_data_structures::sync::WorkerLocal, rustc_index::vec::Idx, std::sync::mpsc, std::thread, +}; // The maximum value of `SerializedDepNodeIndex` leaves the upper two bits // unused so that we can store multiple index types in `CompressedHybridIndex`, From e1c99e5fccdd97e7b78e364c3e408f535994e23c Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 16 Mar 2021 19:32:00 +0100 Subject: [PATCH 216/370] Remove the parallel version. --- .../src/dep_graph/serialized.rs | 148 ++---------------- 1 file changed, 13 insertions(+), 135 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 7b6ee721eba..6cb728bf0a8 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -4,18 +4,13 @@ use super::query::DepGraphQuery; use super::{DepKind, DepNode, DepNodeIndex}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::{AtomicU32, Lock, Lrc, Ordering}; -use rustc_index::vec::IndexVec; +use rustc_data_structures::sync::{Lock, Lrc}; +use rustc_index::vec::{Idx, IndexVec}; use rustc_serialize::opaque::{self, FileEncodeResult, FileEncoder, IntEncodedWithFixedSize}; use rustc_serialize::{Decodable, Decoder, Encodable}; use smallvec::SmallVec; use std::convert::TryInto; -#[cfg(parallel_compiler)] -use { - rustc_data_structures::sync::WorkerLocal, rustc_index::vec::Idx, std::sync::mpsc, std::thread, -}; - // The maximum value of `SerializedDepNodeIndex` leaves the upper two bits // unused so that we can store multiple index types in `CompressedHybridIndex`, // and use those bits to encode which index type it contains. @@ -146,12 +141,8 @@ fn encode_node( ) -> FileEncodeResult { #[cfg(debug_assertions)] if let Some(record_graph) = &_record_graph { - if let Some(record_graph) = &mut if cfg!(parallel_compiler) { - Some(record_graph.lock()) - } else { - // Do not ICE when a query is called from within `with_query`. - record_graph.try_lock() - } { + // Do not ICE when a query is called from within `with_query`. + if let Some(record_graph) = &mut record_graph.try_lock() { record_graph.push(_index, node.node, &node.edges); } } @@ -190,19 +181,8 @@ fn encode_counts( encoder.flush() } -#[cfg(not(parallel_compiler))] pub struct GraphEncoder { - status: Lock<(FileEncoder, usize, FileEncodeResult)>, - counter: AtomicU32, - record_graph: Option>>>, - record_stats: Option>>>, -} - -#[cfg(parallel_compiler)] -pub struct GraphEncoder { - send: WorkerLocal)>>, - thread: thread::JoinHandle, - counter: AtomicU32, + status: Lock<(FileEncoder, DepNodeIndex, usize, FileEncodeResult)>, record_graph: Option>>>, record_stats: Option>>>, } @@ -228,29 +208,8 @@ impl> GraphEncoder { } else { None }; - let counter = AtomicU32::new(0); - - #[cfg(not(parallel_compiler))] - { - let status = Lock::new((encoder, 0, Ok(()))); - GraphEncoder { status, counter, record_graph, record_stats } - } - #[cfg(parallel_compiler)] - { - let (send, recv) = mpsc::channel(); - let thread = { - let record_graph = record_graph.clone(); - let record_stats = record_stats.clone(); - thread::spawn(move || { - encode_graph(encoder, recv, |encoder, index, node| { - encode_node(encoder, index, node, &record_graph, &record_stats) - }) - }) - }; - let send = WorkerLocal::new(move |_| send.clone()); - - GraphEncoder { send, thread, counter, record_graph, record_stats } - } + let status = Lock::new((encoder, DepNodeIndex::new(0), 0, Ok(()))); + GraphEncoder { status, record_graph, record_stats } } pub(crate) fn with_query(&self, f: impl Fn(&DepGraphQuery)) { @@ -314,19 +273,17 @@ impl> GraphEncoder { eprintln!("[incremental]"); } } -} -#[cfg(not(parallel_compiler))] -impl> GraphEncoder { pub(crate) fn send( &self, node: DepNode, fingerprint: Fingerprint, edges: SmallVec<[DepNodeIndex; 8]>, ) -> DepNodeIndex { - let index = self.counter.fetch_add(1, Ordering::SeqCst); - let index = DepNodeIndex::from_u32(index); - let &mut (ref mut encoder, ref mut edge_count, ref mut result) = &mut *self.status.lock(); + let &mut (ref mut encoder, ref mut next_index, ref mut edge_count, ref mut result) = + &mut *self.status.lock(); + let index = next_index.clone(); + next_index.increment_by(1); *edge_count += edges.len(); *result = std::mem::replace(result, Ok(())).and_then(|()| { let node = NodeInfo { node, fingerprint, edges }; @@ -336,89 +293,10 @@ impl> GraphEncoder { } pub fn finish(self) -> FileEncodeResult { - let (encoder, edge_count, result) = self.status.into_inner(); + let (encoder, node_count, edge_count, result) = self.status.into_inner(); let () = result?; - let node_count = self.counter.into_inner() as usize; + let node_count = node_count.index(); encode_counts(encoder, node_count, edge_count) } } - -#[cfg(parallel_compiler)] -impl> GraphEncoder { - pub(crate) fn send( - &self, - node: DepNode, - fingerprint: Fingerprint, - edges: SmallVec<[DepNodeIndex; 8]>, - ) -> DepNodeIndex { - let node = NodeInfo { node, fingerprint, edges }; - let index = self.counter.fetch_add(1, Ordering::SeqCst); - let index = DepNodeIndex::from_u32(index); - self.send.send((index, node)).unwrap(); - index - } - - pub fn finish(self) -> FileEncodeResult { - std::mem::drop(self.send); - self.thread.join().unwrap() - } -} - -#[cfg(parallel_compiler)] -#[instrument(skip(encoder, recv, process))] -fn encode_graph>( - mut encoder: FileEncoder, - recv: mpsc::Receiver<(DepNodeIndex, NodeInfo)>, - process: impl Fn(&mut FileEncoder, DepNodeIndex, &NodeInfo) -> FileEncodeResult, -) -> FileEncodeResult { - let mut edge_count: usize = 0; - let node_count: usize = ordered_recv(recv, |index, node| { - edge_count += node.edges.len(); - process(&mut encoder, index, node) - })?; - - encode_counts(encoder, node_count, edge_count) -} - -/// Since there are multiple producers assigning the DepNodeIndex using an atomic, -/// the messages may not arrive in order. This function sorts them as they come. -#[cfg(parallel_compiler)] -fn ordered_recv>( - recv: mpsc::Receiver<(DepNodeIndex, NodeInfo)>, - mut f: impl FnMut(DepNodeIndex, &NodeInfo) -> FileEncodeResult, -) -> Result { - let mut pending = Vec::<(DepNodeIndex, _)>::new(); - let mut expected = DepNodeIndex::new(0); - - // INVARIANT: No message can arrive with an index less than `expected`. - 'outer: loop { - pending.sort_by_key(|n| n.0); - for (index, node) in pending.drain_filter(|(index, _)| { - if *index == expected { - expected.increment_by(1); - true - } else { - false - } - }) { - f(index, &node)?; - } - - while let Ok((index, node)) = recv.recv() { - if index > expected { - pending.push((index, node)); - } else if index == expected { - f(index, &node)?; - expected.increment_by(1); - continue 'outer; - } else { - panic!("Unexpected index {:?} while waiting for {:?}", index, expected); - } - } - - break; - } - - Ok(expected.as_u32() as usize) -} From c5c935af9218c64f5960bd2af58a086e580b35e9 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 16 Mar 2021 20:52:28 +0100 Subject: [PATCH 217/370] Simplify tracking the encoder state. --- .../src/dep_graph/serialized.rs | 152 +++++++++--------- 1 file changed, 72 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 6cb728bf0a8..ab97222e19a 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -4,7 +4,7 @@ use super::query::DepGraphQuery; use super::{DepKind, DepNode, DepNodeIndex}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::{Lock, Lrc}; +use rustc_data_structures::sync::Lock; use rustc_index::vec::{Idx, IndexVec}; use rustc_serialize::opaque::{self, FileEncodeResult, FileEncoder, IntEncodedWithFixedSize}; use rustc_serialize::{Decodable, Decoder, Encodable}; @@ -125,66 +125,80 @@ struct Stat { edge_counter: u64, } -struct Stats { - stats: FxHashMap>, +struct EncodingStatus { + encoder: FileEncoder, total_node_count: usize, total_edge_count: usize, + result: FileEncodeResult, + stats: Option>>, } -#[instrument(skip(encoder, _record_graph, record_stats))] -fn encode_node( - encoder: &mut FileEncoder, - _index: DepNodeIndex, - node: &NodeInfo, - _record_graph: &Option>>>, - record_stats: &Option>>>, -) -> FileEncodeResult { - #[cfg(debug_assertions)] - if let Some(record_graph) = &_record_graph { - // Do not ICE when a query is called from within `with_query`. - if let Some(record_graph) = &mut record_graph.try_lock() { - record_graph.push(_index, node.node, &node.edges); +impl EncodingStatus { + fn new(encoder: FileEncoder, record_stats: bool) -> Self { + Self { + encoder, + total_edge_count: 0, + total_node_count: 0, + result: Ok(()), + stats: if record_stats { Some(FxHashMap::default()) } else { None }, } } - if let Some(record_stats) = &record_stats { - let mut stats = record_stats.lock(); - let kind = node.node.kind; - let edge_count = node.edges.len(); + #[instrument(skip(self, _record_graph))] + fn encode_node( + &mut self, + node: &NodeInfo, + _record_graph: &Option>>, + ) -> DepNodeIndex { + let index = DepNodeIndex::new(self.total_node_count); + self.total_node_count += 1; - let stat = - stats.stats.entry(kind).or_insert(Stat { kind, node_counter: 0, edge_counter: 0 }); - stat.node_counter += 1; - stat.edge_counter += edge_count as u64; - stats.total_node_count += 1; - stats.total_edge_count += edge_count; + let edge_count = node.edges.len(); + self.total_edge_count += edge_count; + + #[cfg(debug_assertions)] + if let Some(record_graph) = &_record_graph { + // Do not ICE when a query is called from within `with_query`. + if let Some(record_graph) = &mut record_graph.try_lock() { + record_graph.push(index, node.node, &node.edges); + } + } + + if let Some(stats) = &mut self.stats { + let kind = node.node.kind; + + let stat = stats.entry(kind).or_insert(Stat { kind, node_counter: 0, edge_counter: 0 }); + stat.node_counter += 1; + stat.edge_counter += edge_count as u64; + } + + debug!(?index, ?node); + let encoder = &mut self.encoder; + self.result = + std::mem::replace(&mut self.result, Ok(())).and_then(|()| node.encode(encoder)); + index } - debug!(?_index, ?node); - node.encode(encoder) -} + fn finish(self) -> FileEncodeResult { + let Self { mut encoder, total_node_count, total_edge_count, result, stats: _ } = self; + let () = result?; -fn encode_counts( - mut encoder: FileEncoder, - node_count: usize, - edge_count: usize, -) -> FileEncodeResult { - let node_count = node_count.try_into().unwrap(); - let edge_count = edge_count.try_into().unwrap(); + let node_count = total_node_count.try_into().unwrap(); + let edge_count = total_edge_count.try_into().unwrap(); - debug!(?node_count, ?edge_count); - debug!("position: {:?}", encoder.position()); - IntEncodedWithFixedSize(node_count).encode(&mut encoder)?; - IntEncodedWithFixedSize(edge_count).encode(&mut encoder)?; - debug!("position: {:?}", encoder.position()); - // Drop the encoder so that nothing is written after the counts. - encoder.flush() + debug!(?node_count, ?edge_count); + debug!("position: {:?}", encoder.position()); + IntEncodedWithFixedSize(node_count).encode(&mut encoder)?; + IntEncodedWithFixedSize(edge_count).encode(&mut encoder)?; + debug!("position: {:?}", encoder.position()); + // Drop the encoder so that nothing is written after the counts. + encoder.flush() + } } pub struct GraphEncoder { - status: Lock<(FileEncoder, DepNodeIndex, usize, FileEncodeResult)>, - record_graph: Option>>>, - record_stats: Option>>>, + status: Lock>, + record_graph: Option>>, } impl> GraphEncoder { @@ -195,21 +209,12 @@ impl> GraphEncoder { record_stats: bool, ) -> Self { let record_graph = if cfg!(debug_assertions) && record_graph { - Some(Lrc::new(Lock::new(DepGraphQuery::new(prev_node_count)))) + Some(Lock::new(DepGraphQuery::new(prev_node_count))) } else { None }; - let record_stats = if record_stats { - Some(Lrc::new(Lock::new(Stats { - stats: FxHashMap::default(), - total_node_count: 0, - total_edge_count: 0, - }))) - } else { - None - }; - let status = Lock::new((encoder, DepNodeIndex::new(0), 0, Ok(()))); - GraphEncoder { status, record_graph, record_stats } + let status = Lock::new(EncodingStatus::new(encoder, record_stats)); + GraphEncoder { status, record_graph } } pub(crate) fn with_query(&self, f: impl Fn(&DepGraphQuery)) { @@ -223,10 +228,9 @@ impl> GraphEncoder { total_read_count: u64, total_duplicate_read_count: u64, ) { - if let Some(record_stats) = &self.record_stats { - let record_stats = record_stats.lock(); - - let mut stats: Vec<_> = record_stats.stats.values().collect(); + let status = self.status.lock(); + if let Some(record_stats) = &status.stats { + let mut stats: Vec<_> = record_stats.values().collect(); stats.sort_by_key(|s| -(s.node_counter as i64)); const SEPARATOR: &str = "[incremental] --------------------------------\ @@ -237,8 +241,8 @@ impl> GraphEncoder { eprintln!("[incremental] DepGraph Statistics"); eprintln!("{}", SEPARATOR); eprintln!("[incremental]"); - eprintln!("[incremental] Total Node Count: {}", record_stats.total_node_count); - eprintln!("[incremental] Total Edge Count: {}", record_stats.total_edge_count); + eprintln!("[incremental] Total Node Count: {}", status.total_node_count); + eprintln!("[incremental] Total Edge Count: {}", status.total_edge_count); if cfg!(debug_assertions) { eprintln!("[incremental] Total Edge Reads: {}", total_read_count); @@ -257,7 +261,7 @@ impl> GraphEncoder { for stat in stats { let node_kind_ratio = - (100.0 * (stat.node_counter as f64)) / (record_stats.total_node_count as f64); + (100.0 * (stat.node_counter as f64)) / (status.total_node_count as f64); let node_kind_avg_edges = (stat.edge_counter as f64) / (stat.node_counter as f64); eprintln!( @@ -280,23 +284,11 @@ impl> GraphEncoder { fingerprint: Fingerprint, edges: SmallVec<[DepNodeIndex; 8]>, ) -> DepNodeIndex { - let &mut (ref mut encoder, ref mut next_index, ref mut edge_count, ref mut result) = - &mut *self.status.lock(); - let index = next_index.clone(); - next_index.increment_by(1); - *edge_count += edges.len(); - *result = std::mem::replace(result, Ok(())).and_then(|()| { - let node = NodeInfo { node, fingerprint, edges }; - encode_node(encoder, index, &node, &self.record_graph, &self.record_stats) - }); - index + let node = NodeInfo { node, fingerprint, edges }; + self.status.lock().encode_node(&node, &self.record_graph) } pub fn finish(self) -> FileEncodeResult { - let (encoder, node_count, edge_count, result) = self.status.into_inner(); - let () = result?; - let node_count = node_count.index(); - - encode_counts(encoder, node_count, edge_count) + self.status.into_inner().finish() } } From 65a8681a1701fa01e62a9fc9698e682df465f2ec Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 17 Mar 2021 19:23:17 +0100 Subject: [PATCH 218/370] Add documentation. --- .../rustc_query_system/src/dep_graph/serialized.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index ab97222e19a..663113543fc 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -1,4 +1,16 @@ //! The data that we will serialize and deserialize. +//! +//! The dep-graph is serialized as a sequence of NodeInfo, with the dependencies +//! specified inline. The total number of nodes and edges are stored as the last +//! 16 bytes of the file, so we can find them easily at decoding time. +//! +//! The serialisation is performed on-demand when each node is emitted. Using this +//! scheme, we do not need to keep the current graph in memory. +//! +//! The deserisalisation is performed manually, in order to convert from the stored +//! sequence of NodeInfos to the different arrays in SerializedDepGraph. Since the +//! node and edge count are stored at the end of the file, all the arrays can be +//! pre-allocated with the right length. use super::query::DepGraphQuery; use super::{DepKind, DepNode, DepNodeIndex}; From fe89f3236c08abd8fd2c81cdd2f41ff2066f13ac Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 18 Mar 2021 19:26:08 +0100 Subject: [PATCH 219/370] Address review. --- .../src/persist/dirty_clean.rs | 2 - .../rustc_incremental/src/persist/save.rs | 6 +- .../rustc_query_system/src/dep_graph/graph.rs | 72 +++++++++---------- .../rustc_query_system/src/dep_graph/query.rs | 3 +- .../src/dep_graph/serialized.rs | 17 ++--- 5 files changed, 45 insertions(+), 55 deletions(-) diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index 145c168f8c4..e7bd488af8e 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -391,8 +391,6 @@ impl DirtyCleanVisitor<'tcx> { fn assert_clean(&self, item_span: Span, dep_node: DepNode) { debug!("assert_clean({:?})", dep_node); - // if the node wasn't previously evaluated and now is (or vice versa), - // then the node isn't actually clean or dirty. if self.tcx.dep_graph.is_red(&dep_node) { let dep_node_str = self.dep_node_str(&dep_node); self.tcx diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index d80397970ac..23bd63a37d6 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -34,10 +34,8 @@ pub fn save_dep_graph(tcx: TyCtxt<'_>) { let dep_graph_path = dep_graph_path(sess); let staging_dep_graph_path = staging_dep_graph_path(sess); - join( - || sess.time("assert_dep_graph", || crate::assert_dep_graph(tcx)), - || sess.time("check_dirty_clean", || dirty_clean::check_dirty_clean_annotations(tcx)), - ); + sess.time("assert_dep_graph", || crate::assert_dep_graph(tcx)); + sess.time("check_dirty_clean", || dirty_clean::check_dirty_clean_annotations(tcx)); if sess.opts.debugging_opts.incremental_info { tcx.dep_graph.print_incremental_info() diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 295b2a97e4c..04def909131 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -626,11 +626,10 @@ impl DepGraph { // There may be multiple threads trying to mark the same dep node green concurrently - let dep_node_index = { - // We allocating an entry for the node in the current dependency graph and - // adding all the appropriate edges imported from the previous graph - data.current.intern_dark_green_node(&data.previous, prev_dep_node_index) - }; + // We allocating an entry for the node in the current dependency graph and + // adding all the appropriate edges imported from the previous graph + let dep_node_index = + data.current.promote_node_and_deps_to_current(&data.previous, prev_dep_node_index); // ... emitting any stored diagnostic ... @@ -713,7 +712,7 @@ impl DepGraph { } } - // Returns true if the given node has been marked as green during the + // Returns true if the given node has been marked as red during the // current compilation session. Used in various assertions pub fn is_red(&self, dep_node: &DepNode) -> bool { self.node_color(dep_node) == Some(DepNodeColor::Red) @@ -833,17 +832,11 @@ rustc_index::newtype_index! { /// will be populated as we run queries or tasks. We never remove nodes from the /// graph: they are only added. /// -/// The nodes in it are identified by a `DepNodeIndex`. Internally, this maps to -/// a `HybridIndex`, which identifies which collection in the `data` field -/// contains a node's data. Which collection is used for a node depends on -/// whether the node was present in the `PreviousDepGraph`, and if so, the color -/// of the node. Each type of node can share more or less data with the previous -/// graph. When possible, we can store just the index of the node in the -/// previous graph, rather than duplicating its data in our own collections. -/// This is important, because these graph structures are some of the largest in -/// the compiler. +/// The nodes in it are identified by a `DepNodeIndex`. We avoid keeping the nodes +/// in memory. This is important, because these graph structures are some of the +/// largest in the compiler. /// -/// For the same reason, we also avoid storing `DepNode`s more than once as map +/// For this reason, we avoid storing `DepNode`s more than once as map /// keys. The `new_node_to_index` map only contains nodes not in the previous /// graph, and we map nodes in the previous graph to indices via a two-step /// mapping. `PreviousDepGraph` maps from `DepNode` to `SerializedDepNodeIndex`, @@ -939,6 +932,15 @@ impl CurrentDepGraph { } } + #[cfg(debug_assertions)] + fn record_edge(&self, dep_node_index: DepNodeIndex, key: DepNode) { + if let Some(forbidden_edge) = &self.forbidden_edge { + forbidden_edge.index_to_node.lock().insert(dep_node_index, key); + } + } + + /// Writes the node to the current dep-graph and allocates a `DepNodeIndex` for it. + /// Assumes that this is a node that has no equivalent in the previous dep-graph. fn intern_new_node( &self, key: DepNode, @@ -951,9 +953,7 @@ impl CurrentDepGraph { let dep_node_index = self.encoder.borrow().send(key, current_fingerprint, edges); entry.insert(dep_node_index); #[cfg(debug_assertions)] - if let Some(forbidden_edge) = &self.forbidden_edge { - forbidden_edge.index_to_node.lock().insert(dep_node_index, key); - } + self.record_edge(dep_node_index, key); dep_node_index } } @@ -964,20 +964,20 @@ impl CurrentDepGraph { prev_graph: &PreviousDepGraph, key: DepNode, edges: EdgesVec, - current_fingerprint: Option, + fingerprint: Option, print_status: bool, ) -> (DepNodeIndex, Option<(SerializedDepNodeIndex, DepNodeColor)>) { let print_status = cfg!(debug_assertions) && print_status; if let Some(prev_index) = prev_graph.node_to_index_opt(&key) { // Determine the color and index of the new `DepNode`. - if let Some(current_fingerprint) = current_fingerprint { - if current_fingerprint == prev_graph.fingerprint_by_index(prev_index) { + if let Some(fingerprint) = fingerprint { + if fingerprint == prev_graph.fingerprint_by_index(prev_index) { if print_status { eprintln!("[task::green] {:?}", key); } - // This is a light green node: it existed in the previous compilation, + // This is a green node: it existed in the previous compilation, // its query was re-executed, and it has the same result as before. let mut prev_index_to_index = self.prev_index_to_index.lock(); @@ -985,16 +985,14 @@ impl CurrentDepGraph { Some(dep_node_index) => dep_node_index, None => { let dep_node_index = - self.encoder.borrow().send(key, current_fingerprint, edges); + self.encoder.borrow().send(key, fingerprint, edges); prev_index_to_index[prev_index] = Some(dep_node_index); dep_node_index } }; #[cfg(debug_assertions)] - if let Some(forbidden_edge) = &self.forbidden_edge { - forbidden_edge.index_to_node.lock().insert(dep_node_index, key); - } + self.record_edge(dep_node_index, key); (dep_node_index, Some((prev_index, DepNodeColor::Green(dep_node_index)))) } else { if print_status { @@ -1009,16 +1007,14 @@ impl CurrentDepGraph { Some(dep_node_index) => dep_node_index, None => { let dep_node_index = - self.encoder.borrow().send(key, current_fingerprint, edges); + self.encoder.borrow().send(key, fingerprint, edges); prev_index_to_index[prev_index] = Some(dep_node_index); dep_node_index } }; #[cfg(debug_assertions)] - if let Some(forbidden_edge) = &self.forbidden_edge { - forbidden_edge.index_to_node.lock().insert(dep_node_index, key); - } + self.record_edge(dep_node_index, key); (dep_node_index, Some((prev_index, DepNodeColor::Red))) } } else { @@ -1043,9 +1039,7 @@ impl CurrentDepGraph { }; #[cfg(debug_assertions)] - if let Some(forbidden_edge) = &self.forbidden_edge { - forbidden_edge.index_to_node.lock().insert(dep_node_index, key); - } + self.record_edge(dep_node_index, key); (dep_node_index, Some((prev_index, DepNodeColor::Red))) } } else { @@ -1053,16 +1047,16 @@ impl CurrentDepGraph { eprintln!("[task::new] {:?}", key); } - let current_fingerprint = current_fingerprint.unwrap_or(Fingerprint::ZERO); + let fingerprint = fingerprint.unwrap_or(Fingerprint::ZERO); // This is a new node: it didn't exist in the previous compilation session. - let dep_node_index = self.intern_new_node(key, edges, current_fingerprint); + let dep_node_index = self.intern_new_node(key, edges, fingerprint); (dep_node_index, None) } } - fn intern_dark_green_node( + fn promote_node_and_deps_to_current( &self, prev_graph: &PreviousDepGraph, prev_index: SerializedDepNodeIndex, @@ -1086,9 +1080,7 @@ impl CurrentDepGraph { ); prev_index_to_index[prev_index] = Some(dep_node_index); #[cfg(debug_assertions)] - if let Some(forbidden_edge) = &self.forbidden_edge { - forbidden_edge.index_to_node.lock().insert(dep_node_index, key); - } + self.record_edge(dep_node_index, key); dep_node_index } } diff --git a/compiler/rustc_query_system/src/dep_graph/query.rs b/compiler/rustc_query_system/src/dep_graph/query.rs index 0fe3748e386..27b3b5e1366 100644 --- a/compiler/rustc_query_system/src/dep_graph/query.rs +++ b/compiler/rustc_query_system/src/dep_graph/query.rs @@ -32,7 +32,8 @@ impl DepGraphQuery { for &target in edges.iter() { let target = self.dep_index_to_index[target]; - // Skip missing edges. + // We may miss the edges that are pushed while the `DepGraphQuery` is being accessed. + // Skip them to issues. if let Some(target) = target { self.graph.add_edge(source, target, ()); } diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 663113543fc..aeb0e2b0da1 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -73,7 +73,7 @@ impl<'a, K: DepKind + Decodable>> Decodable) -> Result, String> { - let position = d.position(); + let start_position = d.position(); // The last 16 bytes are the node count and edge count. debug!("position: {:?}", d.position()); @@ -85,7 +85,7 @@ impl<'a, K: DepKind + Decodable>> Decodable { edge_counter: u64, } -struct EncodingStatus { +struct EncoderState { encoder: FileEncoder, total_node_count: usize, total_edge_count: usize, @@ -145,7 +145,7 @@ struct EncodingStatus { stats: Option>>, } -impl EncodingStatus { +impl EncoderState { fn new(encoder: FileEncoder, record_stats: bool) -> Self { Self { encoder, @@ -186,8 +186,9 @@ impl EncodingStatus { debug!(?index, ?node); let encoder = &mut self.encoder; - self.result = - std::mem::replace(&mut self.result, Ok(())).and_then(|()| node.encode(encoder)); + if self.result.is_ok() { + self.result = node.encode(encoder); + } index } @@ -209,7 +210,7 @@ impl EncodingStatus { } pub struct GraphEncoder { - status: Lock>, + status: Lock>, record_graph: Option>>, } @@ -225,7 +226,7 @@ impl> GraphEncoder { } else { None }; - let status = Lock::new(EncodingStatus::new(encoder, record_stats)); + let status = Lock::new(EncoderState::new(encoder, record_stats)); GraphEncoder { status, record_graph } } From df24315ddf0103a5f9ecd8d3cd15e069e3571a53 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 18 Mar 2021 19:38:50 +0100 Subject: [PATCH 220/370] Adjust profiling. --- .../rustc_query_system/src/dep_graph/graph.rs | 39 ++++++++++++++----- .../src/dep_graph/serialized.rs | 3 ++ .../rustc_query_system/src/query/plumbing.rs | 8 ++-- .../src/traits/select/mod.rs | 2 +- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 04def909131..f92ee85f62e 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -1,6 +1,7 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::QueryInvocationId; +use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{self, Sharded}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; @@ -241,6 +242,7 @@ impl DepGraph { // Intern the new `DepNode`. let (dep_node_index, prev_and_color) = data.current.intern_node( + dcx.profiler(), &data.previous, key, edges, @@ -271,7 +273,12 @@ impl DepGraph { /// Executes something within an "anonymous" task, that is, a task the /// `DepNode` of which is determined by the list of inputs it read from. - pub fn with_anon_task(&self, dep_kind: K, op: OP) -> (R, DepNodeIndex) + pub fn with_anon_task, OP, R>( + &self, + cx: Ctxt, + dep_kind: K, + op: OP, + ) -> (R, DepNodeIndex) where OP: FnOnce() -> R, { @@ -298,8 +305,12 @@ impl DepGraph { hash: data.current.anon_id_seed.combine(hasher.finish()).into(), }; - let dep_node_index = - data.current.intern_new_node(target_dep_node, task_deps.reads, Fingerprint::ZERO); + let dep_node_index = data.current.intern_new_node( + cx.profiler(), + target_dep_node, + task_deps.reads, + Fingerprint::ZERO, + ); (result, dep_node_index) } else { @@ -628,8 +639,11 @@ impl DepGraph { // We allocating an entry for the node in the current dependency graph and // adding all the appropriate edges imported from the previous graph - let dep_node_index = - data.current.promote_node_and_deps_to_current(&data.previous, prev_dep_node_index); + let dep_node_index = data.current.promote_node_and_deps_to_current( + tcx.dep_context().profiler(), + &data.previous, + prev_dep_node_index, + ); // ... emitting any stored diagnostic ... @@ -943,6 +957,7 @@ impl CurrentDepGraph { /// Assumes that this is a node that has no equivalent in the previous dep-graph. fn intern_new_node( &self, + profiler: &SelfProfilerRef, key: DepNode, edges: EdgesVec, current_fingerprint: Fingerprint, @@ -950,7 +965,8 @@ impl CurrentDepGraph { match self.new_node_to_index.get_shard_by_value(&key).lock().entry(key) { Entry::Occupied(entry) => *entry.get(), Entry::Vacant(entry) => { - let dep_node_index = self.encoder.borrow().send(key, current_fingerprint, edges); + let dep_node_index = + self.encoder.borrow().send(profiler, key, current_fingerprint, edges); entry.insert(dep_node_index); #[cfg(debug_assertions)] self.record_edge(dep_node_index, key); @@ -961,6 +977,7 @@ impl CurrentDepGraph { fn intern_node( &self, + profiler: &SelfProfilerRef, prev_graph: &PreviousDepGraph, key: DepNode, edges: EdgesVec, @@ -985,7 +1002,7 @@ impl CurrentDepGraph { Some(dep_node_index) => dep_node_index, None => { let dep_node_index = - self.encoder.borrow().send(key, fingerprint, edges); + self.encoder.borrow().send(profiler, key, fingerprint, edges); prev_index_to_index[prev_index] = Some(dep_node_index); dep_node_index } @@ -1007,7 +1024,7 @@ impl CurrentDepGraph { Some(dep_node_index) => dep_node_index, None => { let dep_node_index = - self.encoder.borrow().send(key, fingerprint, edges); + self.encoder.borrow().send(profiler, key, fingerprint, edges); prev_index_to_index[prev_index] = Some(dep_node_index); dep_node_index } @@ -1032,7 +1049,7 @@ impl CurrentDepGraph { Some(dep_node_index) => dep_node_index, None => { let dep_node_index = - self.encoder.borrow().send(key, Fingerprint::ZERO, edges); + self.encoder.borrow().send(profiler, key, Fingerprint::ZERO, edges); prev_index_to_index[prev_index] = Some(dep_node_index); dep_node_index } @@ -1050,7 +1067,7 @@ impl CurrentDepGraph { let fingerprint = fingerprint.unwrap_or(Fingerprint::ZERO); // This is a new node: it didn't exist in the previous compilation session. - let dep_node_index = self.intern_new_node(key, edges, fingerprint); + let dep_node_index = self.intern_new_node(profiler, key, edges, fingerprint); (dep_node_index, None) } @@ -1058,6 +1075,7 @@ impl CurrentDepGraph { fn promote_node_and_deps_to_current( &self, + profiler: &SelfProfilerRef, prev_graph: &PreviousDepGraph, prev_index: SerializedDepNodeIndex, ) -> DepNodeIndex { @@ -1070,6 +1088,7 @@ impl CurrentDepGraph { None => { let key = prev_graph.index_to_node(prev_index); let dep_node_index = self.encoder.borrow().send( + profiler, key, prev_graph.fingerprint_by_index(prev_index), prev_graph diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index aeb0e2b0da1..27f7e5730a7 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -16,6 +16,7 @@ use super::query::DepGraphQuery; use super::{DepKind, DepNode, DepNodeIndex}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::Lock; use rustc_index::vec::{Idx, IndexVec}; use rustc_serialize::opaque::{self, FileEncodeResult, FileEncoder, IntEncodedWithFixedSize}; @@ -293,10 +294,12 @@ impl> GraphEncoder { pub(crate) fn send( &self, + profiler: &SelfProfilerRef, node: DepNode, fingerprint: Fingerprint, edges: SmallVec<[DepNodeIndex; 8]>, ) -> DepNodeIndex { + let _prof_timer = profiler.generic_activity("incr_comp_encode_dep_graph"); let node = NodeInfo { node, fingerprint, edges }; self.status.lock().encode_node(&node, &self.record_graph) } diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index b5880247475..fb8a53048fa 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -449,9 +449,11 @@ where let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| { tcx.start_query(job.id, diagnostics, || { - tcx.dep_context() - .dep_graph() - .with_anon_task(query.dep_kind, || query.compute(tcx, key)) + tcx.dep_context().dep_graph().with_anon_task( + *tcx.dep_context(), + query.dep_kind, + || query.compute(tcx, key), + ) }) }); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 45680c90cdc..0a15ca87d16 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -981,7 +981,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { OP: FnOnce(&mut Self) -> R, { let (result, dep_node) = - self.tcx().dep_graph.with_anon_task(DepKind::TraitSelect, || op(self)); + self.tcx().dep_graph.with_anon_task(self.tcx(), DepKind::TraitSelect, || op(self)); self.tcx().dep_graph.read_index(dep_node); (result, dep_node) } From 8ee9322c1041bcbaee408961727c4418bd792979 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 23 Mar 2021 13:19:42 +0100 Subject: [PATCH 221/370] Also profile finishing the encoding. --- compiler/rustc_incremental/src/persist/save.rs | 2 +- compiler/rustc_query_system/src/dep_graph/graph.rs | 8 ++++++-- compiler/rustc_query_system/src/dep_graph/serialized.rs | 3 ++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 23bd63a37d6..d558af3c1d5 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -49,7 +49,7 @@ pub fn save_dep_graph(tcx: TyCtxt<'_>) { }, move || { sess.time("incr_comp_persist_dep_graph", || { - if let Err(err) = tcx.dep_graph.encode() { + if let Err(err) = tcx.dep_graph.encode(&tcx.sess.prof) { sess.err(&format!( "failed to write dependency graph to `{}`: {}", staging_dep_graph_path.display(), diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index f92ee85f62e..7a0fc320663 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -789,8 +789,12 @@ impl DepGraph { } } - pub fn encode(&self) -> FileEncodeResult { - if let Some(data) = &self.data { data.current.encoder.steal().finish() } else { Ok(()) } + pub fn encode(&self, profiler: &SelfProfilerRef) -> FileEncodeResult { + if let Some(data) = &self.data { + data.current.encoder.steal().finish(profiler) + } else { + Ok(()) + } } fn next_virtual_depnode_index(&self) -> DepNodeIndex { diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 27f7e5730a7..1e34b14d906 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -304,7 +304,8 @@ impl> GraphEncoder { self.status.lock().encode_node(&node, &self.record_graph) } - pub fn finish(self) -> FileEncodeResult { + pub fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult { + let _prof_timer = profiler.generic_activity("incr_comp_encode_dep_graph"); self.status.into_inner().finish() } } From 6f06b761b991f5c4b714c6935781114dce44637a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 30 Mar 2021 12:28:33 -0400 Subject: [PATCH 222/370] Only look at blanket impls in `get_blanket_impls` --- compiler/rustc_middle/src/ty/trait_def.rs | 6 ++++++ src/librustdoc/clean/blanket_impl.rs | 8 +++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index ce17a724e25..33065bc3a7b 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -69,6 +69,12 @@ pub struct TraitImpls { non_blanket_impls: FxHashMap>, } +impl TraitImpls { + pub fn blanket_impls(&self) -> &[DefId] { + self.blanket_impls.as_slice() + } +} + impl<'tcx> TraitDef { pub fn new( def_id: DefId, diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 1bbaa60fe96..f7e08d10401 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -26,7 +26,9 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { { continue; } - self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { + // NOTE: doesn't use `for_each_relevant_impl` to avoid looking at anything besides blanket impls + let trait_impls = self.cx.tcx.trait_impls_of(trait_def_id); + for &impl_def_id in trait_impls.blanket_impls() { debug!( "get_blanket_impls: Considering impl for trait '{:?}' {:?}", trait_def_id, impl_def_id @@ -86,7 +88,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { may_apply, trait_ref, ty ); if !may_apply { - return; + continue; } self.cx.generated_synthetics.insert((ty, trait_def_id)); @@ -127,7 +129,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { blanket_impl: Some(trait_ref.self_ty().clean(self.cx)), }), }); - }); + } } impls } From 8331dbe6d023a168334a7a46f15731c6bc1baf1e Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 29 Mar 2021 11:18:52 +0200 Subject: [PATCH 223/370] Add an Mmap wrapper to rustc_data_structures This wrapper implements StableAddress and falls back to directly reading the file on wasm32 --- Cargo.lock | 3 +- compiler/rustc_codegen_cranelift/Cargo.lock | 10 ----- compiler/rustc_codegen_cranelift/Cargo.toml | 1 - .../rustc_codegen_cranelift/src/metadata.rs | 21 ++-------- compiler/rustc_codegen_ssa/Cargo.toml | 1 - compiler/rustc_codegen_ssa/src/back/lto.rs | 3 +- compiler/rustc_codegen_ssa/src/back/write.rs | 3 +- compiler/rustc_data_structures/Cargo.toml | 3 ++ compiler/rustc_data_structures/src/lib.rs | 1 + compiler/rustc_data_structures/src/memmap.rs | 40 +++++++++++++++++++ compiler/rustc_metadata/Cargo.toml | 1 - compiler/rustc_metadata/src/locator.rs | 19 ++------- 12 files changed, 56 insertions(+), 50 deletions(-) create mode 100644 compiler/rustc_data_structures/src/memmap.rs diff --git a/Cargo.lock b/Cargo.lock index 284a1ba5482..635b1557bee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3811,7 +3811,6 @@ dependencies = [ "itertools 0.9.0", "jobserver", "libc", - "memmap2", "pathdiff", "rustc_apfloat", "rustc_ast", @@ -3846,6 +3845,7 @@ dependencies = [ "jobserver", "libc", "measureme", + "memmap2", "parking_lot", "rustc-hash", "rustc-rayon", @@ -4145,7 +4145,6 @@ name = "rustc_metadata" version = "0.0.0" dependencies = [ "libc", - "memmap2", "rustc_ast", "rustc_attr", "rustc_data_structures", diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock index 3cb67032aaa..dc1cd336e15 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.lock +++ b/compiler/rustc_codegen_cranelift/Cargo.lock @@ -240,15 +240,6 @@ dependencies = [ "libc", ] -[[package]] -name = "memmap2" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e3e85b970d650e2ae6d70592474087051c11c54da7f7b4949725c5735fbcc6" -dependencies = [ - "libc", -] - [[package]] name = "object" version = "0.23.0" @@ -319,7 +310,6 @@ dependencies = [ "gimli", "indexmap", "libloading", - "memmap2", "object", "smallvec", "target-lexicon", diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml index 59542c414fa..60946ab2808 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.toml +++ b/compiler/rustc_codegen_cranelift/Cargo.toml @@ -22,7 +22,6 @@ ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg indexmap = "1.0.2" libloading = { version = "0.6.0", optional = true } smallvec = "1.6.1" -memmap2 = "0.2.1" # Uncomment to use local checkout of cranelift #[patch."https://github.com/bytecodealliance/wasmtime/"] diff --git a/compiler/rustc_codegen_cranelift/src/metadata.rs b/compiler/rustc_codegen_cranelift/src/metadata.rs index c5189c972cd..dbdc8cbad44 100644 --- a/compiler/rustc_codegen_cranelift/src/metadata.rs +++ b/compiler/rustc_codegen_cranelift/src/metadata.rs @@ -1,11 +1,11 @@ //! Reading and writing of the rustc metadata for rlibs and dylibs use std::fs::File; -use std::ops::Deref; use std::path::Path; use rustc_codegen_ssa::METADATA_FILENAME; -use rustc_data_structures::owning_ref::{OwningRef, StableAddress}; +use rustc_data_structures::memmap::Mmap; +use rustc_data_structures::owning_ref::OwningRef; use rustc_data_structures::rustc_erase_owner; use rustc_data_structures::sync::MetadataRef; use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader}; @@ -17,26 +17,13 @@ use crate::backend::WriteMetadata; pub(crate) struct CraneliftMetadataLoader; -struct StableMmap(memmap2::Mmap); - -impl Deref for StableMmap { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - &*self.0 - } -} - -unsafe impl StableAddress for StableMmap {} - fn load_metadata_with( path: &Path, f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>, ) -> Result { let file = File::open(path).map_err(|e| format!("{:?}", e))?; - let data = unsafe { memmap2::MmapOptions::new().map_copy_read_only(&file) } - .map_err(|e| format!("{:?}", e))?; - let metadata = OwningRef::new(StableMmap(data)).try_map(f)?; + let data = unsafe { Mmap::map(file) }.map_err(|e| format!("{:?}", e))?; + let metadata = OwningRef::new(data).try_map(f)?; return Ok(rustc_erase_owner!(metadata.map_owner_box())); } diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 15dbbbd49aa..7c1aaebb9ab 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -11,7 +11,6 @@ test = false bitflags = "1.2.1" cc = "1.0.1" itertools = "0.9" -memmap2 = "0.2.1" tracing = "0.1" libc = "0.2.50" jobserver = "0.1.11" diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs index c6aea22a63e..0ff05229466 100644 --- a/compiler/rustc_codegen_ssa/src/back/lto.rs +++ b/compiler/rustc_codegen_ssa/src/back/lto.rs @@ -2,6 +2,7 @@ use super::write::CodegenContext; use crate::traits::*; use crate::ModuleCodegen; +use rustc_data_structures::memmap::Mmap; use rustc_errors::FatalError; use std::ffi::CString; @@ -93,7 +94,7 @@ impl LtoModuleCodegen { pub enum SerializedModule { Local(M), FromRlib(Vec), - FromUncompressedFile(memmap2::Mmap), + FromUncompressedFile(Mmap), } impl SerializedModule { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 7a8d8fb1304..44a055a092c 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -10,6 +10,7 @@ use crate::{ use crate::traits::*; use jobserver::{Acquired, Client}; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::memmap::Mmap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::profiling::TimingGuard; use rustc_data_structures::profiling::VerboseTimingGuard; @@ -1958,7 +1959,7 @@ pub fn submit_pre_lto_module_to_llvm( .unwrap_or_else(|e| panic!("failed to open bitcode file `{}`: {}", bc_path.display(), e)); let mmap = unsafe { - memmap2::Mmap::map(&file).unwrap_or_else(|e| { + Mmap::map(file).unwrap_or_else(|e| { panic!("failed to mmap bitcode file `{}`: {}", bc_path.display(), e) }) }; diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 2e5a86b14c9..d32598e716e 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -36,3 +36,6 @@ features = ["nightly"] [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["fileapi", "psapi"] } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +memmap2 = "0.2.1" diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 123618a440d..adbb98fa750 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -84,6 +84,7 @@ pub mod snapshot_map; pub mod stable_map; pub mod svh; pub use ena::snapshot_vec; +pub mod memmap; pub mod sorted_map; pub mod stable_set; #[macro_use] diff --git a/compiler/rustc_data_structures/src/memmap.rs b/compiler/rustc_data_structures/src/memmap.rs new file mode 100644 index 00000000000..0c24f227cc9 --- /dev/null +++ b/compiler/rustc_data_structures/src/memmap.rs @@ -0,0 +1,40 @@ +use std::fs::File; +use std::io; +use std::ops::Deref; + +use crate::owning_ref::StableAddress; + +/// A trivial wrapper for [`memmap2::Mmap`] that implements [`StableAddress`]. +#[cfg(not(target_arch = "wasm32"))] +pub struct Mmap(memmap2::Mmap); + +#[cfg(target_arch = "wasm32")] +pub struct Mmap(Vec); + +#[cfg(not(target_arch = "wasm32"))] +impl Mmap { + pub unsafe fn map(file: File) -> io::Result { + memmap2::Mmap::map(&file).map(Mmap) + } +} + +#[cfg(target_arch = "wasm32")] +impl Mmap { + pub unsafe fn map(mut file: File) -> io::Result { + use std::io::Read; + + let mut data = Vec::new(); + file.read_to_end(&mut data)?; + Ok(Mmap(data)) + } +} + +impl Deref for Mmap { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + &*self.0 + } +} + +unsafe impl StableAddress for Mmap {} diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 48effed9274..29fa0b70069 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -11,7 +11,6 @@ doctest = false libc = "0.2" snap = "1" tracing = "0.1" -memmap2 = "0.2.1" smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } rustc_middle = { path = "../rustc_middle" } rustc_attr = { path = "../rustc_attr" } diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 39a39917f57..7f6311861c1 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -216,6 +216,7 @@ use crate::creader::Library; use crate::rmeta::{rustc_version, MetadataBlob, METADATA_HEADER}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::memmap::Mmap; use rustc_data_structures::owning_ref::OwningRef; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::MetadataRef; @@ -232,7 +233,6 @@ use rustc_target::spec::{Target, TargetTriple}; use snap::read::FrameDecoder; use std::io::{Read, Result as IoResult, Write}; -use std::ops::Deref; use std::path::{Path, PathBuf}; use std::{cmp, fmt, fs}; use tracing::{debug, info, warn}; @@ -727,19 +727,6 @@ impl<'a> CrateLocator<'a> { } } -/// A trivial wrapper for `Mmap` that implements `StableDeref`. -struct StableDerefMmap(memmap2::Mmap); - -impl Deref for StableDerefMmap { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - self.0.deref() - } -} - -unsafe impl stable_deref_trait::StableDeref for StableDerefMmap {} - fn get_metadata_section( target: &Target, flavor: CrateFlavor, @@ -779,11 +766,11 @@ fn get_metadata_section( // mmap the file, because only a small fraction of it is read. let file = std::fs::File::open(filename) .map_err(|_| format!("failed to open rmeta metadata: '{}'", filename.display()))?; - let mmap = unsafe { memmap2::Mmap::map(&file) }; + let mmap = unsafe { Mmap::map(file) }; let mmap = mmap .map_err(|_| format!("failed to mmap rmeta metadata: '{}'", filename.display()))?; - rustc_erase_owner!(OwningRef::new(StableDerefMmap(mmap)).map_owner_box()) + rustc_erase_owner!(OwningRef::new(mmap).map_owner_box()) } }; let blob = MetadataBlob::new(raw_bytes); From 8f97b948e36e16a309df436259ac38bb92975eea Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Tue, 30 Mar 2021 18:36:53 +0100 Subject: [PATCH 224/370] bootstrap: don't complain about linkcheck if it is excluded We don't need to complain to the user about linkcheck having different hosts and targets when it is already excluded. This can be achieved by moving the check to when the step is run instead of in should_run. --- src/bootstrap/test.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index f4976f2f436..adb0a372c64 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -108,6 +108,19 @@ impl Step for Linkcheck { /// documentation to ensure we don't have a bunch of dead ones. fn run(self, builder: &Builder<'_>) { let host = self.host; + let hosts = &builder.hosts; + let targets = &builder.targets; + + // if we have different hosts and targets, some things may be built for + // the host (e.g. rustc) and others for the target (e.g. std). The + // documentation built for each will contain broken links to + // docs built for the other platform (e.g. rustc linking to cargo) + if (hosts != targets) && !hosts.is_empty() && !targets.is_empty() { + panic!( + "Linkcheck currently does not support builds with different hosts and targets. +You can skip linkcheck with --exclude src/tools/linkchecker" + ); + } builder.info(&format!("Linkcheck ({})", host)); @@ -123,19 +136,6 @@ impl Step for Linkcheck { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let builder = run.builder; let run = run.path("src/tools/linkchecker"); - let hosts = &builder.hosts; - let targets = &builder.targets; - - // if we have different hosts and targets, some things may be built for - // the host (e.g. rustc) and others for the target (e.g. std). The - // documentation built for each will contain broken links to - // docs built for the other platform (e.g. rustc linking to cargo) - if (hosts != targets) && !hosts.is_empty() && !targets.is_empty() { - panic!( - "Linkcheck currently does not support builds with different hosts and targets. -You can skip linkcheck with --exclude src/tools/linkchecker" - ); - } run.default_condition(builder.config.docs) } From 9d8f833e0587b9c3991f94b227369f38ee48613a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 30 Mar 2021 20:31:06 +0200 Subject: [PATCH 225/370] Remove hir::CrateItem. --- compiler/rustc_ast_lowering/src/lib.rs | 2 +- compiler/rustc_hir/src/hir.rs | 11 ++--------- compiler/rustc_hir/src/intravisit.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/hir/map/mod.rs | 4 ++-- compiler/rustc_passes/src/entry.rs | 2 +- compiler/rustc_passes/src/stability.rs | 4 ++-- compiler/rustc_save_analysis/src/dump_visitor.rs | 15 +++++---------- src/librustdoc/clean/mod.rs | 2 -- src/librustdoc/doctest.rs | 2 +- src/librustdoc/visit_ast.rs | 4 ++-- src/tools/clippy/clippy_lints/src/missing_doc.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 10 +++++----- 15 files changed, 26 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 192c3280327..4e375e00682 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -569,7 +569,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } hir::Crate { - item: hir::CrateItem { module, span: c.span }, + item: module, exported_macros: self.arena.alloc_from_iter(self.exported_macros), non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs), items: self.items, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index d91c1813da3..03af81ae02a 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -625,13 +625,6 @@ pub struct ModuleItems { pub foreign_items: BTreeSet, } -/// A type representing only the top-level module. -#[derive(Encodable, Debug, HashStable_Generic)] -pub struct CrateItem<'hir> { - pub module: Mod<'hir>, - pub span: Span, -} - /// The top-level data structure that stores the entire contents of /// the crate currently being compiled. /// @@ -640,7 +633,7 @@ pub struct CrateItem<'hir> { /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html #[derive(Debug)] pub struct Crate<'hir> { - pub item: CrateItem<'hir>, + pub item: Mod<'hir>, pub exported_macros: &'hir [MacroDef<'hir>], // Attributes from non-exported macros, kept only for collecting the library feature list. pub non_exported_macro_attrs: &'hir [Attribute], @@ -2983,7 +2976,7 @@ pub enum Node<'hir> { GenericParam(&'hir GenericParam<'hir>), Visibility(&'hir Visibility<'hir>), - Crate(&'hir CrateItem<'hir>), + Crate(&'hir Mod<'hir>), } impl<'hir> Node<'hir> { diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 9b908b141af..d766a68e194 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -478,7 +478,7 @@ pub trait Visitor<'v>: Sized { /// Walks the contents of a crate. See also `Crate::visit_all_items`. pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate<'v>) { - visitor.visit_mod(&krate.item.module, krate.item.span, CRATE_HIR_ID); + visitor.visit_mod(&krate.item, krate.item.inner, CRATE_HIR_ID); walk_list!(visitor, visit_macro_def, krate.exported_macros); for (&id, attrs) in krate.attrs.iter() { for a in *attrs { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 89d56ed3174..2d499e194e1 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -170,7 +170,7 @@ pub fn print_crate<'a>( // When printing the AST, we sometimes need to inject `#[no_std]` here. // Since you can't compile the HIR, it's not necessary. - s.print_mod(&krate.item.module, s.attrs(hir::CRATE_HIR_ID)); + s.print_mod(&krate.item, s.attrs(hir::CRATE_HIR_ID)); s.print_remaining_comments(); s.s.eof() } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 218248e715b..3f16bb9f442 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -565,7 +565,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn check_crate(&mut self, cx: &LateContext<'_>, krate: &hir::Crate<'_>) { - self.check_missing_docs_attrs(cx, hir::CRATE_HIR_ID, krate.item.span, "the", "crate"); + self.check_missing_docs_attrs(cx, hir::CRATE_HIR_ID, krate.item.inner, "the", "crate"); for macro_def in krate.exported_macros { let attrs = cx.tcx.hir().attrs(macro_def.hir_id()); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index d055c275299..a5157854e15 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -427,7 +427,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_info_for_items(&mut self) { let krate = self.tcx.hir().krate(); - self.encode_info_for_mod(CRATE_DEF_ID, &krate.item.module); + self.encode_info_for_mod(CRATE_DEF_ID, &krate.item); // Proc-macro crates only export proc-macro items, which are looked // up using `proc_macro_data` diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 9e763befe29..d155276051e 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -459,7 +459,7 @@ impl<'hir> Map<'hir> { let hir_id = self.local_def_id_to_hir_id(module); match self.get_entry(hir_id).node { Node::Item(&Item { span, kind: ItemKind::Mod(ref m), .. }) => (m, span, hir_id), - Node::Crate(item) => (&item.module, item.span, hir_id), + Node::Crate(item) => (&item, item.inner, hir_id), node => panic!("not a module: {:?}", node), } } @@ -868,7 +868,7 @@ impl<'hir> Map<'hir> { Node::Visibility(v) => bug!("unexpected Visibility {:?}", v), Node::Local(local) => local.span, Node::MacroDef(macro_def) => macro_def.span, - Node::Crate(item) => item.span, + Node::Crate(item) => item.inner, }; Some(span) } diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index 57848208f94..e53f821e6da 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -171,7 +171,7 @@ fn configure_main( } fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) { - let sp = tcx.hir().krate().item.span; + let sp = tcx.hir().krate().item.inner; if *tcx.sess.parse_sess.reached_eof.borrow() { // There's an unclosed brace that made the parser reach `Eof`, we shouldn't complain about // the missing `fn main()` then as it might have been hidden inside an unclosed block. diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index e54b1796aaa..9c4f9b1198c 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -686,7 +686,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> { annotator.annotate( hir::CRATE_HIR_ID, - krate.item.span, + krate.item.inner, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -885,7 +885,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { if tcx.stability().staged_api[&LOCAL_CRATE] { let krate = tcx.hir().krate(); let mut missing = MissingStabilityAnnotations { tcx, access_levels }; - missing.check_missing_stability(hir::CRATE_HIR_ID, krate.item.span); + missing.check_missing_stability(hir::CRATE_HIR_ID, krate.item.inner); intravisit::walk_crate(&mut missing, krate); krate.visit_all_item_likes(&mut missing.as_deep_visitor()); } diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs index 65f16ff45a1..12c77e0c8a6 100644 --- a/compiler/rustc_save_analysis/src/dump_visitor.rs +++ b/compiler/rustc_save_analysis/src/dump_visitor.rs @@ -151,7 +151,7 @@ impl<'tcx> DumpVisitor<'tcx> { }, crate_root: crate_root.unwrap_or_else(|| "".to_owned()), external_crates: self.save_ctxt.get_external_crates(), - span: self.span_from_span(krate.item.span), + span: self.span_from_span(krate.item.inner), }; self.dumper.crate_prelude(data); @@ -1097,16 +1097,11 @@ impl<'tcx> DumpVisitor<'tcx> { format!("::{}", self.tcx.def_path_str(self.tcx.hir().local_def_id(id).to_def_id())); let sm = self.tcx.sess.source_map(); - let filename = sm.span_to_filename(krate.item.span); + let filename = sm.span_to_filename(krate.item.inner); let data_id = id_from_hir_id(id, &self.save_ctxt); - let children = krate - .item - .module - .item_ids - .iter() - .map(|i| id_from_def_id(i.def_id.to_def_id())) - .collect(); - let span = self.span_from_span(krate.item.span); + let children = + krate.item.item_ids.iter().map(|i| id_from_def_id(i.def_id.to_def_id())).collect(); + let span = self.span_from_span(krate.item.inner); let attrs = self.tcx.hir().attrs(id); self.dumper.dump_def( diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 80054469f9d..4d33a1e6961 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -129,7 +129,6 @@ impl Clean for CrateNum { tcx.hir() .krate() .item - .module .item_ids .iter() .filter_map(|&id| { @@ -174,7 +173,6 @@ impl Clean for CrateNum { tcx.hir() .krate() .item - .module .item_ids .iter() .filter_map(|&id| { diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index d9e97e02a14..3d0ef028902 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -141,7 +141,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { hir_collector.visit_testable( "".to_string(), CRATE_HIR_ID, - krate.item.span, + krate.item.inner, |this| { intravisit::walk_crate(this, krate); }, diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 17a66d1788e..ca30d8f0d46 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -72,10 +72,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> { let mut top_level_module = self.visit_mod_contents( - krate.item.span, + krate.item.inner, &Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Public }, hir::CRATE_HIR_ID, - &krate.item.module, + &krate.item, self.cx.tcx.crate_name, ); top_level_module.is_crate = true; diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 5741aad261b..21b4983a1af 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) { let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID); - self.check_missing_docs_attrs(cx, attrs, krate.item.span, "the", "crate"); + self.check_missing_docs_attrs(cx, attrs, krate.item.inner, "the", "crate"); } fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index b2655f8d797..6b235875c20 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -61,10 +61,10 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::{ - def, Arm, BindingAnnotation, Block, Body, Constness, CrateItem, Expr, ExprKind, FieldDef, FnDecl, ForeignItem, - GenericArgs, GenericParam, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, LangItem, Lifetime, Local, - MacroDef, MatchSource, Node, Param, Pat, PatKind, Path, PathSegment, QPath, Stmt, TraitItem, TraitItemKind, - TraitRef, TyKind, Variant, Visibility, + def, Arm, BindingAnnotation, Block, Body, Constness, Expr, ExprKind, FieldDef, FnDecl, ForeignItem, GenericArgs, + GenericParam, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, LangItem, Lifetime, Local, MacroDef, + MatchSource, Mod, Node, Param, Pat, PatKind, Path, PathSegment, QPath, Stmt, TraitItem, TraitItemKind, TraitRef, + TyKind, Variant, Visibility, }; use rustc_lint::{LateContext, Level, Lint, LintContext}; use rustc_middle::hir::exports::Export; @@ -743,7 +743,7 @@ pub fn get_node_span(node: Node<'_>) -> Option { | Node::Lifetime(Lifetime { span, .. }) | Node::GenericParam(GenericParam { span, .. }) | Node::Visibility(Visibility { span, .. }) - | Node::Crate(CrateItem { span, .. }) => Some(*span), + | Node::Crate(Mod { inner: span, .. }) => Some(*span), Node::Ctor(_) | Node::AnonConst(_) => None, } } From fbfef40e32d5613af2e765c47caa28dc22caa4a4 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 30 Mar 2021 23:51:15 +0200 Subject: [PATCH 226/370] Fix fulldeps tests. --- src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs | 2 +- src/test/ui-fulldeps/auxiliary/lint-for-crate.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs index 8b1a3887f15..51cea4f6ba9 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs @@ -33,7 +33,7 @@ macro_rules! fake_lint_pass { if !cx.sess().contains_name(attrs, $attr) { cx.lint(CRATE_NOT_OKAY, |lint| { let msg = format!("crate is not marked with #![{}]", $attr); - lint.build(&msg).set_span(krate.item.span).emit() + lint.build(&msg).set_span(krate.item.inner).emit() }); } )* diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index c9269d2b9ba..ef5353e6d8c 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -31,7 +31,7 @@ impl<'tcx> LateLintPass<'tcx> for Pass { if !cx.sess().contains_name(attrs, Symbol::intern("crate_okay")) { cx.lint(CRATE_NOT_OKAY, |lint| { lint.build("crate is not marked with #![crate_okay]") - .set_span(krate.item.span) + .set_span(krate.item.inner) .emit() }); } From 8f7735624924e3399a1abee68615a99072347cc9 Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Tue, 30 Mar 2021 17:56:39 +0800 Subject: [PATCH 227/370] give full path of constraint in suggest_constraining_type_param revert file bless with nll mode --- .../src/traits/error_reporting/suggestions.rs | 4 ++- .../defaults-suitability.stderr | 8 +++--- .../issue-27675-unchecked-bounds.stderr | 4 +-- .../issue-43784-associated-type.stderr | 4 +-- src/test/ui/async-await/issue-70818.stderr | 4 +-- .../ui/bad/bad-method-typaram-kind.stderr | 4 +-- src/test/ui/bound-suggestions.fixed | 12 ++++----- src/test/ui/bound-suggestions.stderr | 24 ++++++++--------- ...builtin-superkinds-double-superkind.stderr | 8 +++--- .../builtin-superkinds-in-metadata.stderr | 4 +-- ...builtin-superkinds-typaram-not-send.stderr | 4 +-- ...ds-cant-promote-superkind-in-struct.stderr | 4 +-- .../ui/closures/closure-bounds-subtype.stderr | 4 +-- .../const-argument-if-length.full.stderr | 4 +-- .../const-argument-if-length.min.stderr | 2 +- .../issues/issue-61336-2.full.stderr | 4 +-- .../issues/issue-61336-2.min.stderr | 4 +-- .../issues/issue-61336.full.stderr | 4 +-- .../issues/issue-61336.min.stderr | 4 +-- .../dst/dst-object-from-unsized-type.stderr | 4 +-- ...ature-gate-generic_associated_types.stderr | 4 +-- .../impl_bounds.stderr | 4 +-- .../issue-68641-check-gat-bounds.stderr | 4 +-- .../issue-68642-broken-llvm-ir.stderr | 4 +-- .../issue-68643-broken-mir.stderr | 4 +-- .../issue-68644-codegen-selection.stderr | 4 +-- .../issue-68645-codegen-fulfillment.stderr | 4 +-- .../issue-74824.stderr | 4 +-- .../impl-trait/issue-55872-1.full_tait.stderr | 8 +++--- .../impl-trait/issue-55872-1.min_tait.stderr | 8 +++--- src/test/ui/issues/issue-27060-2.stderr | 2 +- .../ui/issues/issue-43784-supertrait.stderr | 4 +-- .../kindck/kindck-impl-type-params.nll.stderr | 16 ++++++------ .../ui/kindck/kindck-impl-type-params.stderr | 16 ++++++------ src/test/ui/phantom-auto-trait.stderr | 8 +++--- ...afult-generic-associated-type-bound.stderr | 4 +-- .../defaultimpl/specialization-wfcheck.stderr | 4 +-- ...adt-param-with-implicit-sized-bound.stderr | 2 +- .../suggestions/restrict-type-argument.stderr | 24 ++++++++--------- .../ui/trait-impl-bound-suggestions.fixed | 2 +- .../ui/trait-impl-bound-suggestions.stderr | 4 +-- .../inductive-overflow/two-traits.stderr | 4 +-- .../ui/traits/suggest-where-clause.stderr | 4 +-- .../bounds-are-checked-2.full_tait.stderr | 4 +-- .../bounds-are-checked-2.min_tait.stderr | 4 +-- ...eric_duplicate_param_use5.full_tait.stderr | 8 +++--- ...neric_duplicate_param_use5.min_tait.stderr | 8 +++--- ...eric_duplicate_param_use6.full_tait.stderr | 4 +-- ...neric_duplicate_param_use6.min_tait.stderr | 4 +-- ...eric_duplicate_param_use8.full_tait.stderr | 4 +-- ...neric_duplicate_param_use8.min_tait.stderr | 4 +-- ...eric_duplicate_param_use9.full_tait.stderr | 8 +++--- ...neric_duplicate_param_use9.min_tait.stderr | 8 +++--- ...generic_underconstrained2.full_tait.stderr | 8 +++--- .../generic_underconstrained2.min_tait.stderr | 8 +++--- .../issue-52843.full_tait.stderr | 4 +-- .../issue-52843.min_tait.stderr | 4 +-- src/test/ui/type/type-check-defaults.stderr | 4 +-- ...ypeck-default-trait-impl-send-param.stderr | 4 +-- src/test/ui/union/union-sized-field.stderr | 6 ++--- .../ui/unsized/unsized-bare-typaram.stderr | 2 +- src/test/ui/unsized/unsized-enum.stderr | 2 +- src/test/ui/unsized/unsized-enum2.stderr | 8 +++--- .../unsized-inherent-impl-self-type.stderr | 2 +- src/test/ui/unsized/unsized-struct.stderr | 4 +-- .../unsized-trait-impl-self-type.stderr | 2 +- .../unsized-trait-impl-trait-arg.stderr | 2 +- src/test/ui/unsized3.stderr | 12 ++++----- src/test/ui/unsized5.stderr | 8 +++--- src/test/ui/unsized6.stderr | 26 +++++++++---------- src/test/ui/unsized7.stderr | 2 +- src/test/ui/wf/wf-enum-bound.stderr | 4 +-- .../wf/wf-enum-fields-struct-variant.stderr | 4 +-- src/test/ui/wf/wf-enum-fields.stderr | 4 +-- src/test/ui/wf/wf-fn-where-clause.stderr | 4 +-- src/test/ui/wf/wf-in-fn-arg.stderr | 4 +-- src/test/ui/wf/wf-in-fn-ret.stderr | 4 +-- src/test/ui/wf/wf-in-fn-type-arg.stderr | 4 +-- src/test/ui/wf/wf-in-fn-type-ret.stderr | 4 +-- src/test/ui/wf/wf-in-fn-where-clause.stderr | 4 +-- src/test/ui/wf/wf-in-obj-type-trait.stderr | 4 +-- ...f-inherent-impl-method-where-clause.stderr | 4 +-- .../wf/wf-inherent-impl-where-clause.stderr | 4 +-- src/test/ui/wf/wf-struct-bound.stderr | 4 +-- src/test/ui/wf/wf-struct-field.stderr | 4 +-- .../wf/wf-trait-associated-type-bound.stderr | 4 +-- src/test/ui/wf/wf-trait-bound.stderr | 4 +-- src/test/ui/wf/wf-trait-superbound.stderr | 4 +-- ...traints-are-local-for-inherent-impl.stderr | 4 +-- ...onstraints-are-local-for-trait-impl.stderr | 4 +-- 90 files changed, 249 insertions(+), 247 deletions(-) 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 c1b105f1d84..32f8a16908a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -28,6 +28,7 @@ use std::fmt; use super::InferCtxtPrivExt; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; +use rustc_middle::ty::print::with_no_trimmed_paths; #[derive(Debug)] pub enum GeneratorInteriorOrUpvar { @@ -440,7 +441,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { { // Missing generic type parameter bound. let param_name = self_ty.to_string(); - let constraint = trait_ref.print_only_trait_path().to_string(); + let constraint = + with_no_trimmed_paths(|| trait_ref.print_only_trait_path().to_string()); if suggest_constraining_type_param( self.tcx, generics, diff --git a/src/test/ui/associated-types/defaults-suitability.stderr b/src/test/ui/associated-types/defaults-suitability.stderr index 274d09fd09c..af4e6f0a5c1 100644 --- a/src/test/ui/associated-types/defaults-suitability.stderr +++ b/src/test/ui/associated-types/defaults-suitability.stderr @@ -31,8 +31,8 @@ LL | type Bar: Clone = Vec; = note: required because of the requirements on the impl of `Clone` for `Vec` help: consider restricting type parameter `T` | -LL | trait Foo { - | ^^^^^^^ +LL | trait Foo { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `(): Foo` is not satisfied --> $DIR/defaults-suitability.rs:34:5 @@ -99,8 +99,8 @@ LL | type Baz = T; | help: consider further restricting type parameter `T` | -LL | Self::Baz: Clone, T: Clone - | ^^^^^^^^^^ +LL | Self::Baz: Clone, T: std::clone::Clone + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 8 previous errors diff --git a/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr index 02396bd00a5..b6122bd54d1 100644 --- a/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr +++ b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr @@ -9,8 +9,8 @@ LL | copy::>(t) | help: consider restricting type parameter `T` | -LL | pub fn copy_any(t: &T) -> T { - | ^^^^^^ +LL | pub fn copy_any(t: &T) -> T { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/associated-types/issue-43784-associated-type.stderr b/src/test/ui/associated-types/issue-43784-associated-type.stderr index d5105ae3b58..0e653a7d3b2 100644 --- a/src/test/ui/associated-types/issue-43784-associated-type.stderr +++ b/src/test/ui/associated-types/issue-43784-associated-type.stderr @@ -9,8 +9,8 @@ LL | type Assoc = T; | help: consider restricting type parameter `T` | -LL | impl Complete for T { - | ^^^^^^ +LL | impl Complete for T { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/async-await/issue-70818.stderr b/src/test/ui/async-await/issue-70818.stderr index 11fca2dd8ef..5f39cf6dde1 100644 --- a/src/test/ui/async-await/issue-70818.stderr +++ b/src/test/ui/async-await/issue-70818.stderr @@ -11,8 +11,8 @@ LL | async { (ty, ty1) } | ^^^ has type `U` which is not `Send` help: consider restricting type parameter `U` | -LL | fn foo(ty: T, ty1: U) -> impl Future + Send { - | ^^^^^^ +LL | fn foo(ty: T, ty1: U) -> impl Future + Send { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/bad/bad-method-typaram-kind.stderr b/src/test/ui/bad/bad-method-typaram-kind.stderr index 5b68d97a9ea..fd3999ae6fb 100644 --- a/src/test/ui/bad/bad-method-typaram-kind.stderr +++ b/src/test/ui/bad/bad-method-typaram-kind.stderr @@ -6,8 +6,8 @@ LL | 1.bar::(); | help: consider further restricting this bound | -LL | fn foo() { - | ^^^^^^ +LL | fn foo() { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/bound-suggestions.fixed b/src/test/ui/bound-suggestions.fixed index be61b7dda25..31fdd2b67e2 100644 --- a/src/test/ui/bound-suggestions.fixed +++ b/src/test/ui/bound-suggestions.fixed @@ -5,37 +5,37 @@ use std::fmt::Debug; // Rustfix should add this, or use `std::fmt::Debug` instead. #[allow(dead_code)] -fn test_impl(t: impl Sized + Debug) { +fn test_impl(t: impl Sized + std::fmt::Debug) { println!("{:?}", t); //~^ ERROR doesn't implement } #[allow(dead_code)] -fn test_no_bounds(t: T) { +fn test_no_bounds(t: T) { println!("{:?}", t); //~^ ERROR doesn't implement } #[allow(dead_code)] -fn test_one_bound(t: T) { +fn test_one_bound(t: T) { println!("{:?}", t); //~^ ERROR doesn't implement } #[allow(dead_code)] -fn test_no_bounds_where(x: X, y: Y) where X: std::fmt::Debug, Y: Debug { +fn test_no_bounds_where(x: X, y: Y) where X: std::fmt::Debug, Y: std::fmt::Debug { println!("{:?} {:?}", x, y); //~^ ERROR doesn't implement } #[allow(dead_code)] -fn test_one_bound_where(x: X) where X: Sized + Debug { +fn test_one_bound_where(x: X) where X: Sized + std::fmt::Debug { println!("{:?}", x); //~^ ERROR doesn't implement } #[allow(dead_code)] -fn test_many_bounds_where(x: X) where X: Sized, X: Sized, X: Debug { +fn test_many_bounds_where(x: X) where X: Sized, X: Sized, X: std::fmt::Debug { println!("{:?}", x); //~^ ERROR doesn't implement } diff --git a/src/test/ui/bound-suggestions.stderr b/src/test/ui/bound-suggestions.stderr index 12e67e90265..ebf43bdb271 100644 --- a/src/test/ui/bound-suggestions.stderr +++ b/src/test/ui/bound-suggestions.stderr @@ -8,8 +8,8 @@ LL | println!("{:?}", t); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting this bound | -LL | fn test_impl(t: impl Sized + Debug) { - | ^^^^^^^ +LL | fn test_impl(t: impl Sized + std::fmt::Debug) { + | ^^^^^^^^^^^^^^^^^ error[E0277]: `T` doesn't implement `Debug` --> $DIR/bound-suggestions.rs:15:22 @@ -21,8 +21,8 @@ LL | println!("{:?}", t); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `T` | -LL | fn test_no_bounds(t: T) { - | ^^^^^^^ +LL | fn test_no_bounds(t: T) { + | ^^^^^^^^^^^^^^^^^ error[E0277]: `T` doesn't implement `Debug` --> $DIR/bound-suggestions.rs:21:22 @@ -34,8 +34,8 @@ LL | println!("{:?}", t); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting this bound | -LL | fn test_one_bound(t: T) { - | ^^^^^^^ +LL | fn test_one_bound(t: T) { + | ^^^^^^^^^^^^^^^^^ error[E0277]: `Y` doesn't implement `Debug` --> $DIR/bound-suggestions.rs:27:30 @@ -47,8 +47,8 @@ LL | println!("{:?} {:?}", x, y); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting type parameter `Y` | -LL | fn test_no_bounds_where(x: X, y: Y) where X: std::fmt::Debug, Y: Debug { - | ^^^^^^^^^^ +LL | fn test_no_bounds_where(x: X, y: Y) where X: std::fmt::Debug, Y: std::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ error[E0277]: `X` doesn't implement `Debug` --> $DIR/bound-suggestions.rs:33:22 @@ -60,8 +60,8 @@ LL | println!("{:?}", x); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting this bound | -LL | fn test_one_bound_where(x: X) where X: Sized + Debug { - | ^^^^^^^ +LL | fn test_one_bound_where(x: X) where X: Sized + std::fmt::Debug { + | ^^^^^^^^^^^^^^^^^ error[E0277]: `X` doesn't implement `Debug` --> $DIR/bound-suggestions.rs:39:22 @@ -73,8 +73,8 @@ LL | println!("{:?}", x); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting type parameter `X` | -LL | fn test_many_bounds_where(x: X) where X: Sized, X: Sized, X: Debug { - | ^^^^^^^^^^ +LL | fn test_many_bounds_where(x: X) where X: Sized, X: Sized, X: std::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/bound-suggestions.rs:44:46 diff --git a/src/test/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr b/src/test/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr index 7e8ac113b48..7ff986ec381 100644 --- a/src/test/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr +++ b/src/test/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr @@ -10,8 +10,8 @@ LL | impl Foo for (T,) { } = note: required because it appears within the type `(T,)` help: consider further restricting this bound | -LL | impl Foo for (T,) { } - | ^^^^^^ +LL | impl Foo for (T,) { } + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: `T` cannot be shared between threads safely --> $DIR/builtin-superkinds-double-superkind.rs:9:16 @@ -25,8 +25,8 @@ LL | impl Foo for (T,T) { } = note: required because it appears within the type `(T, T)` help: consider further restricting this bound | -LL | impl Foo for (T,T) { } - | ^^^^^^ +LL | impl Foo for (T,T) { } + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr b/src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr index 2b4b6e548b8..133508d39c1 100644 --- a/src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr +++ b/src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr @@ -12,8 +12,8 @@ LL | pub trait RequiresRequiresShareAndSend : RequiresShare + Send { } = note: required because it appears within the type `X` help: consider further restricting this bound | -LL | impl RequiresRequiresShareAndSend for X { } - | ^^^^^^ +LL | impl RequiresRequiresShareAndSend for X { } + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr b/src/test/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr index ff2cd1c4c8c..ad80b3fa8d1 100644 --- a/src/test/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr +++ b/src/test/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr @@ -9,8 +9,8 @@ LL | impl Foo for T { } | help: consider further restricting this bound | -LL | impl Foo for T { } - | ^^^^^^ +LL | impl Foo for T { } + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr b/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr index 48f18b1ebe9..273eae99553 100644 --- a/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr +++ b/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr @@ -9,8 +9,8 @@ LL | fn foo(blk: F) -> X where F: FnOnce() + 'static { | help: consider further restricting this bound | -LL | fn foo(blk: F) -> X where F: FnOnce() + 'static + Send { - | ^^^^^^ +LL | fn foo(blk: F) -> X where F: FnOnce() + 'static + std::marker::Send { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/closures/closure-bounds-subtype.stderr b/src/test/ui/closures/closure-bounds-subtype.stderr index d649eeccb8c..7df29d5a098 100644 --- a/src/test/ui/closures/closure-bounds-subtype.stderr +++ b/src/test/ui/closures/closure-bounds-subtype.stderr @@ -9,8 +9,8 @@ LL | take_const_owned(f); | help: consider further restricting this bound | -LL | fn give_owned(f: F) where F: FnOnce() + Send + Sync { - | ^^^^^^ +LL | fn give_owned(f: F) where F: FnOnce() + Send + std::marker::Sync { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/const-generics/const-argument-if-length.full.stderr b/src/test/ui/const-generics/const-argument-if-length.full.stderr index 5dca01f0dc0..c6088e665a2 100644 --- a/src/test/ui/const-generics/const-argument-if-length.full.stderr +++ b/src/test/ui/const-generics/const-argument-if-length.full.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/const-argument-if-length.rs:7:28 | LL | pub const fn is_zst() -> usize { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | if std::mem::size_of::() == 0 { | ^ doesn't have a size known at compile-time | @@ -15,7 +15,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/const-argument-if-length.rs:16:12 | LL | pub struct AtLeastByte { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | value: T, | ^ doesn't have a size known at compile-time | diff --git a/src/test/ui/const-generics/const-argument-if-length.min.stderr b/src/test/ui/const-generics/const-argument-if-length.min.stderr index ea177c19746..bc06e8d7fb1 100644 --- a/src/test/ui/const-generics/const-argument-if-length.min.stderr +++ b/src/test/ui/const-generics/const-argument-if-length.min.stderr @@ -11,7 +11,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/const-argument-if-length.rs:16:12 | LL | pub struct AtLeastByte { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | value: T, | ^ doesn't have a size known at compile-time | diff --git a/src/test/ui/const-generics/issues/issue-61336-2.full.stderr b/src/test/ui/const-generics/issues/issue-61336-2.full.stderr index 9f8e68d211d..ef0cafcb9bb 100644 --- a/src/test/ui/const-generics/issues/issue-61336-2.full.stderr +++ b/src/test/ui/const-generics/issues/issue-61336-2.full.stderr @@ -16,8 +16,8 @@ LL | [x; { N }] = note: the `Copy` trait is required because the repeated element will be copied help: consider restricting type parameter `T` | -LL | fn g(x: T) -> [T; N] { - | ^^^^^^ +LL | fn g(x: T) -> [T; N] { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/const-generics/issues/issue-61336-2.min.stderr b/src/test/ui/const-generics/issues/issue-61336-2.min.stderr index 82d17a87e0a..e5fe50513aa 100644 --- a/src/test/ui/const-generics/issues/issue-61336-2.min.stderr +++ b/src/test/ui/const-generics/issues/issue-61336-2.min.stderr @@ -7,8 +7,8 @@ LL | [x; { N }] = note: the `Copy` trait is required because the repeated element will be copied help: consider restricting type parameter `T` | -LL | fn g(x: T) -> [T; N] { - | ^^^^^^ +LL | fn g(x: T) -> [T; N] { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/const-generics/issues/issue-61336.full.stderr b/src/test/ui/const-generics/issues/issue-61336.full.stderr index 974e2af6fd2..fcfd39387c2 100644 --- a/src/test/ui/const-generics/issues/issue-61336.full.stderr +++ b/src/test/ui/const-generics/issues/issue-61336.full.stderr @@ -16,8 +16,8 @@ LL | [x; N] = note: the `Copy` trait is required because the repeated element will be copied help: consider restricting type parameter `T` | -LL | fn g(x: T) -> [T; N] { - | ^^^^^^ +LL | fn g(x: T) -> [T; N] { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/const-generics/issues/issue-61336.min.stderr b/src/test/ui/const-generics/issues/issue-61336.min.stderr index 19c7153582c..91580313e1e 100644 --- a/src/test/ui/const-generics/issues/issue-61336.min.stderr +++ b/src/test/ui/const-generics/issues/issue-61336.min.stderr @@ -7,8 +7,8 @@ LL | [x; N] = note: the `Copy` trait is required because the repeated element will be copied help: consider restricting type parameter `T` | -LL | fn g(x: T) -> [T; N] { - | ^^^^^^ +LL | fn g(x: T) -> [T; N] { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/dst/dst-object-from-unsized-type.stderr b/src/test/ui/dst/dst-object-from-unsized-type.stderr index 49940112a9f..2d12265df98 100644 --- a/src/test/ui/dst/dst-object-from-unsized-type.stderr +++ b/src/test/ui/dst/dst-object-from-unsized-type.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/dst-object-from-unsized-type.rs:8:23 | LL | fn test1(t: &T) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | let u: &dyn Foo = t; | ^ doesn't have a size known at compile-time | @@ -12,7 +12,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/dst-object-from-unsized-type.rs:13:23 | LL | fn test2(t: &T) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | let v: &dyn Foo = t as &dyn Foo; | ^ doesn't have a size known at compile-time | diff --git a/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr b/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr index 266008cc0de..4afbde5021f 100644 --- a/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr +++ b/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr @@ -69,8 +69,8 @@ LL | type Pointer2 = Box; | help: consider restricting type parameter `U32` | -LL | type Pointer2 = Box; - | ^^^^^^^ +LL | type Pointer2 = Box; + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 8 previous errors diff --git a/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr index 645d2927145..e3d3de8bf94 100644 --- a/src/test/ui/generic-associated-types/impl_bounds.stderr +++ b/src/test/ui/generic-associated-types/impl_bounds.stderr @@ -51,8 +51,8 @@ LL | type C where Self: Copy = String; = note: the requirement `Fooy: Copy` appears on the associated impl type but not on the corresponding associated trait type help: consider restricting type parameter `T` | -LL | impl Foo for Fooy { - | ^^^^^^ +LL | impl Foo for Fooy { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr b/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr index b380f0da2ea..c92800c3746 100644 --- a/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr +++ b/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr @@ -18,8 +18,8 @@ LL | type Item<'a> = T; | help: consider restricting type parameter `T` | -LL | impl UnsafeCopy for T { - | ^^^^^^ +LL | impl UnsafeCopy for T { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr b/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr index 61950478c32..e44547b10c1 100644 --- a/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr +++ b/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr @@ -19,8 +19,8 @@ LL | type F<'a> = Self; = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }` help: consider restricting type parameter `T` | -LL | impl> Fun for T { - | ^^^^^^^^ +LL | impl> Fun for T { + | ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/generic-associated-types/issue-68643-broken-mir.stderr b/src/test/ui/generic-associated-types/issue-68643-broken-mir.stderr index 13980618987..fd0b4733d93 100644 --- a/src/test/ui/generic-associated-types/issue-68643-broken-mir.stderr +++ b/src/test/ui/generic-associated-types/issue-68643-broken-mir.stderr @@ -19,8 +19,8 @@ LL | type F<'a> = Self; = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }` help: consider restricting type parameter `T` | -LL | impl> Fun for T { - | ^^^^^^^^ +LL | impl> Fun for T { + | ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/generic-associated-types/issue-68644-codegen-selection.stderr b/src/test/ui/generic-associated-types/issue-68644-codegen-selection.stderr index 81124251469..0c23c870f01 100644 --- a/src/test/ui/generic-associated-types/issue-68644-codegen-selection.stderr +++ b/src/test/ui/generic-associated-types/issue-68644-codegen-selection.stderr @@ -19,8 +19,8 @@ LL | type F<'a> = Self; = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }` help: consider restricting type parameter `T` | -LL | impl> Fun for T { - | ^^^^^^^^ +LL | impl> Fun for T { + | ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr b/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr index 22f50b39498..85d8d3f8e93 100644 --- a/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr +++ b/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr @@ -19,8 +19,8 @@ LL | type F<'a> = Self; = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }` help: consider restricting type parameter `T` | -LL | impl> Fun for T { - | ^^^^^^^^ +LL | impl> Fun for T { + | ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/generic-associated-types/issue-74824.stderr b/src/test/ui/generic-associated-types/issue-74824.stderr index 34a2c1932eb..7a7b5fd4f1c 100644 --- a/src/test/ui/generic-associated-types/issue-74824.stderr +++ b/src/test/ui/generic-associated-types/issue-74824.stderr @@ -19,8 +19,8 @@ LL | type Copy: Copy = Box; = note: required because of the requirements on the impl of `Clone` for `Box` help: consider restricting type parameter `T` | -LL | type Copy: Copy = Box; - | ^^^^^^^ +LL | type Copy: Copy = Box; + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/impl-trait/issue-55872-1.full_tait.stderr b/src/test/ui/impl-trait/issue-55872-1.full_tait.stderr index 5195333884a..67a500f34d8 100644 --- a/src/test/ui/impl-trait/issue-55872-1.full_tait.stderr +++ b/src/test/ui/impl-trait/issue-55872-1.full_tait.stderr @@ -25,8 +25,8 @@ LL | type E = impl Copy; = note: required because it appears within the type `(S, T)` help: consider further restricting this bound | -LL | impl Bar for S { - | ^^^^^^ +LL | impl Bar for S { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: Copy` is not satisfied in `(S, T)` --> $DIR/issue-55872-1.rs:14:14 @@ -37,8 +37,8 @@ LL | type E = impl Copy; = note: required because it appears within the type `(S, T)` help: consider further restricting this bound | -LL | fn foo() -> Self::E { - | ^^^^^^ +LL | fn foo() -> Self::E { + | ^^^^^^^^^^^^^^^^^^^ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias --> $DIR/issue-55872-1.rs:18:37 diff --git a/src/test/ui/impl-trait/issue-55872-1.min_tait.stderr b/src/test/ui/impl-trait/issue-55872-1.min_tait.stderr index 26fc200c2a2..90225d249d7 100644 --- a/src/test/ui/impl-trait/issue-55872-1.min_tait.stderr +++ b/src/test/ui/impl-trait/issue-55872-1.min_tait.stderr @@ -16,8 +16,8 @@ LL | type E = impl Copy; = note: required because it appears within the type `(S, T)` help: consider further restricting this bound | -LL | impl Bar for S { - | ^^^^^^ +LL | impl Bar for S { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: Copy` is not satisfied in `(S, T)` --> $DIR/issue-55872-1.rs:14:14 @@ -28,8 +28,8 @@ LL | type E = impl Copy; = note: required because it appears within the type `(S, T)` help: consider further restricting this bound | -LL | fn foo() -> Self::E { - | ^^^^^^ +LL | fn foo() -> Self::E { + | ^^^^^^^^^^^^^^^^^^^ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias --> $DIR/issue-55872-1.rs:18:37 diff --git a/src/test/ui/issues/issue-27060-2.stderr b/src/test/ui/issues/issue-27060-2.stderr index c4faecbdf2f..5dbcc96e874 100644 --- a/src/test/ui/issues/issue-27060-2.stderr +++ b/src/test/ui/issues/issue-27060-2.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/issue-27060-2.rs:3:11 | LL | pub struct Bad { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | data: T, | ^ doesn't have a size known at compile-time | diff --git a/src/test/ui/issues/issue-43784-supertrait.stderr b/src/test/ui/issues/issue-43784-supertrait.stderr index c73536ba973..45a2350ddfd 100644 --- a/src/test/ui/issues/issue-43784-supertrait.stderr +++ b/src/test/ui/issues/issue-43784-supertrait.stderr @@ -9,8 +9,8 @@ LL | impl Complete for T {} | help: consider restricting type parameter `T` | -LL | impl Complete for T {} - | ^^^^^^ +LL | impl Complete for T {} + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/kindck/kindck-impl-type-params.nll.stderr b/src/test/ui/kindck/kindck-impl-type-params.nll.stderr index b01b8258e73..e9002ec36f4 100644 --- a/src/test/ui/kindck/kindck-impl-type-params.nll.stderr +++ b/src/test/ui/kindck/kindck-impl-type-params.nll.stderr @@ -8,8 +8,8 @@ LL | let a = &t as &dyn Gettable; = note: required for the cast to the object type `dyn Gettable` help: consider restricting type parameter `T` | -LL | fn f(val: T) { - | ^^^^^^ +LL | fn f(val: T) { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: Copy` is not satisfied --> $DIR/kindck-impl-type-params.rs:18:13 @@ -21,8 +21,8 @@ LL | let a = &t as &dyn Gettable; = note: required for the cast to the object type `dyn Gettable` help: consider restricting type parameter `T` | -LL | fn f(val: T) { - | ^^^^^^ +LL | fn f(val: T) { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: `T` cannot be sent between threads safely --> $DIR/kindck-impl-type-params.rs:25:31 @@ -34,8 +34,8 @@ LL | let a: &dyn Gettable = &t; = note: required for the cast to the object type `dyn Gettable` help: consider restricting type parameter `T` | -LL | fn g(val: T) { - | ^^^^^^ +LL | fn g(val: T) { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: Copy` is not satisfied --> $DIR/kindck-impl-type-params.rs:25:31 @@ -47,8 +47,8 @@ LL | let a: &dyn Gettable = &t; = note: required for the cast to the object type `dyn Gettable` help: consider restricting type parameter `T` | -LL | fn g(val: T) { - | ^^^^^^ +LL | fn g(val: T) { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/kindck-impl-type-params.rs:38:13 diff --git a/src/test/ui/kindck/kindck-impl-type-params.stderr b/src/test/ui/kindck/kindck-impl-type-params.stderr index ddf8adf3637..472a6bcafa2 100644 --- a/src/test/ui/kindck/kindck-impl-type-params.stderr +++ b/src/test/ui/kindck/kindck-impl-type-params.stderr @@ -8,8 +8,8 @@ LL | let a = &t as &dyn Gettable; = note: required for the cast to the object type `dyn Gettable` help: consider restricting type parameter `T` | -LL | fn f(val: T) { - | ^^^^^^ +LL | fn f(val: T) { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: Copy` is not satisfied --> $DIR/kindck-impl-type-params.rs:18:13 @@ -21,8 +21,8 @@ LL | let a = &t as &dyn Gettable; = note: required for the cast to the object type `dyn Gettable` help: consider restricting type parameter `T` | -LL | fn f(val: T) { - | ^^^^^^ +LL | fn f(val: T) { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: `T` cannot be sent between threads safely --> $DIR/kindck-impl-type-params.rs:25:31 @@ -34,8 +34,8 @@ LL | let a: &dyn Gettable = &t; = note: required for the cast to the object type `dyn Gettable` help: consider restricting type parameter `T` | -LL | fn g(val: T) { - | ^^^^^^ +LL | fn g(val: T) { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: Copy` is not satisfied --> $DIR/kindck-impl-type-params.rs:25:31 @@ -47,8 +47,8 @@ LL | let a: &dyn Gettable = &t; = note: required for the cast to the object type `dyn Gettable` help: consider restricting type parameter `T` | -LL | fn g(val: T) { - | ^^^^^^ +LL | fn g(val: T) { + | ^^^^^^^^^^^^^^^^^^^ error[E0477]: the type `&'a isize` does not fulfill the required lifetime --> $DIR/kindck-impl-type-params.rs:32:13 diff --git a/src/test/ui/phantom-auto-trait.stderr b/src/test/ui/phantom-auto-trait.stderr index 779919f9d64..5a2ad637e42 100644 --- a/src/test/ui/phantom-auto-trait.stderr +++ b/src/test/ui/phantom-auto-trait.stderr @@ -12,8 +12,8 @@ LL | is_zen(x) = note: required because it appears within the type `Guard<'_, T>` help: consider restricting type parameter `T` | -LL | fn not_sync(x: Guard) { - | ^^^^^^ +LL | fn not_sync(x: Guard) { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: `T` cannot be shared between threads safely --> $DIR/phantom-auto-trait.rs:26:12 @@ -30,8 +30,8 @@ LL | is_zen(x) = note: required because it appears within the type `Nested>` help: consider restricting type parameter `T` | -LL | fn nested_not_sync(x: Nested>) { - | ^^^^^^ +LL | fn nested_not_sync(x: Nested>) { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/specialization/deafult-generic-associated-type-bound.stderr b/src/test/ui/specialization/deafult-generic-associated-type-bound.stderr index b5a1877ea19..eb5d80bc4dd 100644 --- a/src/test/ui/specialization/deafult-generic-associated-type-bound.stderr +++ b/src/test/ui/specialization/deafult-generic-associated-type-bound.stderr @@ -28,8 +28,8 @@ LL | default type U<'a> = &'a T; = note: required because of the requirements on the impl of `PartialEq` for `&'a T` help: consider further restricting this bound | -LL | impl X for T { - | ^^^^^^^^^^^ +LL | impl X for T { + | ^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error; 2 warnings emitted diff --git a/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr b/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr index 57b90c457cb..e416f30cb41 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr @@ -19,8 +19,8 @@ LL | default impl Foo<'static, U> for () {} | help: consider restricting type parameter `U` | -LL | default impl Foo<'static, U> for () {} - | ^^^^ +LL | default impl Foo<'static, U> for () {} + | ^^^^^^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr b/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr index 9437fbe61cc..5cb3a404037 100644 --- a/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr +++ b/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr @@ -5,7 +5,7 @@ LL | struct X(T); | - required by this bound in `X` ... LL | struct Struct5{ - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | _t: X, | ^^^^ doesn't have a size known at compile-time | diff --git a/src/test/ui/suggestions/restrict-type-argument.stderr b/src/test/ui/suggestions/restrict-type-argument.stderr index 7a7242a6369..33af13d943f 100644 --- a/src/test/ui/suggestions/restrict-type-argument.stderr +++ b/src/test/ui/suggestions/restrict-type-argument.stderr @@ -9,8 +9,8 @@ LL | is_send(val); | help: consider further restricting this bound | -LL | fn use_impl_sync(val: impl Sync + Send) { - | ^^^^^^ +LL | fn use_impl_sync(val: impl Sync + std::marker::Send) { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: `S` cannot be sent between threads safely --> $DIR/restrict-type-argument.rs:8:13 @@ -23,8 +23,8 @@ LL | is_send(val); | help: consider further restricting this bound | -LL | fn use_where(val: S) where S: Sync + Send { - | ^^^^^^ +LL | fn use_where(val: S) where S: Sync + std::marker::Send { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: `S` cannot be sent between threads safely --> $DIR/restrict-type-argument.rs:12:13 @@ -37,8 +37,8 @@ LL | is_send(val); | help: consider further restricting this bound | -LL | fn use_bound(val: S) { - | ^^^^^^ +LL | fn use_bound(val: S) { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: `S` cannot be sent between threads safely --> $DIR/restrict-type-argument.rs:20:13 @@ -51,8 +51,8 @@ LL | is_send(val); | help: consider further restricting this bound | -LL | Sync + Send - | ^^^^^^ +LL | Sync + std::marker::Send + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: `S` cannot be sent between threads safely --> $DIR/restrict-type-argument.rs:24:13 @@ -65,8 +65,8 @@ LL | is_send(val); | help: consider further restricting this bound | -LL | fn use_bound_and_where(val: S) where S: std::fmt::Debug + Send { - | ^^^^^^ +LL | fn use_bound_and_where(val: S) where S: std::fmt::Debug + std::marker::Send { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: `S` cannot be sent between threads safely --> $DIR/restrict-type-argument.rs:28:13 @@ -79,8 +79,8 @@ LL | is_send(val); | help: consider restricting type parameter `S` | -LL | fn use_unbound(val: S) { - | ^^^^^^ +LL | fn use_unbound(val: S) { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/src/test/ui/trait-impl-bound-suggestions.fixed b/src/test/ui/trait-impl-bound-suggestions.fixed index db3a95f5c4f..744e7bef04e 100644 --- a/src/test/ui/trait-impl-bound-suggestions.fixed +++ b/src/test/ui/trait-impl-bound-suggestions.fixed @@ -10,7 +10,7 @@ struct ConstrainedStruct { } #[allow(dead_code)] -trait InsufficientlyConstrainedGeneric where X: Copy { +trait InsufficientlyConstrainedGeneric where X: std::marker::Copy { fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct { //~^ ERROR the trait bound `X: Copy` is not satisfied ConstrainedStruct { x } diff --git a/src/test/ui/trait-impl-bound-suggestions.stderr b/src/test/ui/trait-impl-bound-suggestions.stderr index 3a21e9c6b2a..110ca799080 100644 --- a/src/test/ui/trait-impl-bound-suggestions.stderr +++ b/src/test/ui/trait-impl-bound-suggestions.stderr @@ -9,8 +9,8 @@ LL | fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct { | help: consider further restricting type parameter `X` | -LL | trait InsufficientlyConstrainedGeneric where X: Copy { - | ^^^^^^^^^^^^^ +LL | trait InsufficientlyConstrainedGeneric where X: std::marker::Copy { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/traits/inductive-overflow/two-traits.stderr b/src/test/ui/traits/inductive-overflow/two-traits.stderr index d3f2931f25d..508a12d859a 100644 --- a/src/test/ui/traits/inductive-overflow/two-traits.stderr +++ b/src/test/ui/traits/inductive-overflow/two-traits.stderr @@ -9,8 +9,8 @@ LL | type X = Self; | help: consider further restricting this bound | -LL | impl Magic for T { - | ^^^^^^ +LL | impl Magic for T { + | ^^^^^^^^^^^^^^^^^^^ error[E0275]: overflow evaluating the requirement `*mut (): Magic` --> $DIR/two-traits.rs:20:5 diff --git a/src/test/ui/traits/suggest-where-clause.stderr b/src/test/ui/traits/suggest-where-clause.stderr index 86d589ffa9e..efab64205f3 100644 --- a/src/test/ui/traits/suggest-where-clause.stderr +++ b/src/test/ui/traits/suggest-where-clause.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `U` cannot be known at compilation tim --> $DIR/suggest-where-clause.rs:7:20 | LL | fn check() { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | // suggest a where-clause, if needed LL | mem::size_of::(); | ^ doesn't have a size known at compile-time @@ -16,7 +16,7 @@ error[E0277]: the size for values of type `U` cannot be known at compilation tim --> $DIR/suggest-where-clause.rs:10:5 | LL | fn check() { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | mem::size_of::>(); | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time diff --git a/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.full_tait.stderr b/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.full_tait.stderr index 871ef22f3eb..cfb1fe9c19a 100644 --- a/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.full_tait.stderr @@ -15,8 +15,8 @@ LL | type X = impl Clone; | help: consider restricting type parameter `T` | -LL | type X = impl Clone; - | ^^^^^^^ +LL | type X = impl Clone; + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.min_tait.stderr b/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.min_tait.stderr index 20656e5e553..735b96d5df9 100644 --- a/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.min_tait.stderr @@ -6,8 +6,8 @@ LL | type X = impl Clone; | help: consider restricting type parameter `T` | -LL | type X = impl Clone; - | ^^^^^^^ +LL | type X = impl Clone; + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.full_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.full_tait.stderr index 8a0c411c775..aab64e72b7b 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.full_tait.stderr @@ -28,8 +28,8 @@ LL | type Two = impl Debug; = note: required because of the requirements on the impl of `Debug` for `(T, U)` help: consider restricting type parameter `T` | -LL | type Two = impl Debug; - | ^^^^^^^ +LL | type Two = impl Debug; + | ^^^^^^^^^^^^^^^^^ error[E0277]: `U` doesn't implement `Debug` --> $DIR/generic_duplicate_param_use5.rs:11:18 @@ -40,8 +40,8 @@ LL | type Two = impl Debug; = note: required because of the requirements on the impl of `Debug` for `(T, U)` help: consider restricting type parameter `U` | -LL | type Two = impl Debug; - | ^^^^^^^ +LL | type Two = impl Debug; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors; 1 warning emitted diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.min_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.min_tait.stderr index 35115ccb2d6..5c8c5b89779 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.min_tait.stderr @@ -19,8 +19,8 @@ LL | type Two = impl Debug; = note: required because of the requirements on the impl of `Debug` for `(T, U)` help: consider restricting type parameter `T` | -LL | type Two = impl Debug; - | ^^^^^^^ +LL | type Two = impl Debug; + | ^^^^^^^^^^^^^^^^^ error[E0277]: `U` doesn't implement `Debug` --> $DIR/generic_duplicate_param_use5.rs:11:18 @@ -31,8 +31,8 @@ LL | type Two = impl Debug; = note: required because of the requirements on the impl of `Debug` for `(T, U)` help: consider restricting type parameter `U` | -LL | type Two = impl Debug; - | ^^^^^^^ +LL | type Two = impl Debug; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.full_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.full_tait.stderr index 8f72c333e81..a69e99bf8b0 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.full_tait.stderr @@ -28,8 +28,8 @@ LL | type Two = impl Debug; = note: required because of the requirements on the impl of `Debug` for `(T, T)` help: consider restricting type parameter `T` | -LL | type Two = impl Debug; - | ^^^^^^^ +LL | type Two = impl Debug; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors; 1 warning emitted diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.min_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.min_tait.stderr index 922c9a74208..a377ef2d873 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.min_tait.stderr @@ -19,8 +19,8 @@ LL | type Two = impl Debug; = note: required because of the requirements on the impl of `Debug` for `(T, T)` help: consider restricting type parameter `T` | -LL | type Two = impl Debug; - | ^^^^^^^ +LL | type Two = impl Debug; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.full_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.full_tait.stderr index a93321d4d05..e73ac88500e 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.full_tait.stderr @@ -28,8 +28,8 @@ LL | type Two = impl Debug; = note: required because of the requirements on the impl of `Debug` for `(T, u32)` help: consider restricting type parameter `T` | -LL | type Two = impl Debug; - | ^^^^^^^ +LL | type Two = impl Debug; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors; 1 warning emitted diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.min_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.min_tait.stderr index 25ac60799f6..d7edce7a491 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.min_tait.stderr @@ -19,8 +19,8 @@ LL | type Two = impl Debug; = note: required because of the requirements on the impl of `Debug` for `(T, u32)` help: consider restricting type parameter `T` | -LL | type Two = impl Debug; - | ^^^^^^^ +LL | type Two = impl Debug; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.full_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.full_tait.stderr index 098be7929d6..0b3d72d67b2 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.full_tait.stderr @@ -40,8 +40,8 @@ LL | type Two = impl Debug; = note: required because of the requirements on the impl of `Debug` for `(A, B, ::Bar)` help: consider restricting type parameter `A` | -LL | type Two = impl Debug; - | ^^^^^^^ +LL | type Two = impl Debug; + | ^^^^^^^^^^^^^^^^^ error[E0277]: `B` doesn't implement `Debug` --> $DIR/generic_duplicate_param_use9.rs:10:18 @@ -52,8 +52,8 @@ LL | type Two = impl Debug; = note: required because of the requirements on the impl of `Debug` for `(A, B, ::Bar)` help: consider restricting type parameter `B` | -LL | type Two = impl Debug; - | ^^^^^^^ +LL | type Two = impl Debug; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors; 1 warning emitted diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.min_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.min_tait.stderr index b59e10c1b06..fd1081d7b71 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.min_tait.stderr @@ -31,8 +31,8 @@ LL | type Two = impl Debug; = note: required because of the requirements on the impl of `Debug` for `(A, B, ::Bar)` help: consider restricting type parameter `A` | -LL | type Two = impl Debug; - | ^^^^^^^ +LL | type Two = impl Debug; + | ^^^^^^^^^^^^^^^^^ error[E0277]: `B` doesn't implement `Debug` --> $DIR/generic_duplicate_param_use9.rs:10:18 @@ -43,8 +43,8 @@ LL | type Two = impl Debug; = note: required because of the requirements on the impl of `Debug` for `(A, B, ::Bar)` help: consider restricting type parameter `B` | -LL | type Two = impl Debug; - | ^^^^^^^ +LL | type Two = impl Debug; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.full_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.full_tait.stderr index ca263ba4f5b..7ab73d24274 100644 --- a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.full_tait.stderr @@ -30,8 +30,8 @@ LL | fn underconstrained(_: U) -> Underconstrained { | help: consider restricting type parameter `U` | -LL | fn underconstrained(_: U) -> Underconstrained { - | ^^^^^^^ +LL | fn underconstrained(_: U) -> Underconstrained { + | ^^^^^^^^^^^^^^^^^ error[E0277]: `V` doesn't implement `Debug` --> $DIR/generic_underconstrained2.rs:21:43 @@ -44,8 +44,8 @@ LL | fn underconstrained2(_: U, _: V) -> Underconstrained2 { | help: consider restricting type parameter `V` | -LL | fn underconstrained2(_: U, _: V) -> Underconstrained2 { - | ^^^^^^^ +LL | fn underconstrained2(_: U, _: V) -> Underconstrained2 { + | ^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors; 1 warning emitted diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.min_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.min_tait.stderr index 6ce32f457e3..a4f5f4b8645 100644 --- a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.min_tait.stderr @@ -21,8 +21,8 @@ LL | fn underconstrained(_: U) -> Underconstrained { | help: consider restricting type parameter `U` | -LL | fn underconstrained(_: U) -> Underconstrained { - | ^^^^^^^ +LL | fn underconstrained(_: U) -> Underconstrained { + | ^^^^^^^^^^^^^^^^^ error[E0277]: `V` doesn't implement `Debug` --> $DIR/generic_underconstrained2.rs:21:43 @@ -35,8 +35,8 @@ LL | fn underconstrained2(_: U, _: V) -> Underconstrained2 { | help: consider restricting type parameter `V` | -LL | fn underconstrained2(_: U, _: V) -> Underconstrained2 { - | ^^^^^^^ +LL | fn underconstrained2(_: U, _: V) -> Underconstrained2 { + | ^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/type-alias-impl-trait/issue-52843.full_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-52843.full_tait.stderr index 14f4f62d7a5..35ac0993b29 100644 --- a/src/test/ui/type-alias-impl-trait/issue-52843.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-52843.full_tait.stderr @@ -15,8 +15,8 @@ LL | type Foo = impl Default; | help: consider restricting type parameter `T` | -LL | type Foo = impl Default; - | ^^^^^^^^^ +LL | type Foo = impl Default; + | ^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/type-alias-impl-trait/issue-52843.min_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-52843.min_tait.stderr index 6dda27f515e..9fb760f34c1 100644 --- a/src/test/ui/type-alias-impl-trait/issue-52843.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-52843.min_tait.stderr @@ -6,8 +6,8 @@ LL | type Foo = impl Default; | help: consider restricting type parameter `T` | -LL | type Foo = impl Default; - | ^^^^^^^^^ +LL | type Foo = impl Default; + | ^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type/type-check-defaults.stderr b/src/test/ui/type/type-check-defaults.stderr index d8c7f595e62..ddfa31cf624 100644 --- a/src/test/ui/type/type-check-defaults.stderr +++ b/src/test/ui/type/type-check-defaults.stderr @@ -56,8 +56,8 @@ LL | trait Base: Super { } | help: consider further restricting type parameter `T` | -LL | trait Base: Super where T: Copy { } - | ^^^^^^^^^^^^^ +LL | trait Base: Super where T: std::marker::Copy { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: cannot add `u8` to `i32` --> $DIR/type-check-defaults.rs:24:66 diff --git a/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr b/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr index 4fb423b9a2c..7398b48a238 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr +++ b/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr @@ -9,8 +9,8 @@ LL | fn is_send() { | help: consider restricting type parameter `T` | -LL | fn foo() { - | ^^^^^^ +LL | fn foo() { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/union/union-sized-field.stderr b/src/test/ui/union/union-sized-field.stderr index cebeeb59a78..b916bbe8ad1 100644 --- a/src/test/ui/union/union-sized-field.stderr +++ b/src/test/ui/union/union-sized-field.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/union-sized-field.rs:4:12 | LL | union Foo { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | value: T, | ^ doesn't have a size known at compile-time | @@ -21,7 +21,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/union-sized-field.rs:9:12 | LL | struct Foo2 { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | value: T, | ^ doesn't have a size known at compile-time | @@ -40,7 +40,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim --> $DIR/union-sized-field.rs:15:11 | LL | enum Foo3 { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | Value(T), | ^ doesn't have a size known at compile-time | diff --git a/src/test/ui/unsized/unsized-bare-typaram.stderr b/src/test/ui/unsized/unsized-bare-typaram.stderr index b2ff3159c95..19978ae24ca 100644 --- a/src/test/ui/unsized/unsized-bare-typaram.stderr +++ b/src/test/ui/unsized/unsized-bare-typaram.stderr @@ -6,7 +6,7 @@ LL | fn bar() { } LL | fn foo() { bar::() } | - ^ doesn't have a size known at compile-time | | - | this type parameter needs to be `Sized` + | this type parameter needs to be `std::marker::Sized` error: aborting due to previous error diff --git a/src/test/ui/unsized/unsized-enum.stderr b/src/test/ui/unsized/unsized-enum.stderr index 3057d4789bd..601db7d1cd9 100644 --- a/src/test/ui/unsized/unsized-enum.stderr +++ b/src/test/ui/unsized/unsized-enum.stderr @@ -7,7 +7,7 @@ LL | fn foo1() { not_sized::>() } // Hunky dory. LL | fn foo2() { not_sized::>() } | - ^^^^^^ doesn't have a size known at compile-time | | - | this type parameter needs to be `Sized` + | this type parameter needs to be `std::marker::Sized` | help: you could relax the implicit `Sized` bound on `U` if it were used through indirection like `&U` or `Box` --> $DIR/unsized-enum.rs:4:10 diff --git a/src/test/ui/unsized/unsized-enum2.stderr b/src/test/ui/unsized/unsized-enum2.stderr index 0a0896638e0..79f690e8d1a 100644 --- a/src/test/ui/unsized/unsized-enum2.stderr +++ b/src/test/ui/unsized/unsized-enum2.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `W` cannot be known at compilation tim --> $DIR/unsized-enum2.rs:23:8 | LL | enum E { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | // parameter LL | VA(W), | ^ doesn't have a size known at compile-time @@ -22,7 +22,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized-enum2.rs:25:11 | LL | enum E { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | VB{x: X}, | ^ doesn't have a size known at compile-time @@ -42,7 +42,7 @@ error[E0277]: the size for values of type `Y` cannot be known at compilation tim --> $DIR/unsized-enum2.rs:27:15 | LL | enum E { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | VC(isize, Y), | ^ doesn't have a size known at compile-time @@ -62,7 +62,7 @@ error[E0277]: the size for values of type `Z` cannot be known at compilation tim --> $DIR/unsized-enum2.rs:29:21 | LL | enum E { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | VD{u: isize, x: Z}, | ^ doesn't have a size known at compile-time diff --git a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr index 9d8a1c67734..9d072eda4e8 100644 --- a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr +++ b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr @@ -7,7 +7,7 @@ LL | LL | impl S5 { | - ^^^^^ doesn't have a size known at compile-time | | - | this type parameter needs to be `Sized` + | this type parameter needs to be `std::marker::Sized` | help: you could relax the implicit `Sized` bound on `Y` if it were used through indirection like `&Y` or `Box` --> $DIR/unsized-inherent-impl-self-type.rs:5:11 diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr index 6661cf358b3..52cf1cbb81d 100644 --- a/src/test/ui/unsized/unsized-struct.stderr +++ b/src/test/ui/unsized/unsized-struct.stderr @@ -7,7 +7,7 @@ LL | fn foo1() { not_sized::>() } // Hunky dory. LL | fn foo2() { not_sized::>() } | - ^^^^^^ doesn't have a size known at compile-time | | - | this type parameter needs to be `Sized` + | this type parameter needs to be `std::marker::Sized` | help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` --> $DIR/unsized-struct.rs:4:12 @@ -26,7 +26,7 @@ LL | fn is_sized() { } LL | fn bar2() { is_sized::>() } | - ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | | - | this type parameter needs to be `Sized` + | this type parameter needs to be `std::marker::Sized` | = note: required because it appears within the type `Bar` diff --git a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr index d1b590d8133..aef0d0cbb83 100644 --- a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr +++ b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr @@ -7,7 +7,7 @@ LL | LL | impl T3 for S5 { | - ^^^^^ doesn't have a size known at compile-time | | - | this type parameter needs to be `Sized` + | this type parameter needs to be `std::marker::Sized` | help: you could relax the implicit `Sized` bound on `Y` if it were used through indirection like `&Y` or `Box` --> $DIR/unsized-trait-impl-self-type.rs:8:11 diff --git a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr index 17fe16ed4fc..f48d4ef9f14 100644 --- a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr +++ b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr @@ -7,7 +7,7 @@ LL | trait T2 { LL | impl T2 for S4 { | - ^^^^^ doesn't have a size known at compile-time | | - | this type parameter needs to be `Sized` + | this type parameter needs to be `std::marker::Sized` | help: consider relaxing the implicit `Sized` restriction | diff --git a/src/test/ui/unsized3.stderr b/src/test/ui/unsized3.stderr index 7ed43c38f1d..ddddae4eaba 100644 --- a/src/test/ui/unsized3.stderr +++ b/src/test/ui/unsized3.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized3.rs:7:13 | LL | fn f1(x: &X) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | f2::(x); | ^ doesn't have a size known at compile-time ... @@ -18,7 +18,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized3.rs:18:13 | LL | fn f3(x: &X) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | f4::(x); | ^ doesn't have a size known at compile-time ... @@ -37,7 +37,7 @@ LL | fn f5(x: &Y) {} | - required by this bound in `f5` ... LL | fn f8(x1: &S, x2: &S) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | f5(x1); | ^^ doesn't have a size known at compile-time | @@ -51,7 +51,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized3.rs:40:8 | LL | fn f9(x1: Box>) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | f5(&(*x1, 34)); | ^^^^^^^^^^ doesn't have a size known at compile-time | @@ -62,7 +62,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized3.rs:45:9 | LL | fn f10(x1: Box>) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | f5(&(32, *x1)); | ^^^^^^^^^ doesn't have a size known at compile-time | @@ -77,7 +77,7 @@ LL | fn f5(x: &Y) {} | - required by this bound in `f5` ... LL | fn f10(x1: Box>) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | f5(&(32, *x1)); | ^^^^^^^^^^ doesn't have a size known at compile-time | diff --git a/src/test/ui/unsized5.stderr b/src/test/ui/unsized5.stderr index a7539b0672a..0bfd4565529 100644 --- a/src/test/ui/unsized5.stderr +++ b/src/test/ui/unsized5.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized5.rs:4:9 | LL | struct S1 { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | f1: X, | ^ doesn't have a size known at compile-time | @@ -21,7 +21,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized5.rs:10:8 | LL | struct S2 { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | f: isize, LL | g: X, | ^ doesn't have a size known at compile-time @@ -77,7 +77,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized5.rs:25:8 | LL | enum E { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | V1(X, isize), | ^ doesn't have a size known at compile-time | @@ -96,7 +96,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized5.rs:29:12 | LL | enum F { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | V2{f1: X, f: isize}, | ^ doesn't have a size known at compile-time | diff --git a/src/test/ui/unsized6.stderr b/src/test/ui/unsized6.stderr index 71dac236fa3..f9f7877d542 100644 --- a/src/test/ui/unsized6.stderr +++ b/src/test/ui/unsized6.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `Y` cannot be known at compilation tim --> $DIR/unsized6.rs:9:9 | LL | fn f1(x: &X) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y: Y; | ^ doesn't have a size known at compile-time @@ -14,7 +14,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:7:12 | LL | fn f1(x: &X) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | let _: W; // <-- this is OK, no bindings created, no initializer. LL | let _: (isize, (X, isize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -25,7 +25,7 @@ error[E0277]: the size for values of type `Z` cannot be known at compilation tim --> $DIR/unsized6.rs:11:12 | LL | fn f1(x: &X) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y: (isize, (Z, usize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -36,7 +36,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:15:9 | LL | fn f2(x: &X) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | let y: X; | ^ doesn't have a size known at compile-time | @@ -47,7 +47,7 @@ error[E0277]: the size for values of type `Y` cannot be known at compilation tim --> $DIR/unsized6.rs:17:12 | LL | fn f2(x: &X) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y: (isize, (Y, isize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -58,7 +58,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:22:9 | LL | fn f3(x1: Box, x2: Box, x3: Box) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | let y: X = *x1; | ^ doesn't have a size known at compile-time | @@ -69,7 +69,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:24:9 | LL | fn f3(x1: Box, x2: Box, x3: Box) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y = *x2; | ^ doesn't have a size known at compile-time @@ -81,7 +81,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:26:10 | LL | fn f3(x1: Box, x2: Box, x3: Box) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | let (y, z) = (*x3, 4); | ^ doesn't have a size known at compile-time @@ -93,7 +93,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:30:9 | LL | fn f4(x1: Box, x2: Box, x3: Box) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` LL | let y: X = *x1; | ^ doesn't have a size known at compile-time | @@ -104,7 +104,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:32:9 | LL | fn f4(x1: Box, x2: Box, x3: Box) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | let y = *x2; | ^ doesn't have a size known at compile-time @@ -116,7 +116,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim --> $DIR/unsized6.rs:34:10 | LL | fn f4(x1: Box, x2: Box, x3: Box) { - | - this type parameter needs to be `Sized` + | - this type parameter needs to be `std::marker::Sized` ... LL | let (y, z) = (*x3, 4); | ^ doesn't have a size known at compile-time @@ -130,7 +130,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim LL | fn g1(x: X) {} | - ^ doesn't have a size known at compile-time | | - | this type parameter needs to be `Sized` + | this type parameter needs to be `std::marker::Sized` | = help: unsized fn params are gated as an unstable feature help: function arguments must have a statically known size, borrowed types always have a known size @@ -144,7 +144,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim LL | fn g2(x: X) {} | - ^ doesn't have a size known at compile-time | | - | this type parameter needs to be `Sized` + | this type parameter needs to be `std::marker::Sized` | = help: unsized fn params are gated as an unstable feature help: function arguments must have a statically known size, borrowed types always have a known size diff --git a/src/test/ui/unsized7.stderr b/src/test/ui/unsized7.stderr index 5f9a2604ed5..7dbddd4ed24 100644 --- a/src/test/ui/unsized7.stderr +++ b/src/test/ui/unsized7.stderr @@ -7,7 +7,7 @@ LL | trait T1 { LL | impl T1 for S3 { | - ^^^^^ doesn't have a size known at compile-time | | - | this type parameter needs to be `Sized` + | this type parameter needs to be `std::marker::Sized` | help: consider relaxing the implicit `Sized` restriction | diff --git a/src/test/ui/wf/wf-enum-bound.stderr b/src/test/ui/wf/wf-enum-bound.stderr index e7bc8582251..7819110dd98 100644 --- a/src/test/ui/wf/wf-enum-bound.stderr +++ b/src/test/ui/wf/wf-enum-bound.stderr @@ -9,8 +9,8 @@ LL | where T: ExtraCopy | help: consider further restricting type parameter `U` | -LL | where T: ExtraCopy, U: Copy - | ^^^^^^^^^ +LL | where T: ExtraCopy, U: std::marker::Copy + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-enum-fields-struct-variant.stderr b/src/test/ui/wf/wf-enum-fields-struct-variant.stderr index c97ce53885b..4bfb2413fe9 100644 --- a/src/test/ui/wf/wf-enum-fields-struct-variant.stderr +++ b/src/test/ui/wf/wf-enum-fields-struct-variant.stderr @@ -9,8 +9,8 @@ LL | f: IsCopy | help: consider restricting type parameter `A` | -LL | enum AnotherEnum { - | ^^^^^^ +LL | enum AnotherEnum { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-enum-fields.stderr b/src/test/ui/wf/wf-enum-fields.stderr index 85da1bf5839..c8a75afbab7 100644 --- a/src/test/ui/wf/wf-enum-fields.stderr +++ b/src/test/ui/wf/wf-enum-fields.stderr @@ -9,8 +9,8 @@ LL | SomeVariant(IsCopy) | help: consider restricting type parameter `A` | -LL | enum SomeEnum { - | ^^^^^^ +LL | enum SomeEnum { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr index 22598e58bd7..e463e3db887 100644 --- a/src/test/ui/wf/wf-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-fn-where-clause.stderr @@ -9,8 +9,8 @@ LL | fn foo() where T: ExtraCopy | help: consider further restricting type parameter `U` | -LL | fn foo() where T: ExtraCopy, U: Copy - | ^^^^^^^^^ +LL | fn foo() where T: ExtraCopy, U: std::marker::Copy + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `(dyn Copy + 'static)` cannot be known at compilation time --> $DIR/wf-fn-where-clause.rs:12:16 diff --git a/src/test/ui/wf/wf-in-fn-arg.stderr b/src/test/ui/wf/wf-in-fn-arg.stderr index d6010d1d79e..9687658feba 100644 --- a/src/test/ui/wf/wf-in-fn-arg.stderr +++ b/src/test/ui/wf/wf-in-fn-arg.stderr @@ -9,8 +9,8 @@ LL | fn bar(_: &MustBeCopy) | help: consider restricting type parameter `T` | -LL | fn bar(_: &MustBeCopy) - | ^^^^^^ +LL | fn bar(_: &MustBeCopy) + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-in-fn-ret.stderr b/src/test/ui/wf/wf-in-fn-ret.stderr index c22252657f1..f9a962578e6 100644 --- a/src/test/ui/wf/wf-in-fn-ret.stderr +++ b/src/test/ui/wf/wf-in-fn-ret.stderr @@ -9,8 +9,8 @@ LL | fn bar() -> MustBeCopy | help: consider restricting type parameter `T` | -LL | fn bar() -> MustBeCopy - | ^^^^^^ +LL | fn bar() -> MustBeCopy + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-in-fn-type-arg.stderr b/src/test/ui/wf/wf-in-fn-type-arg.stderr index 6d249f5f918..33300b39642 100644 --- a/src/test/ui/wf/wf-in-fn-type-arg.stderr +++ b/src/test/ui/wf/wf-in-fn-type-arg.stderr @@ -9,8 +9,8 @@ LL | x: fn(MustBeCopy) | help: consider restricting type parameter `T` | -LL | struct Bar { - | ^^^^^^ +LL | struct Bar { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-in-fn-type-ret.stderr b/src/test/ui/wf/wf-in-fn-type-ret.stderr index 30ff365b116..1ffc47e6d82 100644 --- a/src/test/ui/wf/wf-in-fn-type-ret.stderr +++ b/src/test/ui/wf/wf-in-fn-type-ret.stderr @@ -9,8 +9,8 @@ LL | x: fn() -> MustBeCopy | help: consider restricting type parameter `T` | -LL | struct Foo { - | ^^^^^^ +LL | struct Foo { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-in-fn-where-clause.stderr b/src/test/ui/wf/wf-in-fn-where-clause.stderr index 64e9694c0e1..7cb9af11d79 100644 --- a/src/test/ui/wf/wf-in-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-in-fn-where-clause.stderr @@ -9,8 +9,8 @@ LL | where T: MustBeCopy | help: consider further restricting type parameter `U` | -LL | where T: MustBeCopy, U: Copy - | ^^^^^^^^^ +LL | where T: MustBeCopy, U: std::marker::Copy + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-in-obj-type-trait.stderr b/src/test/ui/wf/wf-in-obj-type-trait.stderr index 55ea08ccbe7..8606eabf59c 100644 --- a/src/test/ui/wf/wf-in-obj-type-trait.stderr +++ b/src/test/ui/wf/wf-in-obj-type-trait.stderr @@ -9,8 +9,8 @@ LL | x: dyn Object> | help: consider restricting type parameter `T` | -LL | struct Bar { - | ^^^^^^ +LL | struct Bar { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr index 7bbdd4bcf24..8e0ce557e6b 100644 --- a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr +++ b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr @@ -9,8 +9,8 @@ LL | fn foo(self) where T: ExtraCopy | help: consider restricting type parameter `U` | -LL | impl Foo { - | ^^^^^^ +LL | impl Foo { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-inherent-impl-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-where-clause.stderr index 2a44e1cdc71..bf8077ba88f 100644 --- a/src/test/ui/wf/wf-inherent-impl-where-clause.stderr +++ b/src/test/ui/wf/wf-inherent-impl-where-clause.stderr @@ -9,8 +9,8 @@ LL | impl Foo where T: ExtraCopy | help: consider further restricting type parameter `U` | -LL | impl Foo where T: ExtraCopy, U: Copy - | ^^^^^^^^^ +LL | impl Foo where T: ExtraCopy, U: std::marker::Copy + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-struct-bound.stderr b/src/test/ui/wf/wf-struct-bound.stderr index 948693ac6f8..e85f3591438 100644 --- a/src/test/ui/wf/wf-struct-bound.stderr +++ b/src/test/ui/wf/wf-struct-bound.stderr @@ -9,8 +9,8 @@ LL | where T: ExtraCopy | help: consider further restricting type parameter `U` | -LL | where T: ExtraCopy, U: Copy - | ^^^^^^^^^ +LL | where T: ExtraCopy, U: std::marker::Copy + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-struct-field.stderr b/src/test/ui/wf/wf-struct-field.stderr index 04e62a7fcb7..62ef6bb60c7 100644 --- a/src/test/ui/wf/wf-struct-field.stderr +++ b/src/test/ui/wf/wf-struct-field.stderr @@ -9,8 +9,8 @@ LL | data: IsCopy | help: consider restricting type parameter `A` | -LL | struct SomeStruct { - | ^^^^^^ +LL | struct SomeStruct { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-associated-type-bound.stderr b/src/test/ui/wf/wf-trait-associated-type-bound.stderr index 166e3626f09..51adfdb6bd2 100644 --- a/src/test/ui/wf/wf-trait-associated-type-bound.stderr +++ b/src/test/ui/wf/wf-trait-associated-type-bound.stderr @@ -9,8 +9,8 @@ LL | type Type1: ExtraCopy; | help: consider restricting type parameter `T` | -LL | trait SomeTrait { - | ^^^^^^ +LL | trait SomeTrait { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-bound.stderr b/src/test/ui/wf/wf-trait-bound.stderr index abb97adcfd4..c9e818f8e7d 100644 --- a/src/test/ui/wf/wf-trait-bound.stderr +++ b/src/test/ui/wf/wf-trait-bound.stderr @@ -9,8 +9,8 @@ LL | where T: ExtraCopy | help: consider further restricting type parameter `U` | -LL | where T: ExtraCopy, U: Copy - | ^^^^^^^^^ +LL | where T: ExtraCopy, U: std::marker::Copy + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-superbound.stderr b/src/test/ui/wf/wf-trait-superbound.stderr index db337a7c6d0..69269835271 100644 --- a/src/test/ui/wf/wf-trait-superbound.stderr +++ b/src/test/ui/wf/wf-trait-superbound.stderr @@ -9,8 +9,8 @@ LL | trait SomeTrait: ExtraCopy { | help: consider restricting type parameter `T` | -LL | trait SomeTrait: ExtraCopy { - | ^^^^^^ +LL | trait SomeTrait: ExtraCopy { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr index 916c6dc6d53..356ba347cc3 100644 --- a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr +++ b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr @@ -9,8 +9,8 @@ LL | require_copy(self.x); | help: consider restricting type parameter `T` | -LL | impl Foo { - | ^^^^^^ +LL | impl Foo { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr index 8814018964a..d84242cfe12 100644 --- a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr +++ b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr @@ -9,8 +9,8 @@ LL | require_copy(self.x); | help: consider restricting type parameter `T` | -LL | impl Foo for Bar { - | ^^^^^^ +LL | impl Foo for Bar { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error From 5773e516787a90df4ed014cd20eed0226a1f63cd Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 31 Mar 2021 09:19:29 +0200 Subject: [PATCH 228/370] Inline a few methods --- compiler/rustc_data_structures/src/memmap.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_data_structures/src/memmap.rs b/compiler/rustc_data_structures/src/memmap.rs index 0c24f227cc9..29e999efeb1 100644 --- a/compiler/rustc_data_structures/src/memmap.rs +++ b/compiler/rustc_data_structures/src/memmap.rs @@ -13,6 +13,7 @@ pub struct Mmap(Vec); #[cfg(not(target_arch = "wasm32"))] impl Mmap { + #[inline] pub unsafe fn map(file: File) -> io::Result { memmap2::Mmap::map(&file).map(Mmap) } @@ -20,6 +21,7 @@ impl Mmap { #[cfg(target_arch = "wasm32")] impl Mmap { + #[inline] pub unsafe fn map(mut file: File) -> io::Result { use std::io::Read; @@ -32,6 +34,7 @@ impl Mmap { impl Deref for Mmap { type Target = [u8]; + #[inline] fn deref(&self) -> &[u8] { &*self.0 } From c3ec0add8b65e50b6c549353823c7652c354ea2b Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Mon, 1 Feb 2021 12:02:31 +0000 Subject: [PATCH 229/370] Add allocation information to undefined behaviour errors. --- .../rustc_mir/src/const_eval/eval_queries.rs | 10 +++ .../invalid-patterns.stderr | 12 +++ src/test/ui/consts/const-err4.stderr | 3 + ...nst-pointer-values-in-various-types.stderr | 27 +++++++ .../heap/alloc_intrinsic_uninit.stderr | 3 + .../consts/const-eval/ref_to_int_match.stderr | 3 + .../consts/const-eval/transmute-const.stderr | 3 + src/test/ui/consts/const-eval/ub-enum.stderr | 39 ++++++++++ .../ui/consts/const-eval/ub-int-array.stderr | 9 +++ .../ui/consts/const-eval/ub-nonnull.stderr | 18 +++++ .../ui/consts/const-eval/ub-ref-ptr.stderr | 33 ++++++++ .../ui/consts/const-eval/ub-uninhabit.stderr | 5 ++ .../ui/consts/const-eval/ub-upvars.stderr | 3 + .../ui/consts/const-eval/ub-wide-ptr.stderr | 78 +++++++++++++++++++ .../const-eval/union-const-eval-field.stderr | 3 + .../ui/consts/const-eval/union-ice.stderr | 11 +++ src/test/ui/consts/const-eval/union-ub.stderr | 6 ++ .../validate_uninhabited_zsts.stderr | 1 + src/test/ui/consts/const-points-to-static.rs | 3 +- .../ui/consts/const-points-to-static.stderr | 3 + src/test/ui/consts/issue-63952.stderr | 3 + src/test/ui/consts/issue-79690.stderr | 3 + .../miri_unleashed/const_refers_to_static2.rs | 6 +- .../const_refers_to_static2.stderr | 16 +++- .../const_refers_to_static_cross_crate.rs | 6 +- .../const_refers_to_static_cross_crate.stderr | 56 +++++++------ .../mutable_references_err.stderr | 9 +++ src/test/ui/consts/std/alloc.stderr | 3 + .../ui/consts/validate_never_arrays.stderr | 9 +++ 29 files changed, 351 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index fa234ff5feb..d51adc8864d 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -5,6 +5,7 @@ use crate::interpret::{ Immediate, InternKind, InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, Scalar, ScalarMaybeUninit, StackPopCleanup, }; +use crate::util::pretty::display_allocation; use rustc_errors::ErrorReported; use rustc_hir::def::DefKind; @@ -360,6 +361,15 @@ pub fn eval_to_allocation_raw_provider<'tcx>( "it is undefined behavior to use this value", |mut diag| { diag.note(note_on_undefined_behavior_error()); + diag.note(&format!( + "the raw bytes of the constant ({}", + display_allocation( + *ecx.tcx, + ecx.tcx + .global_alloc(mplace.ptr.assert_ptr().alloc_id) + .unwrap_memory() + ) + )); diag.emit(); }, )) diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr b/src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr index 04f716fa733..38c126319b2 100644 --- a/src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr +++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr @@ -29,6 +29,9 @@ LL | get_flag::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + __ __ __ __ │ ░░░░ + } error[E0080]: it is undefined behavior to use this value --> $DIR/invalid-patterns.rs:39:14 @@ -37,6 +40,9 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x42, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 42 │ B + } error[E0080]: it is undefined behavior to use this value --> $DIR/invalid-patterns.rs:41:14 @@ -45,6 +51,9 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x42, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 42 │ B + } error[E0080]: it is undefined behavior to use this value --> $DIR/invalid-patterns.rs:41:47 @@ -53,6 +62,9 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + __ __ __ __ │ ░░░░ + } error: aborting due to 8 previous errors diff --git a/src/test/ui/consts/const-err4.stderr b/src/test/ui/consts/const-err4.stderr index 081b09e3300..e9f0ad7bc8b 100644 --- a/src/test/ui/consts/const-err4.stderr +++ b/src/test/ui/consts/const-err4.stderr @@ -5,6 +5,9 @@ LL | Boo = [unsafe { Foo { b: () }.a }; 4][3], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + __ __ __ __ __ __ __ __ │ ░░░░░░░░ + } error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr index ccd13784784..a1f806448bb 100644 --- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr @@ -5,6 +5,9 @@ LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc2, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc2────────╼ │ ╾──────╼ + } error: any use of this value will cause an error --> $DIR/const-pointer-values-in-various-types.rs:28:43 @@ -47,6 +50,9 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc18, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc18───────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:43:5 @@ -55,6 +61,9 @@ LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.u | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░ + } error: any use of this value will cause an error --> $DIR/const-pointer-values-in-various-types.rs:46:43 @@ -96,6 +105,9 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc38, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc38───────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:61:5 @@ -104,6 +116,9 @@ LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.i | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░ + } error: any use of this value will cause an error --> $DIR/const-pointer-values-in-various-types.rs:64:45 @@ -123,6 +138,9 @@ LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.flo | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc50, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc50───────╼ │ ╾──────╼ + } error: any use of this value will cause an error --> $DIR/const-pointer-values-in-various-types.rs:71:47 @@ -186,6 +204,9 @@ LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc71, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc71───────╼ │ ╾──────╼ + } error: any use of this value will cause an error --> $DIR/const-pointer-values-in-various-types.rs:94:43 @@ -238,6 +259,9 @@ LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc86, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc86───────╼ │ ╾──────╼ + } error: any use of this value will cause an error --> $DIR/const-pointer-values-in-various-types.rs:113:43 @@ -268,6 +292,9 @@ LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc95, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc95───────╼ │ ╾──────╼ + } error: any use of this value will cause an error --> $DIR/const-pointer-values-in-various-types.rs:124:43 diff --git a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.stderr b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.stderr index 866f877f54d..b2bfdf14696 100644 --- a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.stderr +++ b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.stderr @@ -5,6 +5,9 @@ LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at ., but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc1────────╼ │ ╾──────╼ + } error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.stderr index cb0ba5d9929..843dd5662e0 100644 --- a/src/test/ui/consts/const-eval/ref_to_int_match.stderr +++ b/src/test/ui/consts/const-eval/ref_to_int_match.stderr @@ -5,6 +5,9 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc2, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc2────────╼ │ ╾──────╼ + } error: could not evaluate constant pattern --> $DIR/ref_to_int_match.rs:7:14 diff --git a/src/test/ui/consts/const-eval/transmute-const.stderr b/src/test/ui/consts/const-eval/transmute-const.stderr index 46a40498277..4245c3ea5d0 100644 --- a/src/test/ui/consts/const-eval/transmute-const.stderr +++ b/src/test/ui/consts/const-eval/transmute-const.stderr @@ -5,6 +5,9 @@ LL | static FOO: bool = unsafe { mem::transmute(3u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 03 │ . + } error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/ub-enum.stderr b/src/test/ui/consts/const-eval/ub-enum.stderr index db95b996c18..a84f38fe1dc 100644 --- a/src/test/ui/consts/const-eval/ub-enum.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.stderr @@ -5,6 +5,9 @@ LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000001 at ., but expected a valid enum tag | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + 01 00 00 00 00 00 00 00 │ ........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:27:1 @@ -13,6 +16,9 @@ LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc8 at ., but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc8────────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:30:1 @@ -21,6 +27,9 @@ LL | const BAD_ENUM_WRAPPED: Wrap = unsafe { mem::transmute(&1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc12 at .0., but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc12───────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:42:1 @@ -29,6 +38,9 @@ LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000000 at ., but expected a valid enum tag | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + 00 00 00 00 00 00 00 00 │ ........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:44:1 @@ -37,6 +49,9 @@ LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc18 at ., but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc18───────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:47:1 @@ -45,6 +60,9 @@ LL | const BAD_ENUM2_WRAPPED: Wrap = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc22 at .0., but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc22───────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:56:1 @@ -53,6 +71,9 @@ LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at ., but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + __ __ __ __ __ __ __ __ │ ░░░░░░░░ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:60:1 @@ -61,6 +82,9 @@ LL | const BAD_ENUM2_OPTION_PTR: Option = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc28 at ., but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc28───────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:77:1 @@ -69,6 +93,9 @@ LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at ..0 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 01 │ . + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:79:1 @@ -77,6 +104,9 @@ LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Never at ..0 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 03 │ . + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:87:1 @@ -85,6 +115,9 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0xffffffff at ..0.1, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + 78 00 00 00 ff ff ff ff │ x....... + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:92:1 @@ -93,6 +126,9 @@ LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Never at ..0.1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + 00 00 00 00 00 00 00 00 │ ........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:94:1 @@ -101,6 +137,9 @@ LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at ..0.1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + 00 00 00 00 00 00 00 00 │ ........ + } error: aborting due to 13 previous errors diff --git a/src/test/ui/consts/const-eval/ub-int-array.stderr b/src/test/ui/consts/const-eval/ub-int-array.stderr index 92f654847df..c13271a1e5e 100644 --- a/src/test/ui/consts/const-eval/ub-int-array.stderr +++ b/src/test/ui/consts/const-eval/ub-int-array.stderr @@ -11,6 +11,9 @@ LL | | }; | |__^ type validation failed: encountered uninitialized bytes at [0] | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 12, align: 4) { + __ __ __ __ 01 00 00 00 02 00 00 00 │ ░░░░........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-int-array.rs:23:1 @@ -25,6 +28,9 @@ LL | | }; | |__^ type validation failed: encountered uninitialized bytes at [1] | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 12, align: 4) { + 00 00 00 00 01 __ 01 01 02 02 __ 02 │ .....░....░. + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-int-array.rs:43:1 @@ -39,6 +45,9 @@ LL | | }; | |__^ type validation failed: encountered uninitialized bytes at [2] | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 12, align: 4) { + 00 00 00 00 01 01 01 01 02 02 02 __ │ ...........░ + } error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/ub-nonnull.stderr b/src/test/ui/consts/const-eval/ub-nonnull.stderr index 94496b77fe7..2cd55500005 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.stderr @@ -5,6 +5,9 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + 00 00 00 00 00 00 00 00 │ ........ + } error: any use of this value will cause an error --> $DIR/ub-nonnull.rs:18:30 @@ -34,6 +37,9 @@ LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 00 │ . + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-nonnull.rs:25:1 @@ -42,6 +48,9 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + 00 00 00 00 00 00 00 00 │ ........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-nonnull.rs:33:1 @@ -50,6 +59,9 @@ LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at .0, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + __ │ ░ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-nonnull.rs:41:1 @@ -58,6 +70,9 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 10..=30 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 2a 00 00 00 │ *... + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-nonnull.rs:47:1 @@ -66,6 +81,9 @@ LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 20, but expected something less or equal to 10, or greater or equal to 30 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 14 00 00 00 │ .... + } error: aborting due to 7 previous errors diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.stderr index 7d76c5cb43f..25e69134621 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.stderr @@ -5,6 +5,9 @@ LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered an unaligned reference (required 2 byte alignment but found 1) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc2────────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref-ptr.rs:16:1 @@ -13,6 +16,9 @@ LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered an unaligned box (required 2 byte alignment but found 1) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc6────────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref-ptr.rs:20:1 @@ -21,6 +27,9 @@ LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a NULL reference | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + 00 00 00 00 00 00 00 00 │ ........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref-ptr.rs:23:1 @@ -29,6 +38,9 @@ LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a NULL box | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + 00 00 00 00 00 00 00 00 │ ........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref-ptr.rs:29:1 @@ -37,6 +49,9 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc14, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc14───────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref-ptr.rs:32:1 @@ -45,6 +60,9 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at ., but expected plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc20───────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref-ptr.rs:35:1 @@ -53,6 +71,9 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at ., but expected plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc25───────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref-ptr.rs:38:1 @@ -61,6 +82,9 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (created from integer) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + 39 05 00 00 00 00 00 00 │ 9....... + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref-ptr.rs:41:1 @@ -69,6 +93,9 @@ LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (created from integer) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + 39 05 00 00 00 00 00 00 │ 9....... + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref-ptr.rs:44:1 @@ -77,6 +104,9 @@ LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized raw pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + __ __ __ __ __ __ __ __ │ ░░░░░░░░ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-ref-ptr.rs:46:1 @@ -85,6 +115,9 @@ LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a function pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + __ __ __ __ __ __ __ __ │ ░░░░░░░░ + } error: aborting due to 11 previous errors diff --git a/src/test/ui/consts/const-eval/ub-uninhabit.stderr b/src/test/ui/consts/const-eval/ub-uninhabit.stderr index 16f5316a442..af8cda0e4d3 100644 --- a/src/test/ui/consts/const-eval/ub-uninhabit.stderr +++ b/src/test/ui/consts/const-eval/ub-uninhabit.stderr @@ -5,6 +5,7 @@ LL | const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Bar | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 0, align: 1) {} error[E0080]: it is undefined behavior to use this value --> $DIR/ub-uninhabit.rs:17:1 @@ -13,6 +14,9 @@ LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Bar at . | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + 01 00 00 00 00 00 00 00 │ ........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-uninhabit.rs:20:1 @@ -21,6 +25,7 @@ LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Bar at [0] | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 0, align: 1) {} error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/ub-upvars.stderr b/src/test/ui/consts/const-eval/ub-upvars.stderr index afd6c9035ca..23a564edff1 100644 --- a/src/test/ui/consts/const-eval/ub-upvars.stderr +++ b/src/test/ui/consts/const-eval/ub-upvars.stderr @@ -9,6 +9,9 @@ LL | | }; | |__^ type validation failed: encountered a NULL reference at ... | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────alloc2────────╼ ╾───────alloc3────────╼ │ ╾──────╼╾──────╼ + } error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr index be9ec16a06f..ac26630a54f 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr @@ -5,6 +5,9 @@ LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (going beyond the bounds of its allocation) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────allocN────────╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:39:1 @@ -13,6 +16,9 @@ LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, us | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object at .0 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────allocN───────╼ ff ff ff ff ff ff ff ff │ ╾──────╼........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:42:1 @@ -21,6 +27,9 @@ LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────allocN───────╼ ╾───────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:45:1 @@ -29,6 +38,9 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────allocN───────╼ ╾───────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:47:1 @@ -37,6 +49,9 @@ LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize: | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────allocN───────╼ ff ff ff ff ff ff ff ff │ ╾──────╼........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:51:1 @@ -45,6 +60,9 @@ LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit: | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in `str` at . | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────allocN───────╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:54:1 @@ -53,6 +71,9 @@ LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUni | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in `str` at ..0 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────allocN───────╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:61:1 @@ -65,6 +86,9 @@ LL | | }; | |__^ type validation failed: encountered uninitialized reference | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:67:1 @@ -73,6 +97,9 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (going beyond the bounds of its allocation) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────allocN───────╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:70:1 @@ -81,6 +108,9 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────allocN───────╼ ╾───────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:73:1 @@ -89,6 +119,9 @@ LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999us | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (going beyond the bounds of its allocation) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────allocN───────╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:76:1 @@ -97,6 +130,9 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────allocN───────╼ ╾───────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:80:1 @@ -105,6 +141,9 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at .[0], but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────allocN───────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:86:1 @@ -113,6 +152,9 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at ..0, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────allocN───────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:89:1 @@ -121,6 +163,9 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at ..1[0], but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────allocN───────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:96:1 @@ -133,6 +178,9 @@ LL | | }; | |__^ type validation failed: encountered uninitialized raw pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ ░░░░░░░░░░░░░░░░ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:104:1 @@ -141,6 +189,9 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W(( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable at .0 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:107:1 @@ -149,6 +200,9 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W(( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable at .0 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:110:1 @@ -157,6 +211,9 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling vtable pointer in wide pointer at .0 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾──────allocN───────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:112:1 @@ -165,6 +222,9 @@ LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered unaligned vtable pointer in wide pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:114:1 @@ -173,6 +233,9 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:116:1 @@ -181,6 +244,9 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:118:1 @@ -189,6 +255,9 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::trans | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function) at .0 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:122:1 @@ -197,6 +266,9 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at .., but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:126:1 @@ -205,6 +277,9 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling vtable pointer in wide pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾──────allocN───────╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:128:1 @@ -213,6 +288,9 @@ LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transm | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: could not evaluate static initializer --> $DIR/ub-wide-ptr.rs:134:5 diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.stderr b/src/test/ui/consts/const-eval/union-const-eval-field.stderr index 9193bd9dea1..e5a107ff011 100644 --- a/src/test/ui/consts/const-eval/union-const-eval-field.stderr +++ b/src/test/ui/consts/const-eval/union-const-eval-field.stderr @@ -5,6 +5,9 @@ LL | const FIELD3: Field3 = unsafe { UNION.field3 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + __ __ __ __ __ __ __ __ │ ░░░░░░░░ + } error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/union-ice.stderr b/src/test/ui/consts/const-eval/union-ice.stderr index 2545167aa02..6d44b3c8b28 100644 --- a/src/test/ui/consts/const-eval/union-ice.stderr +++ b/src/test/ui/consts/const-eval/union-ice.stderr @@ -5,6 +5,9 @@ LL | const FIELD3: Field3 = unsafe { UNION.field3 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + __ __ __ __ __ __ __ __ │ ░░░░░░░░ + } error[E0080]: it is undefined behavior to use this value --> $DIR/union-ice.rs:16:1 @@ -16,6 +19,9 @@ LL | | }; | |__^ type validation failed: encountered uninitialized bytes at .b, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + __ __ __ __ __ __ __ __ 2a __ __ __ __ __ __ __ │ ░░░░░░░░*░░░░░░░ + } error[E0080]: it is undefined behavior to use this value --> $DIR/union-ice.rs:26:1 @@ -30,6 +36,11 @@ LL | | }; | |__^ type validation failed: encountered uninitialized bytes at .b[1] | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 40, align: 8) { + 0x00 │ 15 00 00 00 00 00 00 00 __ __ __ __ __ __ __ __ │ ........░░░░░░░░ + 0x10 │ 17 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 │ ................ + 0x20 │ 2a __ __ __ __ __ __ __ │ *░░░░░░░ + } error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/union-ub.stderr b/src/test/ui/consts/const-eval/union-ub.stderr index e8869d0d76c..b54e15bad9b 100644 --- a/src/test/ui/consts/const-eval/union-ub.stderr +++ b/src/test/ui/consts/const-eval/union-ub.stderr @@ -5,6 +5,9 @@ LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x2a, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 2a │ * + } error[E0080]: it is undefined behavior to use this value --> $DIR/union-ub.rs:34:1 @@ -13,6 +16,9 @@ LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + __ │ ░ + } error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr index 3f22fac11f6..e25abab7e37 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr @@ -26,6 +26,7 @@ LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Empty at [0] | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 0, align: 1) {} warning: the type `!` does not permit zero-initialization --> $DIR/validate_uninhabited_zsts.rs:5:14 diff --git a/src/test/ui/consts/const-points-to-static.rs b/src/test/ui/consts/const-points-to-static.rs index 7087b6e6a67..e5f0e3f5dae 100644 --- a/src/test/ui/consts/const-points-to-static.rs +++ b/src/test/ui/consts/const-points-to-static.rs @@ -5,7 +5,8 @@ const TEST: &u8 = &MY_STATIC; //~^ ERROR it is undefined behavior to use this value //~| NOTE encountered a reference pointing to a static variable -//~| NOTE +//~| NOTE undefined behavior +//~| NOTE the raw bytes of the constant (size: 8, align: 8) static MY_STATIC: u8 = 4; diff --git a/src/test/ui/consts/const-points-to-static.stderr b/src/test/ui/consts/const-points-to-static.stderr index 465537fb3d5..13e50eb2481 100644 --- a/src/test/ui/consts/const-points-to-static.stderr +++ b/src/test/ui/consts/const-points-to-static.stderr @@ -5,6 +5,9 @@ LL | const TEST: &u8 = &MY_STATIC; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a reference pointing to a static variable | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc0────────╼ │ ╾──────╼ + } warning: skipping const checks | diff --git a/src/test/ui/consts/issue-63952.stderr b/src/test/ui/consts/issue-63952.stderr index 503c5706fa2..c469619f1b7 100644 --- a/src/test/ui/consts/issue-63952.stderr +++ b/src/test/ui/consts/issue-63952.stderr @@ -11,6 +11,9 @@ LL | | }; | |__^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────alloc3────────╼ ff ff ff ff ff ff ff ff │ ╾──────╼........ + } error: aborting due to previous error diff --git a/src/test/ui/consts/issue-79690.stderr b/src/test/ui/consts/issue-79690.stderr index ca56ff22056..6930c02ad5f 100644 --- a/src/test/ui/consts/issue-79690.stderr +++ b/src/test/ui/consts/issue-79690.stderr @@ -5,6 +5,9 @@ LL | const G: Fat = unsafe { Transmute { t: FOO }.u }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered (potentially part of) a pointer at .1..size.foo, but expected plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────alloc2────────╼ ╾───────alloc3────────╼ │ ╾──────╼╾──────╼ + } error: aborting due to previous error diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.rs b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.rs index b5db685ef2c..7ac2d847d3d 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.rs +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.rs @@ -9,7 +9,8 @@ use std::sync::atomic::Ordering; const REF_INTERIOR_MUT: &usize = { //~ ERROR undefined behavior to use this value //~| NOTE encountered a reference pointing to a static variable -//~| NOTE +//~| NOTE undefined behavior +//~| NOTE the raw bytes of the constant static FOO: AtomicUsize = AtomicUsize::new(0); unsafe { &*(&FOO as *const _ as *const usize) } }; @@ -17,7 +18,8 @@ const REF_INTERIOR_MUT: &usize = { //~ ERROR undefined behavior to use this valu // ok some day perhaps const READ_IMMUT: &usize = { //~ ERROR it is undefined behavior to use this value //~| NOTE encountered a reference pointing to a static variable -//~| NOTE +//~| NOTE undefined behavior +//~| NOTE the raw bytes of the constant static FOO: usize = 0; &FOO }; diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.stderr index 2e40b38dac7..b3efac1bd36 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.stderr @@ -4,40 +4,48 @@ error[E0080]: it is undefined behavior to use this value LL | / const REF_INTERIOR_MUT: &usize = { LL | | LL | | +LL | | LL | | static FOO: AtomicUsize = AtomicUsize::new(0); LL | | unsafe { &*(&FOO as *const _ as *const usize) } LL | | }; | |__^ type validation failed: encountered a reference pointing to a static variable | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc0────────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static2.rs:18:1 + --> $DIR/const_refers_to_static2.rs:19:1 | LL | / const READ_IMMUT: &usize = { LL | | LL | | +LL | | LL | | static FOO: usize = 0; LL | | &FOO LL | | }; | |__^ type validation failed: encountered a reference pointing to a static variable | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc1────────╼ │ ╾──────╼ + } warning: skipping const checks | help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static2.rs:14:18 + --> $DIR/const_refers_to_static2.rs:15:18 | LL | unsafe { &*(&FOO as *const _ as *const usize) } | ^^^ help: skipping check for `const_raw_ptr_deref` feature - --> $DIR/const_refers_to_static2.rs:14:14 + --> $DIR/const_refers_to_static2.rs:15:14 | LL | unsafe { &*(&FOO as *const _ as *const usize) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static2.rs:22:6 + --> $DIR/const_refers_to_static2.rs:24:6 | LL | &FOO | ^^^ diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs index 7bbe9c87705..2d32c7ea39e 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs @@ -10,13 +10,15 @@ extern crate static_cross_crate; // Allowing this would be a disaster for pattern matching, we could violate exhaustiveness checking! const SLICE_MUT: &[u8; 1] = { //~ ERROR undefined behavior to use this value //~| NOTE encountered a reference pointing to a static variable -//~| NOTE +//~| NOTE undefined behavior +//~| NOTE the raw bytes of the constant unsafe { &static_cross_crate::ZERO } }; const U8_MUT: &u8 = { //~ ERROR undefined behavior to use this value //~| NOTE encountered a reference pointing to a static variable -//~| NOTE +//~| NOTE undefined behavior +//~| NOTE the raw bytes of the constant unsafe { &static_cross_crate::ZERO[0] } }; diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr index a9d6fde6c05..d6cfa6e023b 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr @@ -4,38 +4,46 @@ error[E0080]: it is undefined behavior to use this value LL | / const SLICE_MUT: &[u8; 1] = { LL | | LL | | +LL | | LL | | unsafe { &static_cross_crate::ZERO } LL | | }; | |__^ type validation failed: encountered a reference pointing to a static variable | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc0────────╼ │ ╾──────╼ + } error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:44:9 + --> $DIR/const_refers_to_static_cross_crate.rs:46:9 | LL | SLICE_MUT => true, | ^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static_cross_crate.rs:17:1 + --> $DIR/const_refers_to_static_cross_crate.rs:18:1 | LL | / const U8_MUT: &u8 = { LL | | LL | | +LL | | LL | | unsafe { &static_cross_crate::ZERO[0] } LL | | }; | |__^ type validation failed: encountered a reference pointing to a static variable | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc0────────╼ │ ╾──────╼ + } error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:53:9 + --> $DIR/const_refers_to_static_cross_crate.rs:55:9 | LL | U8_MUT => true, | ^^^^^^ warning: any use of this value will cause an error - --> $DIR/const_refers_to_static_cross_crate.rs:26:15 + --> $DIR/const_refers_to_static_cross_crate.rs:28:15 | LL | / const U8_MUT2: &u8 = { LL | | unsafe { &(*static_cross_crate::ZERO_REF)[0] } @@ -48,7 +56,7 @@ LL | | }; | |__- | note: the lint level is defined here - --> $DIR/const_refers_to_static_cross_crate.rs:24:8 + --> $DIR/const_refers_to_static_cross_crate.rs:26:8 | LL | #[warn(const_err)] | ^^^^^^^^^ @@ -56,13 +64,13 @@ LL | #[warn(const_err)] = note: for more information, see issue #71800 error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:64:9 + --> $DIR/const_refers_to_static_cross_crate.rs:66:9 | LL | U8_MUT2 => true, | ^^^^^^^ warning: any use of this value will cause an error - --> $DIR/const_refers_to_static_cross_crate.rs:34:51 + --> $DIR/const_refers_to_static_cross_crate.rs:36:51 | LL | / const U8_MUT3: &u8 = { LL | | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } @@ -75,7 +83,7 @@ LL | | }; | |__- | note: the lint level is defined here - --> $DIR/const_refers_to_static_cross_crate.rs:32:8 + --> $DIR/const_refers_to_static_cross_crate.rs:34:8 | LL | #[warn(const_err)] | ^^^^^^^^^ @@ -83,31 +91,31 @@ LL | #[warn(const_err)] = note: for more information, see issue #71800 error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:72:9 + --> $DIR/const_refers_to_static_cross_crate.rs:74:9 | LL | U8_MUT3 => true, | ^^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:44:9 + --> $DIR/const_refers_to_static_cross_crate.rs:46:9 | LL | SLICE_MUT => true, | ^^^^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:53:9 + --> $DIR/const_refers_to_static_cross_crate.rs:55:9 | LL | U8_MUT => true, | ^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:64:9 + --> $DIR/const_refers_to_static_cross_crate.rs:66:9 | LL | U8_MUT2 => true, | ^^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:72:9 + --> $DIR/const_refers_to_static_cross_crate.rs:74:9 | LL | U8_MUT3 => true, | ^^^^^^^ @@ -115,57 +123,57 @@ LL | U8_MUT3 => true, warning: skipping const checks | help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:14:15 + --> $DIR/const_refers_to_static_cross_crate.rs:15:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:14:15 + --> $DIR/const_refers_to_static_cross_crate.rs:15:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:20:15 + --> $DIR/const_refers_to_static_cross_crate.rs:22:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:20:15 + --> $DIR/const_refers_to_static_cross_crate.rs:22:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:20:15 + --> $DIR/const_refers_to_static_cross_crate.rs:22:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:26:17 + --> $DIR/const_refers_to_static_cross_crate.rs:28:17 | LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:34:20 + --> $DIR/const_refers_to_static_cross_crate.rs:36:20 | LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:34:20 + --> $DIR/const_refers_to_static_cross_crate.rs:36:20 | LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:34:20 + --> $DIR/const_refers_to_static_cross_crate.rs:36:20 | LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_panic` feature - --> $DIR/const_refers_to_static_cross_crate.rs:34:77 + --> $DIR/const_refers_to_static_cross_crate.rs:36:77 | LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:34:20 + --> $DIR/const_refers_to_static_cross_crate.rs:36:20 | LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_err.stderr b/src/test/ui/consts/miri_unleashed/mutable_references_err.stderr index 0c206dd51aa..8fde2838e3f 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_references_err.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_references_err.stderr @@ -7,6 +7,9 @@ LL | | }; | |__^ type validation failed: encountered `UnsafeCell` in a `const` at .x. | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc2────────╼ │ ╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/mutable_references_err.rs:26:1 @@ -15,6 +18,9 @@ LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered `UnsafeCell` in a `const` at ...x | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────alloc6────────╼ ╾───────alloc7────────╼ │ ╾──────╼╾──────╼ + } error[E0080]: it is undefined behavior to use this value --> $DIR/mutable_references_err.rs:30:1 @@ -23,6 +29,9 @@ LL | const BLUNT: &mut i32 = &mut 42; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered mutable reference in a `const` | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + ╾───────alloc10───────╼ │ ╾──────╼ + } warning: skipping const checks | diff --git a/src/test/ui/consts/std/alloc.stderr b/src/test/ui/consts/std/alloc.stderr index 26b7a24ebfa..01f44fe4ae9 100644 --- a/src/test/ui/consts/std/alloc.stderr +++ b/src/test/ui/consts/std/alloc.stderr @@ -5,6 +5,9 @@ LL | const LAYOUT_INVALID: Layout = unsafe { Layout::from_size_align_unchecked(0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0 at .align_, but expected something greater or equal to 1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ + } error: aborting due to previous error diff --git a/src/test/ui/consts/validate_never_arrays.stderr b/src/test/ui/consts/validate_never_arrays.stderr index 77f0a2ebd40..cc558ee56d9 100644 --- a/src/test/ui/consts/validate_never_arrays.stderr +++ b/src/test/ui/consts/validate_never_arrays.stderr @@ -5,6 +5,9 @@ LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at .[0] | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 8) { + 01 00 00 00 00 00 00 00 │ ........ + } error[E0080]: it is undefined behavior to use this value --> $DIR/validate_never_arrays.rs:6:1 @@ -13,6 +16,9 @@ LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at .[0] | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 │ ................ + } error[E0080]: it is undefined behavior to use this value --> $DIR/validate_never_arrays.rs:7:1 @@ -21,6 +27,9 @@ LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at .[0] | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + 01 00 00 00 00 00 00 00 2a 00 00 00 00 00 00 00 │ ........*....... + } error: aborting due to 3 previous errors From 091433d6990c4f2e1286ba1757e584719d4038ad Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Wed, 31 Mar 2021 08:09:16 +0000 Subject: [PATCH 230/370] Rename stderr->64bit.stderr where needed. --- ...s.stderr => invalid-patterns.64bit.stderr} | 16 ++--- .../min_const_generics/invalid-patterns.rs | 1 + ...st-err4.stderr => const-err4.64bit.stderr} | 2 +- src/test/ui/consts/const-err4.rs | 1 + ...nter-values-in-various-types.64bit.stderr} | 58 +++++++++---------- .../const-pointer-values-in-various-types.rs | 1 + ...rr => alloc_intrinsic_uninit.64bit.stderr} | 2 +- .../const-eval/heap/alloc_intrinsic_uninit.rs | 1 + ...h.stderr => ref_to_int_match.64bit.stderr} | 6 +- .../ui/consts/const-eval/ref_to_int_match.rs | 1 + ...st.stderr => transmute-const.64bit.stderr} | 2 +- .../ui/consts/const-eval/transmute-const.rs | 1 + .../{ub-enum.stderr => ub-enum.64bit.stderr} | 4 +- src/test/ui/consts/const-eval/ub-enum.rs | 2 +- ...array.stderr => ub-int-array.64bit.stderr} | 0 src/test/ui/consts/const-eval/ub-int-array.rs | 2 +- ...nonnull.stderr => ub-nonnull.64bit.stderr} | 16 ++--- src/test/ui/consts/const-eval/ub-nonnull.rs | 1 + ...ref-ptr.stderr => ub-ref-ptr.64bit.stderr} | 22 +++---- src/test/ui/consts/const-eval/ub-ref-ptr.rs | 1 + ...habit.stderr => ub-uninhabit.64bit.stderr} | 6 +- src/test/ui/consts/const-eval/ub-uninhabit.rs | 1 + ...b-upvars.stderr => ub-upvars.64bit.stderr} | 2 +- src/test/ui/consts/const-eval/ub-upvars.rs | 1 + ...de-ptr.stderr => ub-wide-ptr.64bit.stderr} | 56 +++++++++--------- src/test/ui/consts/const-eval/ub-wide-ptr.rs | 1 + ...rr => union-const-eval-field.64bit.stderr} | 2 +- .../const-eval/union-const-eval-field.rs | 1 + ...nion-ice.stderr => union-ice.64bit.stderr} | 6 +- src/test/ui/consts/const-eval/union-ice.rs | 1 + ...{union-ub.stderr => union-ub.64bit.stderr} | 4 +- src/test/ui/consts/const-eval/union-ub.rs | 1 + ...=> validate_uninhabited_zsts.64bit.stderr} | 14 ++--- .../const-eval/validate_uninhabited_zsts.rs | 1 + ...rr => const-points-to-static.64bit.stderr} | 4 +- src/test/ui/consts/const-points-to-static.rs | 1 + ...-63952.stderr => issue-63952.64bit.stderr} | 2 +- src/test/ui/consts/issue-63952.rs | 1 + ...-79690.stderr => issue-79690.64bit.stderr} | 2 +- src/test/ui/consts/issue-79690.rs | 1 + ...r => const_refers_to_static2.64bit.stderr} | 10 ++-- .../miri_unleashed/const_refers_to_static2.rs | 1 + ...refers_to_static_cross_crate.64bit.stderr} | 50 ++++++++-------- .../const_refers_to_static_cross_crate.rs | 1 + ...rr => mutable_references_err.64bit.stderr} | 12 ++-- .../miri_unleashed/mutable_references_err.rs | 1 + .../std/{alloc.stderr => alloc.64bit.stderr} | 2 +- src/test/ui/consts/std/alloc.rs | 1 + ...err => validate_never_arrays.64bit.stderr} | 6 +- src/test/ui/consts/validate_never_arrays.rs | 1 + src/tools/compiletest/src/common.rs | 14 ++++- src/tools/compiletest/src/runtest.rs | 2 +- 52 files changed, 192 insertions(+), 157 deletions(-) rename src/test/ui/const-generics/min_const_generics/{invalid-patterns.stderr => invalid-patterns.64bit.stderr} (91%) rename src/test/ui/consts/{const-err4.stderr => const-err4.64bit.stderr} (96%) rename src/test/ui/consts/const-eval/{const-pointer-values-in-various-types.stderr => const-pointer-values-in-various-types.64bit.stderr} (91%) rename src/test/ui/consts/const-eval/heap/{alloc_intrinsic_uninit.stderr => alloc_intrinsic_uninit.64bit.stderr} (95%) rename src/test/ui/consts/const-eval/{ref_to_int_match.stderr => ref_to_int_match.64bit.stderr} (90%) rename src/test/ui/consts/const-eval/{transmute-const.stderr => transmute-const.64bit.stderr} (95%) rename src/test/ui/consts/const-eval/{ub-enum.stderr => ub-enum.64bit.stderr} (97%) rename src/test/ui/consts/const-eval/{ub-int-array.stderr => ub-int-array.64bit.stderr} (100%) rename src/test/ui/consts/const-eval/{ub-nonnull.stderr => ub-nonnull.64bit.stderr} (95%) rename src/test/ui/consts/const-eval/{ub-ref-ptr.stderr => ub-ref-ptr.64bit.stderr} (95%) rename src/test/ui/consts/const-eval/{ub-uninhabit.stderr => ub-uninhabit.64bit.stderr} (95%) rename src/test/ui/consts/const-eval/{ub-upvars.stderr => ub-upvars.64bit.stderr} (97%) rename src/test/ui/consts/const-eval/{ub-wide-ptr.stderr => ub-wide-ptr.64bit.stderr} (95%) rename src/test/ui/consts/const-eval/{union-const-eval-field.stderr => union-const-eval-field.64bit.stderr} (94%) rename src/test/ui/consts/const-eval/{union-ice.stderr => union-ice.64bit.stderr} (96%) rename src/test/ui/consts/const-eval/{union-ub.stderr => union-ub.64bit.stderr} (96%) rename src/test/ui/consts/const-eval/{validate_uninhabited_zsts.stderr => validate_uninhabited_zsts.64bit.stderr} (90%) rename src/test/ui/consts/{const-points-to-static.stderr => const-points-to-static.64bit.stderr} (91%) rename src/test/ui/consts/{issue-63952.stderr => issue-63952.64bit.stderr} (96%) rename src/test/ui/consts/{issue-79690.stderr => issue-79690.64bit.stderr} (96%) rename src/test/ui/consts/miri_unleashed/{const_refers_to_static2.stderr => const_refers_to_static2.64bit.stderr} (90%) rename src/test/ui/consts/miri_unleashed/{const_refers_to_static_cross_crate.stderr => const_refers_to_static_cross_crate.64bit.stderr} (80%) rename src/test/ui/consts/miri_unleashed/{mutable_references_err.stderr => mutable_references_err.64bit.stderr} (91%) rename src/test/ui/consts/std/{alloc.stderr => alloc.64bit.stderr} (97%) rename src/test/ui/consts/{validate_never_arrays.stderr => validate_never_arrays.64bit.stderr} (96%) diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr b/src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr similarity index 91% rename from src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr rename to src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr index 38c126319b2..415a53a5627 100644 --- a/src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr +++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr @@ -1,29 +1,29 @@ error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:28:21 + --> $DIR/invalid-patterns.rs:29:21 | LL | get_flag::(); | ^^^^ expected `char`, found `u8` error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:30:14 + --> $DIR/invalid-patterns.rs:31:14 | LL | get_flag::<7, 'c'>(); | ^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:32:14 + --> $DIR/invalid-patterns.rs:33:14 | LL | get_flag::<42, 0x5ad>(); | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:32:18 + --> $DIR/invalid-patterns.rs:33:18 | LL | get_flag::<42, 0x5ad>(); | ^^^^^ expected `char`, found `u8` error[E0080]: it is undefined behavior to use this value - --> $DIR/invalid-patterns.rs:37:21 + --> $DIR/invalid-patterns.rs:38:21 | LL | get_flag::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) @@ -34,7 +34,7 @@ LL | get_flag::(); } error[E0080]: it is undefined behavior to use this value - --> $DIR/invalid-patterns.rs:39:14 + --> $DIR/invalid-patterns.rs:40:14 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x42, but expected a boolean @@ -45,7 +45,7 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); } error[E0080]: it is undefined behavior to use this value - --> $DIR/invalid-patterns.rs:41:14 + --> $DIR/invalid-patterns.rs:42:14 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x42, but expected a boolean @@ -56,7 +56,7 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } error[E0080]: it is undefined behavior to use this value - --> $DIR/invalid-patterns.rs:41:47 + --> $DIR/invalid-patterns.rs:42:47 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs b/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs index a120eee67ee..682e0eced9d 100644 --- a/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs +++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth use std::mem::transmute; fn get_flag() -> Option { diff --git a/src/test/ui/consts/const-err4.stderr b/src/test/ui/consts/const-err4.64bit.stderr similarity index 96% rename from src/test/ui/consts/const-err4.stderr rename to src/test/ui/consts/const-err4.64bit.stderr index e9f0ad7bc8b..2eea3ea7096 100644 --- a/src/test/ui/consts/const-err4.stderr +++ b/src/test/ui/consts/const-err4.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/const-err4.rs:8:11 + --> $DIR/const-err4.rs:9:11 | LL | Boo = [unsafe { Foo { b: () }.a }; 4][3], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes diff --git a/src/test/ui/consts/const-err4.rs b/src/test/ui/consts/const-err4.rs index 70d9bc149d8..f0625faa801 100644 --- a/src/test/ui/consts/const-err4.rs +++ b/src/test/ui/consts/const-err4.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth #[derive(Copy, Clone)] union Foo { a: isize, diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr similarity index 91% rename from src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr rename to src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr index a1f806448bb..187e2760ad2 100644 --- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/const-pointer-values-in-various-types.rs:25:5 + --> $DIR/const-pointer-values-in-various-types.rs:26:5 | LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc2, but expected initialized plain (non-pointer) bytes @@ -10,7 +10,7 @@ LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 } } error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:28:43 + --> $DIR/const-pointer-values-in-various-types.rs:29:43 | LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 }; | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -22,7 +22,7 @@ LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_ = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:32:45 + --> $DIR/const-pointer-values-in-various-types.rs:33:45 | LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 }; | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -33,7 +33,7 @@ LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uin = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:36:45 + --> $DIR/const-pointer-values-in-various-types.rs:37:45 | LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 }; | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -44,7 +44,7 @@ LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uin = note: for more information, see issue #71800 error[E0080]: it is undefined behavior to use this value - --> $DIR/const-pointer-values-in-various-types.rs:40:5 + --> $DIR/const-pointer-values-in-various-types.rs:41:5 | LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc18, but expected initialized plain (non-pointer) bytes @@ -55,7 +55,7 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin } error[E0080]: it is undefined behavior to use this value - --> $DIR/const-pointer-values-in-various-types.rs:43:5 + --> $DIR/const-pointer-values-in-various-types.rs:44:5 | LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes @@ -66,7 +66,7 @@ LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.u } error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:46:43 + --> $DIR/const-pointer-values-in-various-types.rs:47:43 | LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 }; | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -77,7 +77,7 @@ LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:50:45 + --> $DIR/const-pointer-values-in-various-types.rs:51:45 | LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 }; | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -88,7 +88,7 @@ LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:54:45 + --> $DIR/const-pointer-values-in-various-types.rs:55:45 | LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 }; | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -99,7 +99,7 @@ LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int = note: for more information, see issue #71800 error[E0080]: it is undefined behavior to use this value - --> $DIR/const-pointer-values-in-various-types.rs:58:5 + --> $DIR/const-pointer-values-in-various-types.rs:59:5 | LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc38, but expected initialized plain (non-pointer) bytes @@ -110,7 +110,7 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int } error[E0080]: it is undefined behavior to use this value - --> $DIR/const-pointer-values-in-various-types.rs:61:5 + --> $DIR/const-pointer-values-in-various-types.rs:62:5 | LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes @@ -121,7 +121,7 @@ LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.i } error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:64:45 + --> $DIR/const-pointer-values-in-various-types.rs:65:45 | LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 }; | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -132,7 +132,7 @@ LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.flo = note: for more information, see issue #71800 error[E0080]: it is undefined behavior to use this value - --> $DIR/const-pointer-values-in-various-types.rs:68:5 + --> $DIR/const-pointer-values-in-various-types.rs:69:5 | LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc50, but expected initialized plain (non-pointer) bytes @@ -143,7 +143,7 @@ LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.flo } error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:71:47 + --> $DIR/const-pointer-values-in-various-types.rs:72:47 | LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey }; | ------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -154,7 +154,7 @@ LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.t = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:75:47 + --> $DIR/const-pointer-values-in-various-types.rs:76:47 | LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character }; | ------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -165,7 +165,7 @@ LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.c = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:79:39 + --> $DIR/const-pointer-values-in-various-types.rs:80:39 | LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 }; | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -176,7 +176,7 @@ LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 }; = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:83:41 + --> $DIR/const-pointer-values-in-various-types.rs:84:41 | LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }; | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -187,7 +187,7 @@ LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 } = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:87:41 + --> $DIR/const-pointer-values-in-various-types.rs:88:41 | LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }; | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -198,7 +198,7 @@ LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 } = note: for more information, see issue #71800 error[E0080]: it is undefined behavior to use this value - --> $DIR/const-pointer-values-in-various-types.rs:91:5 + --> $DIR/const-pointer-values-in-various-types.rs:92:5 | LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc71, but expected initialized plain (non-pointer) bytes @@ -209,7 +209,7 @@ LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 } } error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:94:43 + --> $DIR/const-pointer-values-in-various-types.rs:95:43 | LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 }; | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -220,7 +220,7 @@ LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_12 = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:98:39 + --> $DIR/const-pointer-values-in-various-types.rs:99:39 | LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 }; | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -231,7 +231,7 @@ LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 }; = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:102:41 + --> $DIR/const-pointer-values-in-various-types.rs:103:41 | LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 }; | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -242,7 +242,7 @@ LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 }; = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:106:41 + --> $DIR/const-pointer-values-in-various-types.rs:107:41 | LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 }; | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -253,7 +253,7 @@ LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 }; = note: for more information, see issue #71800 error[E0080]: it is undefined behavior to use this value - --> $DIR/const-pointer-values-in-various-types.rs:110:5 + --> $DIR/const-pointer-values-in-various-types.rs:111:5 | LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc86, but expected initialized plain (non-pointer) bytes @@ -264,7 +264,7 @@ LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 }; } error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:113:43 + --> $DIR/const-pointer-values-in-various-types.rs:114:43 | LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 }; | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -275,7 +275,7 @@ LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:117:41 + --> $DIR/const-pointer-values-in-various-types.rs:118:41 | LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 }; | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -286,7 +286,7 @@ LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 = note: for more information, see issue #71800 error[E0080]: it is undefined behavior to use this value - --> $DIR/const-pointer-values-in-various-types.rs:121:5 + --> $DIR/const-pointer-values-in-various-types.rs:122:5 | LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc95, but expected initialized plain (non-pointer) bytes @@ -297,7 +297,7 @@ LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 } error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:124:43 + --> $DIR/const-pointer-values-in-various-types.rs:125:43 | LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey }; | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -308,7 +308,7 @@ LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_ = note: for more information, see issue #71800 error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:128:43 + --> $DIR/const-pointer-values-in-various-types.rs:129:43 | LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character }; | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs index 90bc191020e..a1a932639db 100644 --- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs @@ -1,4 +1,5 @@ // only-x86_64 +// stderr-per-bitwidth #[repr(C)] union Nonsense { diff --git a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.stderr b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr similarity index 95% rename from src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.stderr rename to src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr index b2bfdf14696..6d63233997d 100644 --- a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.stderr +++ b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/alloc_intrinsic_uninit.rs:8:1 + --> $DIR/alloc_intrinsic_uninit.rs:9:1 | LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at ., but expected initialized plain (non-pointer) bytes diff --git a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs index 998b6cef84a..63a3fd4e090 100644 --- a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs +++ b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth // compile-test #![feature(core_intrinsics)] #![feature(const_heap)] diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr similarity index 90% rename from src/test/ui/consts/const-eval/ref_to_int_match.stderr rename to src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr index 843dd5662e0..6ea1cf145a2 100644 --- a/src/test/ui/consts/const-eval/ref_to_int_match.stderr +++ b/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ref_to_int_match.rs:25:1 + --> $DIR/ref_to_int_match.rs:26:1 | LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc2, but expected initialized plain (non-pointer) bytes @@ -10,13 +10,13 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; } error: could not evaluate constant pattern - --> $DIR/ref_to_int_match.rs:7:14 + --> $DIR/ref_to_int_match.rs:8:14 | LL | 10..=BAR => {}, | ^^^ error: could not evaluate constant pattern - --> $DIR/ref_to_int_match.rs:7:14 + --> $DIR/ref_to_int_match.rs:8:14 | LL | 10..=BAR => {}, | ^^^ diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.rs b/src/test/ui/consts/const-eval/ref_to_int_match.rs index 87136a109db..0741e425d9b 100644 --- a/src/test/ui/consts/const-eval/ref_to_int_match.rs +++ b/src/test/ui/consts/const-eval/ref_to_int_match.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth #![feature(const_fn_union)] fn main() { diff --git a/src/test/ui/consts/const-eval/transmute-const.stderr b/src/test/ui/consts/const-eval/transmute-const.64bit.stderr similarity index 95% rename from src/test/ui/consts/const-eval/transmute-const.stderr rename to src/test/ui/consts/const-eval/transmute-const.64bit.stderr index 4245c3ea5d0..89c72207883 100644 --- a/src/test/ui/consts/const-eval/transmute-const.stderr +++ b/src/test/ui/consts/const-eval/transmute-const.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/transmute-const.rs:3:1 + --> $DIR/transmute-const.rs:4:1 | LL | static FOO: bool = unsafe { mem::transmute(3u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03, but expected a boolean diff --git a/src/test/ui/consts/const-eval/transmute-const.rs b/src/test/ui/consts/const-eval/transmute-const.rs index 1cfad00ca76..d9d0a3aea07 100644 --- a/src/test/ui/consts/const-eval/transmute-const.rs +++ b/src/test/ui/consts/const-eval/transmute-const.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth use std::mem; static FOO: bool = unsafe { mem::transmute(3u8) }; diff --git a/src/test/ui/consts/const-eval/ub-enum.stderr b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr similarity index 97% rename from src/test/ui/consts/const-eval/ub-enum.stderr rename to src/test/ui/consts/const-eval/ub-enum.64bit.stderr index a84f38fe1dc..29d97962f32 100644 --- a/src/test/ui/consts/const-eval/ub-enum.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr @@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:24:1 | LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000001 at ., but expected a valid enum tag + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x0000000000000001 at ., but expected a valid enum tag | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { @@ -35,7 +35,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:42:1 | LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000000 at ., but expected a valid enum tag + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x0000000000000000 at ., but expected a valid enum tag | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { diff --git a/src/test/ui/consts/const-eval/ub-enum.rs b/src/test/ui/consts/const-eval/ub-enum.rs index dc94f2368c9..e408d8ec072 100644 --- a/src/test/ui/consts/const-eval/ub-enum.rs +++ b/src/test/ui/consts/const-eval/ub-enum.rs @@ -1,4 +1,4 @@ -// normalize-stderr-64bit "0x0000000000" -> "0x00" +// stderr-per-bitwidth #![feature(never_type)] #![allow(const_err)] // make sure we cannot allow away the errors tested here diff --git a/src/test/ui/consts/const-eval/ub-int-array.stderr b/src/test/ui/consts/const-eval/ub-int-array.64bit.stderr similarity index 100% rename from src/test/ui/consts/const-eval/ub-int-array.stderr rename to src/test/ui/consts/const-eval/ub-int-array.64bit.stderr diff --git a/src/test/ui/consts/const-eval/ub-int-array.rs b/src/test/ui/consts/const-eval/ub-int-array.rs index 6801c7fa3ff..635cbb8cef6 100644 --- a/src/test/ui/consts/const-eval/ub-int-array.rs +++ b/src/test/ui/consts/const-eval/ub-int-array.rs @@ -1,5 +1,5 @@ #![allow(const_err)] // make sure we cannot allow away the errors tested here - +// stderr-per-bitwidth //! Test the "array of int" fast path in validity checking, and in particular whether it //! points at the right array element. diff --git a/src/test/ui/consts/const-eval/ub-nonnull.stderr b/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr similarity index 95% rename from src/test/ui/consts/const-eval/ub-nonnull.stderr rename to src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr index 2cd55500005..63815c46efe 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:11:1 + --> $DIR/ub-nonnull.rs:12:1 | LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1 @@ -10,7 +10,7 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; } error: any use of this value will cause an error - --> $DIR/ub-nonnull.rs:18:30 + --> $DIR/ub-nonnull.rs:19:30 | LL | / const OUT_OF_BOUNDS_PTR: NonNull = { unsafe { LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle @@ -23,7 +23,7 @@ LL | | } }; | |____- | note: the lint level is defined here - --> $DIR/ub-nonnull.rs:14:8 + --> $DIR/ub-nonnull.rs:15:8 | LL | #[deny(const_err)] // this triggers a `const_err` so validation does not even happen | ^^^^^^^^^ @@ -31,7 +31,7 @@ LL | #[deny(const_err)] // this triggers a `const_err` so validation does not ev = note: for more information, see issue #71800 error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:23:1 + --> $DIR/ub-nonnull.rs:24:1 | LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1 @@ -42,7 +42,7 @@ LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:25:1 + --> $DIR/ub-nonnull.rs:26:1 | LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1 @@ -53,7 +53,7 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:33:1 + --> $DIR/ub-nonnull.rs:34:1 | LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at .0, but expected initialized plain (non-pointer) bytes @@ -64,7 +64,7 @@ LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:41:1 + --> $DIR/ub-nonnull.rs:42:1 | LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 10..=30 @@ -75,7 +75,7 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-nonnull.rs:47:1 + --> $DIR/ub-nonnull.rs:48:1 | LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 20, but expected something less or equal to 10, or greater or equal to 30 diff --git a/src/test/ui/consts/const-eval/ub-nonnull.rs b/src/test/ui/consts/const-eval/ub-nonnull.rs index e4ced600b4c..0bc406e01a0 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.rs +++ b/src/test/ui/consts/const-eval/ub-nonnull.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth #![feature(rustc_attrs)] #![allow(const_err, invalid_value)] // make sure we cannot allow away the errors tested here diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr similarity index 95% rename from src/test/ui/consts/const-eval/ub-ref-ptr.stderr rename to src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr index 25e69134621..8bd4637a80b 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:12:1 + --> $DIR/ub-ref-ptr.rs:13:1 | LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered an unaligned reference (required 2 byte alignment but found 1) @@ -10,7 +10,7 @@ LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:16:1 + --> $DIR/ub-ref-ptr.rs:17:1 | LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered an unaligned box (required 2 byte alignment but found 1) @@ -21,7 +21,7 @@ LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:20:1 + --> $DIR/ub-ref-ptr.rs:21:1 | LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a NULL reference @@ -32,7 +32,7 @@ LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:23:1 + --> $DIR/ub-ref-ptr.rs:24:1 | LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a NULL box @@ -43,7 +43,7 @@ LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:29:1 + --> $DIR/ub-ref-ptr.rs:30:1 | LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc14, but expected initialized plain (non-pointer) bytes @@ -54,7 +54,7 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:32:1 + --> $DIR/ub-ref-ptr.rs:33:1 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at ., but expected plain (non-pointer) bytes @@ -65,7 +65,7 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:35:1 + --> $DIR/ub-ref-ptr.rs:36:1 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at ., but expected plain (non-pointer) bytes @@ -76,7 +76,7 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:38:1 + --> $DIR/ub-ref-ptr.rs:39:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (created from integer) @@ -87,7 +87,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:41:1 + --> $DIR/ub-ref-ptr.rs:42:1 | LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (created from integer) @@ -98,7 +98,7 @@ LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:44:1 + --> $DIR/ub-ref-ptr.rs:45:1 | LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized raw pointer @@ -109,7 +109,7 @@ LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:46:1 + --> $DIR/ub-ref-ptr.rs:47:1 | LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a function pointer diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.rs b/src/test/ui/consts/const-eval/ub-ref-ptr.rs index f6075987d17..8857ae4caac 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.rs +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.rs @@ -1,4 +1,5 @@ // ignore-tidy-linelength +// stderr-per-bitwidth #![allow(const_err, invalid_value)] // make sure we cannot allow away the errors tested here use std::mem; diff --git a/src/test/ui/consts/const-eval/ub-uninhabit.stderr b/src/test/ui/consts/const-eval/ub-uninhabit.64bit.stderr similarity index 95% rename from src/test/ui/consts/const-eval/ub-uninhabit.stderr rename to src/test/ui/consts/const-eval/ub-uninhabit.64bit.stderr index af8cda0e4d3..def795c7f56 100644 --- a/src/test/ui/consts/const-eval/ub-uninhabit.stderr +++ b/src/test/ui/consts/const-eval/ub-uninhabit.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-uninhabit.rs:14:1 + --> $DIR/ub-uninhabit.rs:15:1 | LL | const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Bar @@ -8,7 +8,7 @@ LL | const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init }; = note: the raw bytes of the constant (size: 0, align: 1) {} error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-uninhabit.rs:17:1 + --> $DIR/ub-uninhabit.rs:18:1 | LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Bar at . @@ -19,7 +19,7 @@ LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-uninhabit.rs:20:1 + --> $DIR/ub-uninhabit.rs:21:1 | LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Bar at [0] diff --git a/src/test/ui/consts/const-eval/ub-uninhabit.rs b/src/test/ui/consts/const-eval/ub-uninhabit.rs index b81bca38494..33fbd14c472 100644 --- a/src/test/ui/consts/const-eval/ub-uninhabit.rs +++ b/src/test/ui/consts/const-eval/ub-uninhabit.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth #![allow(const_err)] // make sure we cannot allow away the errors tested here use std::mem; diff --git a/src/test/ui/consts/const-eval/ub-upvars.stderr b/src/test/ui/consts/const-eval/ub-upvars.64bit.stderr similarity index 97% rename from src/test/ui/consts/const-eval/ub-upvars.stderr rename to src/test/ui/consts/const-eval/ub-upvars.64bit.stderr index 23a564edff1..e9fabd9a3bc 100644 --- a/src/test/ui/consts/const-eval/ub-upvars.stderr +++ b/src/test/ui/consts/const-eval/ub-upvars.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-upvars.rs:5:1 + --> $DIR/ub-upvars.rs:6:1 | LL | / const BAD_UPVAR: &dyn FnOnce() = &{ LL | | let bad_ref: &'static u16 = unsafe { mem::transmute(0usize) }; diff --git a/src/test/ui/consts/const-eval/ub-upvars.rs b/src/test/ui/consts/const-eval/ub-upvars.rs index 5d19276557e..57dd7b9e581 100644 --- a/src/test/ui/consts/const-eval/ub-upvars.rs +++ b/src/test/ui/consts/const-eval/ub-upvars.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth #![allow(const_err, invalid_value)] // make sure we cannot allow away the errors tested here use std::mem; diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr similarity index 95% rename from src/test/ui/consts/const-eval/ub-wide-ptr.stderr rename to src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr index ac26630a54f..e42c65a1517 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:37:1 + --> $DIR/ub-wide-ptr.rs:38:1 | LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (going beyond the bounds of its allocation) @@ -10,7 +10,7 @@ LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:39:1 + --> $DIR/ub-wide-ptr.rs:40:1 | LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object at .0 @@ -21,7 +21,7 @@ LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, us } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:42:1 + --> $DIR/ub-wide-ptr.rs:43:1 | LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer @@ -32,7 +32,7 @@ LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:45:1 + --> $DIR/ub-wide-ptr.rs:46:1 | LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer @@ -43,7 +43,7 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:47:1 + --> $DIR/ub-wide-ptr.rs:48:1 | LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object @@ -54,7 +54,7 @@ LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize: } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:51:1 + --> $DIR/ub-wide-ptr.rs:52:1 | LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in `str` at . @@ -65,7 +65,7 @@ LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit: } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:54:1 + --> $DIR/ub-wide-ptr.rs:55:1 | LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in `str` at ..0 @@ -76,7 +76,7 @@ LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUni } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:61:1 + --> $DIR/ub-wide-ptr.rs:62:1 | LL | / const SLICE_LENGTH_UNINIT: &[u8] = unsafe { LL | | @@ -91,7 +91,7 @@ LL | | }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:67:1 + --> $DIR/ub-wide-ptr.rs:68:1 | LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (going beyond the bounds of its allocation) @@ -102,7 +102,7 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:70:1 + --> $DIR/ub-wide-ptr.rs:71:1 | LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer @@ -113,7 +113,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:73:1 + --> $DIR/ub-wide-ptr.rs:74:1 | LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (going beyond the bounds of its allocation) @@ -124,7 +124,7 @@ LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999us } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:76:1 + --> $DIR/ub-wide-ptr.rs:77:1 | LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer @@ -135,7 +135,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3) } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:80:1 + --> $DIR/ub-wide-ptr.rs:81:1 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at .[0], but expected a boolean @@ -146,7 +146,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:86:1 + --> $DIR/ub-wide-ptr.rs:87:1 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at ..0, but expected a boolean @@ -157,7 +157,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3 } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:89:1 + --> $DIR/ub-wide-ptr.rs:90:1 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at ..1[0], but expected a boolean @@ -168,7 +168,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:96:1 + --> $DIR/ub-wide-ptr.rs:97:1 | LL | / const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { LL | | @@ -183,7 +183,7 @@ LL | | }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:104:1 + --> $DIR/ub-wide-ptr.rs:105:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable at .0 @@ -194,7 +194,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W(( } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:107:1 + --> $DIR/ub-wide-ptr.rs:108:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable at .0 @@ -205,7 +205,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W(( } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:110:1 + --> $DIR/ub-wide-ptr.rs:111:1 | LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling vtable pointer in wide pointer at .0 @@ -216,7 +216,7 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:112:1 + --> $DIR/ub-wide-ptr.rs:113:1 | LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered unaligned vtable pointer in wide pointer @@ -227,7 +227,7 @@ LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92 } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:114:1 + --> $DIR/ub-wide-ptr.rs:115:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function) @@ -238,7 +238,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92 } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:116:1 + --> $DIR/ub-wide-ptr.rs:117:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function) @@ -249,7 +249,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:118:1 + --> $DIR/ub-wide-ptr.rs:119:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function) at .0 @@ -260,7 +260,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::trans } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:122:1 + --> $DIR/ub-wide-ptr.rs:123:1 | LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at .., but expected a boolean @@ -271,7 +271,7 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:126:1 + --> $DIR/ub-wide-ptr.rs:127:1 | LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling vtable pointer in wide pointer @@ -282,7 +282,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:128:1 + --> $DIR/ub-wide-ptr.rs:129:1 | LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable @@ -293,13 +293,13 @@ LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transm } error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:134:5 + --> $DIR/ub-wide-ptr.rs:135:5 | LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ inbounds test failed: 0x0 is not a valid pointer error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:138:5 + --> $DIR/ub-wide-ptr.rs:139:5 | LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset N, but is outside bounds of allocN which has size N diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs index 2975118cdb7..0fb9f7960ce 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.rs +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth // ignore-tidy-linelength #![allow(unused)] #![allow(const_err)] // make sure we cannot allow away the errors tested here diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.stderr b/src/test/ui/consts/const-eval/union-const-eval-field.64bit.stderr similarity index 94% rename from src/test/ui/consts/const-eval/union-const-eval-field.stderr rename to src/test/ui/consts/const-eval/union-const-eval-field.64bit.stderr index e5a107ff011..c1c2dcb2269 100644 --- a/src/test/ui/consts/const-eval/union-const-eval-field.stderr +++ b/src/test/ui/consts/const-eval/union-const-eval-field.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/union-const-eval-field.rs:28:5 + --> $DIR/union-const-eval-field.rs:29:5 | LL | const FIELD3: Field3 = unsafe { UNION.field3 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.rs b/src/test/ui/consts/const-eval/union-const-eval-field.rs index 7f29a5bc24e..c91ed0acb2e 100644 --- a/src/test/ui/consts/const-eval/union-const-eval-field.rs +++ b/src/test/ui/consts/const-eval/union-const-eval-field.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth #![feature(const_fn)] type Field1 = i32; diff --git a/src/test/ui/consts/const-eval/union-ice.stderr b/src/test/ui/consts/const-eval/union-ice.64bit.stderr similarity index 96% rename from src/test/ui/consts/const-eval/union-ice.stderr rename to src/test/ui/consts/const-eval/union-ice.64bit.stderr index 6d44b3c8b28..f8b9478ad1a 100644 --- a/src/test/ui/consts/const-eval/union-ice.stderr +++ b/src/test/ui/consts/const-eval/union-ice.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/union-ice.rs:14:1 + --> $DIR/union-ice.rs:15:1 | LL | const FIELD3: Field3 = unsafe { UNION.field3 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes @@ -10,7 +10,7 @@ LL | const FIELD3: Field3 = unsafe { UNION.field3 }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/union-ice.rs:16:1 + --> $DIR/union-ice.rs:17:1 | LL | / const FIELD_PATH: Struct = Struct { LL | | a: 42, @@ -24,7 +24,7 @@ LL | | }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/union-ice.rs:26:1 + --> $DIR/union-ice.rs:27:1 | LL | / const FIELD_PATH2: Struct2 = Struct2 { LL | | b: [ diff --git a/src/test/ui/consts/const-eval/union-ice.rs b/src/test/ui/consts/const-eval/union-ice.rs index 5a14c7fd993..c1e780d9bb7 100644 --- a/src/test/ui/consts/const-eval/union-ice.rs +++ b/src/test/ui/consts/const-eval/union-ice.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth #![feature(const_fn)] type Field1 = i32; diff --git a/src/test/ui/consts/const-eval/union-ub.stderr b/src/test/ui/consts/const-eval/union-ub.64bit.stderr similarity index 96% rename from src/test/ui/consts/const-eval/union-ub.stderr rename to src/test/ui/consts/const-eval/union-ub.64bit.stderr index b54e15bad9b..d3e4bad968b 100644 --- a/src/test/ui/consts/const-eval/union-ub.stderr +++ b/src/test/ui/consts/const-eval/union-ub.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/union-ub.rs:32:1 + --> $DIR/union-ub.rs:33:1 | LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x2a, but expected a boolean @@ -10,7 +10,7 @@ LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool}; } error[E0080]: it is undefined behavior to use this value - --> $DIR/union-ub.rs:34:1 + --> $DIR/union-ub.rs:35:1 | LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a boolean diff --git a/src/test/ui/consts/const-eval/union-ub.rs b/src/test/ui/consts/const-eval/union-ub.rs index 512359f5b1c..c1bfe69a706 100644 --- a/src/test/ui/consts/const-eval/union-ub.rs +++ b/src/test/ui/consts/const-eval/union-ub.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth #![allow(const_err)] // make sure we cannot allow away the errors tested here #[repr(C)] diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr similarity index 90% rename from src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr rename to src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr index e25abab7e37..bb91b43e20b 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr @@ -1,18 +1,18 @@ warning: any use of this value will cause an error - --> $DIR/validate_uninhabited_zsts.rs:5:14 + --> $DIR/validate_uninhabited_zsts.rs:6:14 | LL | unsafe { std::mem::transmute(()) } | ^^^^^^^^^^^^^^^^^^^^^^^ | | | transmuting to uninhabited type - | inside `foo` at $DIR/validate_uninhabited_zsts.rs:5:14 - | inside `FOO` at $DIR/validate_uninhabited_zsts.rs:15:26 + | inside `foo` at $DIR/validate_uninhabited_zsts.rs:6:14 + | inside `FOO` at $DIR/validate_uninhabited_zsts.rs:16:26 ... LL | const FOO: [Empty; 3] = [foo(); 3]; | ----------------------------------- | note: the lint level is defined here - --> $DIR/validate_uninhabited_zsts.rs:14:8 + --> $DIR/validate_uninhabited_zsts.rs:15:8 | LL | #[warn(const_err)] | ^^^^^^^^^ @@ -20,7 +20,7 @@ LL | #[warn(const_err)] = note: for more information, see issue #71800 error[E0080]: it is undefined behavior to use this value - --> $DIR/validate_uninhabited_zsts.rs:18:1 + --> $DIR/validate_uninhabited_zsts.rs:19:1 | LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Empty at [0] @@ -29,7 +29,7 @@ LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; = note: the raw bytes of the constant (size: 0, align: 1) {} warning: the type `!` does not permit zero-initialization - --> $DIR/validate_uninhabited_zsts.rs:5:14 + --> $DIR/validate_uninhabited_zsts.rs:6:14 | LL | unsafe { std::mem::transmute(()) } | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | unsafe { std::mem::transmute(()) } = note: the `!` type has no valid value warning: the type `Empty` does not permit zero-initialization - --> $DIR/validate_uninhabited_zsts.rs:18:35 + --> $DIR/validate_uninhabited_zsts.rs:19:35 | LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs index 4e1c71cd600..a32dfa2918b 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth #![feature(const_fn)] #![feature(const_fn_transmute)] diff --git a/src/test/ui/consts/const-points-to-static.stderr b/src/test/ui/consts/const-points-to-static.64bit.stderr similarity index 91% rename from src/test/ui/consts/const-points-to-static.stderr rename to src/test/ui/consts/const-points-to-static.64bit.stderr index 13e50eb2481..1112499a3ee 100644 --- a/src/test/ui/consts/const-points-to-static.stderr +++ b/src/test/ui/consts/const-points-to-static.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/const-points-to-static.rs:5:1 + --> $DIR/const-points-to-static.rs:6:1 | LL | const TEST: &u8 = &MY_STATIC; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a reference pointing to a static variable @@ -12,7 +12,7 @@ LL | const TEST: &u8 = &MY_STATIC; warning: skipping const checks | help: skipping check that does not even have a feature gate - --> $DIR/const-points-to-static.rs:5:20 + --> $DIR/const-points-to-static.rs:6:20 | LL | const TEST: &u8 = &MY_STATIC; | ^^^^^^^^^ diff --git a/src/test/ui/consts/const-points-to-static.rs b/src/test/ui/consts/const-points-to-static.rs index e5f0e3f5dae..8a97a9fec01 100644 --- a/src/test/ui/consts/const-points-to-static.rs +++ b/src/test/ui/consts/const-points-to-static.rs @@ -1,4 +1,5 @@ // compile-flags: -Zunleash-the-miri-inside-of-you +// stderr-per-bitwidth #![allow(dead_code)] diff --git a/src/test/ui/consts/issue-63952.stderr b/src/test/ui/consts/issue-63952.64bit.stderr similarity index 96% rename from src/test/ui/consts/issue-63952.stderr rename to src/test/ui/consts/issue-63952.64bit.stderr index c469619f1b7..3335c5bf72e 100644 --- a/src/test/ui/consts/issue-63952.stderr +++ b/src/test/ui/consts/issue-63952.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/issue-63952.rs:16:1 + --> $DIR/issue-63952.rs:17:1 | LL | / const SLICE_WAY_TOO_LONG: &[u8] = unsafe { LL | | SliceTransmute { diff --git a/src/test/ui/consts/issue-63952.rs b/src/test/ui/consts/issue-63952.rs index f50e1e51f61..5c83e6f45c9 100644 --- a/src/test/ui/consts/issue-63952.rs +++ b/src/test/ui/consts/issue-63952.rs @@ -1,4 +1,5 @@ // Regression test for #63952, shouldn't hang. +// stderr-per-bitwidth #[repr(C)] #[derive(Copy, Clone)] diff --git a/src/test/ui/consts/issue-79690.stderr b/src/test/ui/consts/issue-79690.64bit.stderr similarity index 96% rename from src/test/ui/consts/issue-79690.stderr rename to src/test/ui/consts/issue-79690.64bit.stderr index 6930c02ad5f..2639bc4812c 100644 --- a/src/test/ui/consts/issue-79690.stderr +++ b/src/test/ui/consts/issue-79690.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/issue-79690.rs:29:1 + --> $DIR/issue-79690.rs:30:1 | LL | const G: Fat = unsafe { Transmute { t: FOO }.u }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered (potentially part of) a pointer at .1..size.foo, but expected plain (non-pointer) bytes diff --git a/src/test/ui/consts/issue-79690.rs b/src/test/ui/consts/issue-79690.rs index a2e7b97b318..56747bf5a11 100644 --- a/src/test/ui/consts/issue-79690.rs +++ b/src/test/ui/consts/issue-79690.rs @@ -1,5 +1,6 @@ // ignore-32bit // This test gives a different error on 32-bit architectures. +// stderr-per-bitwidth union Transmute { t: T, diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.64bit.stderr similarity index 90% rename from src/test/ui/consts/miri_unleashed/const_refers_to_static2.stderr rename to src/test/ui/consts/miri_unleashed/const_refers_to_static2.64bit.stderr index b3efac1bd36..5521cd34aad 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static2.rs:10:1 + --> $DIR/const_refers_to_static2.rs:11:1 | LL | / const REF_INTERIOR_MUT: &usize = { LL | | @@ -16,7 +16,7 @@ LL | | }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static2.rs:19:1 + --> $DIR/const_refers_to_static2.rs:20:1 | LL | / const READ_IMMUT: &usize = { LL | | @@ -35,17 +35,17 @@ LL | | }; warning: skipping const checks | help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static2.rs:15:18 + --> $DIR/const_refers_to_static2.rs:16:18 | LL | unsafe { &*(&FOO as *const _ as *const usize) } | ^^^ help: skipping check for `const_raw_ptr_deref` feature - --> $DIR/const_refers_to_static2.rs:15:14 + --> $DIR/const_refers_to_static2.rs:16:14 | LL | unsafe { &*(&FOO as *const _ as *const usize) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static2.rs:24:6 + --> $DIR/const_refers_to_static2.rs:25:6 | LL | &FOO | ^^^ diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.rs b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.rs index 7ac2d847d3d..2548474d4fd 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.rs +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.rs @@ -1,4 +1,5 @@ // compile-flags: -Zunleash-the-miri-inside-of-you +// stderr-per-bitwidth #![allow(const_err)] use std::sync::atomic::AtomicUsize; diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr similarity index 80% rename from src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr rename to src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr index d6cfa6e023b..7228f7178ff 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static_cross_crate.rs:11:1 + --> $DIR/const_refers_to_static_cross_crate.rs:12:1 | LL | / const SLICE_MUT: &[u8; 1] = { LL | | @@ -15,13 +15,13 @@ LL | | }; } error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:46:9 + --> $DIR/const_refers_to_static_cross_crate.rs:47:9 | LL | SLICE_MUT => true, | ^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/const_refers_to_static_cross_crate.rs:18:1 + --> $DIR/const_refers_to_static_cross_crate.rs:19:1 | LL | / const U8_MUT: &u8 = { LL | | @@ -37,13 +37,13 @@ LL | | }; } error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:55:9 + --> $DIR/const_refers_to_static_cross_crate.rs:56:9 | LL | U8_MUT => true, | ^^^^^^ warning: any use of this value will cause an error - --> $DIR/const_refers_to_static_cross_crate.rs:28:15 + --> $DIR/const_refers_to_static_cross_crate.rs:29:15 | LL | / const U8_MUT2: &u8 = { LL | | unsafe { &(*static_cross_crate::ZERO_REF)[0] } @@ -56,7 +56,7 @@ LL | | }; | |__- | note: the lint level is defined here - --> $DIR/const_refers_to_static_cross_crate.rs:26:8 + --> $DIR/const_refers_to_static_cross_crate.rs:27:8 | LL | #[warn(const_err)] | ^^^^^^^^^ @@ -64,13 +64,13 @@ LL | #[warn(const_err)] = note: for more information, see issue #71800 error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:66:9 + --> $DIR/const_refers_to_static_cross_crate.rs:67:9 | LL | U8_MUT2 => true, | ^^^^^^^ warning: any use of this value will cause an error - --> $DIR/const_refers_to_static_cross_crate.rs:36:51 + --> $DIR/const_refers_to_static_cross_crate.rs:37:51 | LL | / const U8_MUT3: &u8 = { LL | | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } @@ -83,7 +83,7 @@ LL | | }; | |__- | note: the lint level is defined here - --> $DIR/const_refers_to_static_cross_crate.rs:34:8 + --> $DIR/const_refers_to_static_cross_crate.rs:35:8 | LL | #[warn(const_err)] | ^^^^^^^^^ @@ -91,31 +91,31 @@ LL | #[warn(const_err)] = note: for more information, see issue #71800 error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:74:9 + --> $DIR/const_refers_to_static_cross_crate.rs:75:9 | LL | U8_MUT3 => true, | ^^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:46:9 + --> $DIR/const_refers_to_static_cross_crate.rs:47:9 | LL | SLICE_MUT => true, | ^^^^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:55:9 + --> $DIR/const_refers_to_static_cross_crate.rs:56:9 | LL | U8_MUT => true, | ^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:66:9 + --> $DIR/const_refers_to_static_cross_crate.rs:67:9 | LL | U8_MUT2 => true, | ^^^^^^^ error: could not evaluate constant pattern - --> $DIR/const_refers_to_static_cross_crate.rs:74:9 + --> $DIR/const_refers_to_static_cross_crate.rs:75:9 | LL | U8_MUT3 => true, | ^^^^^^^ @@ -123,57 +123,57 @@ LL | U8_MUT3 => true, warning: skipping const checks | help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:15:15 + --> $DIR/const_refers_to_static_cross_crate.rs:16:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:15:15 + --> $DIR/const_refers_to_static_cross_crate.rs:16:15 | LL | unsafe { &static_cross_crate::ZERO } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:22:15 + --> $DIR/const_refers_to_static_cross_crate.rs:23:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:22:15 + --> $DIR/const_refers_to_static_cross_crate.rs:23:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:22:15 + --> $DIR/const_refers_to_static_cross_crate.rs:23:15 | LL | unsafe { &static_cross_crate::ZERO[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:28:17 + --> $DIR/const_refers_to_static_cross_crate.rs:29:17 | LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:36:20 + --> $DIR/const_refers_to_static_cross_crate.rs:37:20 | LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:36:20 + --> $DIR/const_refers_to_static_cross_crate.rs:37:20 | LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:36:20 + --> $DIR/const_refers_to_static_cross_crate.rs:37:20 | LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_panic` feature - --> $DIR/const_refers_to_static_cross_crate.rs:36:77 + --> $DIR/const_refers_to_static_cross_crate.rs:37:77 | LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:36:20 + --> $DIR/const_refers_to_static_cross_crate.rs:37:20 | LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs index 2d32c7ea39e..53f70198f4c 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs @@ -1,5 +1,6 @@ // compile-flags: -Zunleash-the-miri-inside-of-you // aux-build:static_cross_crate.rs +// stderr-per-bitwidth #![allow(const_err)] #![feature(exclusive_range_pattern, half_open_range_patterns)] diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_err.stderr b/src/test/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr similarity index 91% rename from src/test/ui/consts/miri_unleashed/mutable_references_err.stderr rename to src/test/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr index 8fde2838e3f..606184e5732 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_references_err.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references_err.rs:16:1 + --> $DIR/mutable_references_err.rs:17:1 | LL | / const MUH: Meh = Meh { LL | | x: &UnsafeCell::new(42), @@ -12,7 +12,7 @@ LL | | }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references_err.rs:26:1 + --> $DIR/mutable_references_err.rs:27:1 | LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered `UnsafeCell` in a `const` at ...x @@ -23,7 +23,7 @@ LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/mutable_references_err.rs:30:1 + --> $DIR/mutable_references_err.rs:31:1 | LL | const BLUNT: &mut i32 = &mut 42; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered mutable reference in a `const` @@ -36,17 +36,17 @@ LL | const BLUNT: &mut i32 = &mut 42; warning: skipping const checks | help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:17:8 + --> $DIR/mutable_references_err.rs:18:8 | LL | x: &UnsafeCell::new(42), | ^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:26:27 + --> $DIR/mutable_references_err.rs:27:27 | LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/mutable_references_err.rs:30:25 + --> $DIR/mutable_references_err.rs:31:25 | LL | const BLUNT: &mut i32 = &mut 42; | ^^^^^^^ diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_err.rs b/src/test/ui/consts/miri_unleashed/mutable_references_err.rs index 195414dbad9..722b9cf94e8 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_references_err.rs +++ b/src/test/ui/consts/miri_unleashed/mutable_references_err.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth // compile-flags: -Zunleash-the-miri-inside-of-you #![allow(const_err)] diff --git a/src/test/ui/consts/std/alloc.stderr b/src/test/ui/consts/std/alloc.64bit.stderr similarity index 97% rename from src/test/ui/consts/std/alloc.stderr rename to src/test/ui/consts/std/alloc.64bit.stderr index 01f44fe4ae9..2c891b1d79c 100644 --- a/src/test/ui/consts/std/alloc.stderr +++ b/src/test/ui/consts/std/alloc.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/alloc.rs:7:1 + --> $DIR/alloc.rs:8:1 | LL | const LAYOUT_INVALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0 at .align_, but expected something greater or equal to 1 diff --git a/src/test/ui/consts/std/alloc.rs b/src/test/ui/consts/std/alloc.rs index 65ac7e44926..14eadc4487f 100644 --- a/src/test/ui/consts/std/alloc.rs +++ b/src/test/ui/consts/std/alloc.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth use std::alloc::Layout; // ok diff --git a/src/test/ui/consts/validate_never_arrays.stderr b/src/test/ui/consts/validate_never_arrays.64bit.stderr similarity index 96% rename from src/test/ui/consts/validate_never_arrays.stderr rename to src/test/ui/consts/validate_never_arrays.64bit.stderr index cc558ee56d9..dd677f1b21e 100644 --- a/src/test/ui/consts/validate_never_arrays.stderr +++ b/src/test/ui/consts/validate_never_arrays.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/validate_never_arrays.rs:3:1 + --> $DIR/validate_never_arrays.rs:4:1 | LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at .[0] @@ -10,7 +10,7 @@ LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/validate_never_arrays.rs:6:1 + --> $DIR/validate_never_arrays.rs:7:1 | LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at .[0] @@ -21,7 +21,7 @@ LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/validate_never_arrays.rs:7:1 + --> $DIR/validate_never_arrays.rs:8:1 | LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at .[0] diff --git a/src/test/ui/consts/validate_never_arrays.rs b/src/test/ui/consts/validate_never_arrays.rs index c7144f05ec7..1990fb07397 100644 --- a/src/test/ui/consts/validate_never_arrays.rs +++ b/src/test/ui/consts/validate_never_arrays.rs @@ -1,3 +1,4 @@ +// stderr-per-bitwidth #![feature(const_raw_ptr_deref, never_type)] const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 99cbcf316a2..b7693a3cb14 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -376,12 +376,24 @@ pub fn expected_output_path( testpaths.file.with_extension(extension) } -pub const UI_EXTENSIONS: &[&str] = &[UI_STDERR, UI_STDOUT, UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT]; +pub const UI_EXTENSIONS: &[&str] = &[ + UI_STDERR, + UI_STDOUT, + UI_FIXED, + UI_RUN_STDERR, + UI_RUN_STDOUT, + UI_STDERR_64, + UI_STDERR_32, + UI_STDERR_16, +]; pub const UI_STDERR: &str = "stderr"; pub const UI_STDOUT: &str = "stdout"; pub const UI_FIXED: &str = "fixed"; pub const UI_RUN_STDERR: &str = "run.stderr"; pub const UI_RUN_STDOUT: &str = "run.stdout"; +pub const UI_STDERR_64: &str = "64bit.stderr"; +pub const UI_STDERR_32: &str = "32bit.stderr"; +pub const UI_STDERR_16: &str = "16bit.stderr"; /// Absolute path to the directory where all output for all tests in the given /// `relative_dir` group should reside. Example: diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 7aa3d4ab09e..1a49b1e7b17 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -3185,7 +3185,7 @@ impl<'test> TestCx<'test> { } if !self.props.dont_check_compiler_stderr { let kind = if self.props.stderr_per_bitwidth { - format!("{}bit.stderr", get_pointer_width(&self.config.target)) + format!("{}.stderr", get_pointer_width(&self.config.target)) } else { String::from("stderr") }; From e78fac56015ca2d926237704b02e555604a99e9d Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Wed, 31 Mar 2021 04:40:31 -0400 Subject: [PATCH 231/370] Handle the case of partially captured drop type --- compiler/rustc_typeck/src/check/upvar.rs | 44 +++++++++++++----------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index fd4186e8025..124076a889b 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -639,7 +639,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// `w[c]`. /// Notation: /// - Ty(place): Type of place - /// - `(a, b)`: Represents the function parameters `base_path_ty` and `captured_projs` + /// - `(a, b)`: Represents the function parameters `base_path_ty` and `captured_by_move_projs` /// respectively. /// ``` /// (Ty(w), [ &[p, x], &[c] ]) @@ -700,7 +700,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { closure_def_id: DefId, closure_span: Span, base_path_ty: Ty<'tcx>, - captured_projs: Vec<&[Projection<'tcx>]>, + captured_by_move_projs: Vec<&[Projection<'tcx>]>, ) -> bool { let needs_drop = |ty: Ty<'tcx>| { ty.needs_drop(self.tcx, self.tcx.param_env(closure_def_id.expect_local())) @@ -725,9 +725,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // eg. If `a.b` is captured and we are processing `a.b`, then we can't have the closure also // capture `a.b.c`, because that voilates min capture. - let is_completely_captured = captured_projs.iter().any(|projs| projs.is_empty()); + let is_completely_captured = captured_by_move_projs.iter().any(|projs| projs.is_empty()); - assert!(!is_completely_captured || (captured_projs.len() == 1)); + assert!(!is_completely_captured || (captured_by_move_projs.len() == 1)); if is_completely_captured { // The place is captured entirely, so doesn't matter if needs dtor, it will be drop @@ -735,23 +735,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } - if is_drop_defined_for_ty { - // If drop is implemented for this type then we need it to be fully captured, - // which we know it is not because of the previous check. Therefore we need to - // do migrate. - return true; + if captured_by_move_projs.is_empty() { + return needs_drop(base_path_ty); } - if captured_projs.is_empty() { - return needs_drop(base_path_ty); + if is_drop_defined_for_ty { + // If drop is implemented for this type then we need it to be fully captured, + // and we know it is not completely captured because of the previous checks. + + // Note that this is a bug in the user code that will be reported by the + // borrow checker, since we can't move out of drop types. + + // The bug exists in the user's code pre-migration, and we don't migrate here. + return false; } match base_path_ty.kind() { // Observations: - // - `captured_projs` is not empty. Therefore we can call - // `captured_projs.first().unwrap()` safely. - // - All entries in `captured_projs` have atleast one projection. - // Therefore we can call `captured_projs.first().unwrap().first().unwrap()` safely. + // - `captured_by_move_projs` is not empty. Therefore we can call + // `captured_by_move_projs.first().unwrap()` safely. + // - All entries in `captured_by_move_projs` have atleast one projection. + // Therefore we can call `captured_by_move_projs.first().unwrap().first().unwrap()` safely. // We don't capture derefs in case of move captures, which would have be applied to // access any further paths. @@ -761,19 +765,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Adt(def, substs) => { // Multi-varaint enums are captured in entirety, - // which would've been handled in the case of single empty slice in `captured_projs`. + // which would've been handled in the case of single empty slice in `captured_by_move_projs`. assert_eq!(def.variants.len(), 1); // Only Field projections can be applied to a non-box Adt. assert!( - captured_projs.iter().all(|projs| matches!( + captured_by_move_projs.iter().all(|projs| matches!( projs.first().unwrap().kind, ProjectionKind::Field(..) )) ); def.variants.get(VariantIdx::new(0)).unwrap().fields.iter().enumerate().any( |(i, field)| { - let paths_using_field = captured_projs + let paths_using_field = captured_by_move_projs .iter() .filter_map(|projs| { if let ProjectionKind::Field(field_idx, _) = @@ -800,14 +804,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Tuple(..) => { // Only Field projections can be applied to a tuple. assert!( - captured_projs.iter().all(|projs| matches!( + captured_by_move_projs.iter().all(|projs| matches!( projs.first().unwrap().kind, ProjectionKind::Field(..) )) ); base_path_ty.tuple_fields().enumerate().any(|(i, element_ty)| { - let paths_using_field = captured_projs + let paths_using_field = captured_by_move_projs .iter() .filter_map(|projs| { if let ProjectionKind::Field(field_idx, _) = projs.first().unwrap().kind From 1d56b8a2bc181c6da705c8aa7241672cf25e43bf Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 29 Mar 2021 16:35:21 +0000 Subject: [PATCH 232/370] Make unevaluated DefId rendering deterministic --- compiler/rustc_mir/src/util/pretty.rs | 16 +++++++++++++++- ...promotion_extern_static.BAR.PromoteTemps.diff | 2 +- ...promotion_extern_static.FOO.PromoteTemps.diff | 2 +- ...safe_oob_for_slices.main.ConstProp.32bit.diff | 2 +- ...safe_oob_for_slices.main.ConstProp.64bit.diff | 2 +- ...nst_prop_fails_gracefully.main.ConstProp.diff | 2 +- .../const_prop/ref_deref.main.ConstProp.diff | 2 +- .../const_prop/ref_deref.main.PromoteTemps.diff | 2 +- .../ref_deref_project.main.ConstProp.diff | 2 +- .../ref_deref_project.main.PromoteTemps.diff | 2 +- .../slice_len.main.ConstProp.32bit.diff | 2 +- .../slice_len.main.ConstProp.64bit.diff | 2 +- .../inline/inline_retag.bar.Inline.after.mir | 4 ++-- .../issue_73223.main.PreCodegen.32bit.diff | 2 +- .../issue_73223.main.PreCodegen.64bit.diff | 2 +- ...sue_73223.main.SimplifyArmIdentity.32bit.diff | 2 +- ...sue_73223.main.SimplifyArmIdentity.64bit.diff | 2 +- ..._intrinsics.discriminant.LowerIntrinsics.diff | 6 +++--- ...dges.full_tested_match.PromoteTemps.after.mir | 2 +- ...ag.main.SimplifyCfg-elaborate-drops.after.mir | 2 +- 20 files changed, 37 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_mir/src/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs index 1bf010ffca7..8fa44e4ded3 100644 --- a/compiler/rustc_mir/src/util/pretty.rs +++ b/compiler/rustc_mir/src/util/pretty.rs @@ -465,7 +465,21 @@ impl Visitor<'tcx> for ExtraComments<'tcx> { if use_verbose(ty) { self.push("ty::Const"); self.push(&format!("+ ty: {:?}", ty)); - self.push(&format!("+ val: {:?}", val)); + let val = match val { + ty::ConstKind::Param(p) => format!("Param({})", p), + ty::ConstKind::Infer(infer) => format!("Infer({:?})", infer), + ty::ConstKind::Bound(idx, var) => format!("Bound({:?}, {:?})", idx, var), + ty::ConstKind::Placeholder(ph) => format!("PlaceHolder({:?})", ph), + ty::ConstKind::Unevaluated(uv) => format!( + "Unevaluated({}, {:?}, {:?})", + self.tcx.def_path_str(uv.def.did), + uv.substs, + uv.promoted + ), + ty::ConstKind::Value(val) => format!("Value({:?})", val), + ty::ConstKind::Error(_) => format!("Error"), + }; + self.push(&format!("+ val: {}", val)); } } diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff index 4e990dd6b70..2566d745ecd 100644 --- a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff +++ b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff @@ -22,7 +22,7 @@ - // + ty: &i32 - // + val: Value(Scalar(alloc0)) + // + ty: &[&i32; 1] -+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) ++ // + val: Unevaluated(BAR, [], Some(promoted[0])) // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34 - // + literal: Const { ty: &i32, val: Value(Scalar(alloc0)) } diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff index 0a9a3f3c2c5..093e228a0ce 100644 --- a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff +++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff @@ -24,7 +24,7 @@ - // + ty: *const i32 - // + val: Value(Scalar(alloc2)) + // + ty: &[&i32; 1] -+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) ++ // + val: Unevaluated(FOO, [], Some(promoted[0])) // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 - // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) } diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff index 0535b45aa9f..0517e7fac40 100644 --- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff @@ -28,7 +28,7 @@ _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 // ty::Const // + ty: &[i32; 3] - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 // + literal: Const { ty: &[i32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff index 0535b45aa9f..0517e7fac40 100644 --- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff @@ -28,7 +28,7 @@ _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 // ty::Const // + ty: &[i32; 3] - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 // + literal: Const { ty: &[i32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff index 81e6937b1b3..28c80b346e7 100644 --- a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff @@ -19,7 +19,7 @@ _3 = const FOO; // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:16 // ty::Const // + ty: &i32 - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, substs: [], promoted: None }) + // + val: Unevaluated(FOO, [], None) // mir::Constant // + span: $DIR/const_prop_fails_gracefully.rs:7:13: 7:16 // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, substs: [], promoted: None }) } diff --git a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff index 9126b9953ed..ae77443e019 100644 --- a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff @@ -14,7 +14,7 @@ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10 // ty::Const // + ty: &i32 - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $DIR/ref_deref.rs:5:6: 5:10 // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff index e1c8085b31b..402a28f3f9f 100644 --- a/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff +++ b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff @@ -17,7 +17,7 @@ + _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10 + // ty::Const + // + ty: &i32 -+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) ++ // + val: Unevaluated(main, [], Some(promoted[0])) + // mir::Constant + // + span: $DIR/ref_deref.rs:5:6: 5:10 + // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff index ce1720698c7..b97d7d1be15 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff @@ -14,7 +14,7 @@ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 // ty::Const // + ty: &(i32, i32) - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $DIR/ref_deref_project.rs:5:6: 5:17 // + literal: Const { ty: &(i32, i32), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff index 93ba9de8202..48ede27112c 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff +++ b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff @@ -17,7 +17,7 @@ + _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 + // ty::Const + // + ty: &(i32, i32) -+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) ++ // + val: Unevaluated(main, [], Some(promoted[0])) + // mir::Constant + // + span: $DIR/ref_deref_project.rs:5:6: 5:17 + // + literal: Const { ty: &(i32, i32), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff index 610e3c25573..27791852d6d 100644 --- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff @@ -21,7 +21,7 @@ _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 // ty::Const // + ty: &[u32; 3] - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $DIR/slice_len.rs:5:6: 5:19 // + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff index 610e3c25573..27791852d6d 100644 --- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff @@ -21,7 +21,7 @@ _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:5:6: 5:19 // ty::Const // + ty: &[u32; 3] - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $DIR/slice_len.rs:5:6: 5:19 // + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir index 0b5dc2b20fc..1aabee83be6 100644 --- a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir @@ -35,7 +35,7 @@ fn bar() -> bool { _10 = const bar::promoted[1]; // scope 1 at $DIR/inline-retag.rs:12:7: 12:9 // ty::Const // + ty: &i32 - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[1]) }) + // + val: Unevaluated(bar, [], Some(promoted[1])) // mir::Constant // + span: $DIR/inline-retag.rs:12:7: 12:9 // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[1]) }) } @@ -49,7 +49,7 @@ fn bar() -> bool { _9 = const bar::promoted[0]; // scope 1 at $DIR/inline-retag.rs:12:11: 12:14 // ty::Const // + ty: &i32 - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // + val: Unevaluated(bar, [], Some(promoted[0])) // mir::Constant // + span: $DIR/inline-retag.rs:12:11: 12:14 // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff index 1ba56016776..95a8ef997fa 100644 --- a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff @@ -63,7 +63,7 @@ _20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &i32 - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff index 1ba56016776..95a8ef997fa 100644 --- a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff @@ -63,7 +63,7 @@ _20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &i32 - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff index 245f0e9d000..261eb3b27ea 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff @@ -84,7 +84,7 @@ _28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &i32 - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff index 245f0e9d000..261eb3b27ea 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff @@ -84,7 +84,7 @@ _28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &i32 - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff index 83650d837b0..a37df4da9ae 100644 --- a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff +++ b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff @@ -47,7 +47,7 @@ _19 = const discriminant::::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44 // ty::Const // + ty: &i32 - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[2]) }) + // + val: Unevaluated(discriminant, [T], Some(promoted[2])) // mir::Constant // + span: $DIR/lower_intrinsics.rs:70:42: 70:44 // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[2]) }) } @@ -71,7 +71,7 @@ _18 = const discriminant::::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45 // ty::Const // + ty: &() - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[1]) }) + // + val: Unevaluated(discriminant, [T], Some(promoted[1])) // mir::Constant // + span: $DIR/lower_intrinsics.rs:71:42: 71:45 // + literal: Const { ty: &(), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[1]) }) } @@ -95,7 +95,7 @@ _17 = const discriminant::::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47 // ty::Const // + ty: &E - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[0]) }) + // + val: Unevaluated(discriminant, [T], Some(promoted[0])) // mir::Constant // + span: $DIR/lower_intrinsics.rs:72:42: 72:47 // + literal: Const { ty: &E, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir index 242138754c5..1921b935941 100644 --- a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir +++ b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir @@ -54,7 +54,7 @@ fn full_tested_match() -> () { _11 = const full_tested_match::promoted[0]; // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15 // ty::Const // + ty: &std::option::Option - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // + val: Unevaluated(full_tested_match, [], Some(promoted[0])) // mir::Constant // + span: $DIR/match_false_edges.rs:16:14: 16:15 // + literal: Const { ty: &std::option::Option, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } diff --git a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir index d25f98db9f6..894f64c7767 100644 --- a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir @@ -149,7 +149,7 @@ fn main() -> () { _27 = const main::promoted[0]; // scope 7 at $DIR/retag.rs:47:21: 47:23 // ty::Const // + ty: &i32 - // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) + // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $DIR/retag.rs:47:21: 47:23 // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } From c7c39ce6d07e4d33dc25e07c43f0139c0634b7eb Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 30 Mar 2021 12:11:29 +0000 Subject: [PATCH 233/370] We should never see unevaluated type-level constants after monomorphization unless errors occurred --- compiler/rustc_mir/src/monomorphize/collector.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index c5c701082e6..5cc1d7082d1 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -648,7 +648,13 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { ty::ConstKind::Value(val) => collect_const_value(self.tcx, val, self.output), ty::ConstKind::Unevaluated(unevaluated) => { match self.tcx.const_eval_resolve(param_env, unevaluated, None) { - Ok(val) => collect_const_value(self.tcx, val, self.output), + // The `monomorphize` call should have evaluated that constant already. + Ok(val) => span_bug!( + self.body.source_info(location).span, + "collection encountered the unevaluated constant {} which evaluated to {:?}", + substituted_constant, + val + ), Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {} Err(ErrorHandled::TooGeneric) => span_bug!( self.body.source_info(location).span, From f80b9acf204888585b254e760d13ac4c37af2254 Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Wed, 31 Mar 2021 09:33:45 +0000 Subject: [PATCH 234/370] Add 32bit.stderr files. --- .../invalid-patterns.32bit.stderr | 72 ++++ src/test/ui/consts/const-err4.32bit.stderr | 14 + .../heap/alloc_intrinsic_uninit.32bit.stderr | 14 + .../const-eval/ref_to_int_match.32bit.stderr | 26 ++ .../const-eval/transmute-const.32bit.stderr | 14 + .../ui/consts/const-eval/ub-enum.32bit.stderr | 146 +++++++++ .../const-eval/ub-int-array.32bit.stderr | 54 +++ .../consts/const-eval/ub-nonnull.32bit.stderr | 90 +++++ .../consts/const-eval/ub-ref-ptr.32bit.stderr | 124 +++++++ .../const-eval/ub-uninhabit.32bit.stderr | 32 ++ .../consts/const-eval/ub-upvars.32bit.stderr | 18 + .../const-eval/ub-wide-ptr.32bit.stderr | 309 ++++++++++++++++++ .../union-const-eval-field.32bit.stderr | 14 + .../consts/const-eval/union-ice.32bit.stderr | 47 +++ .../consts/const-eval/union-ub.32bit.stderr | 25 ++ .../validate_uninhabited_zsts.32bit.stderr | 56 ++++ .../const-points-to-static.32bit.stderr | 22 ++ src/test/ui/consts/const-points-to-static.rs | 2 +- src/test/ui/consts/issue-63952.32bit.stderr | 20 ++ .../const_refers_to_static2.32bit.stderr | 55 ++++ ..._refers_to_static_cross_crate.32bit.stderr | 184 +++++++++++ .../mutable_references_err.32bit.stderr | 56 ++++ src/test/ui/consts/std/alloc.32bit.stderr | 14 + .../consts/validate_never_arrays.32bit.stderr | 36 ++ 24 files changed, 1443 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr create mode 100644 src/test/ui/consts/const-err4.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/transmute-const.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/ub-enum.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/ub-int-array.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/ub-uninhabit.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/ub-upvars.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/union-const-eval-field.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/union-ice.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/union-ub.32bit.stderr create mode 100644 src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr create mode 100644 src/test/ui/consts/const-points-to-static.32bit.stderr create mode 100644 src/test/ui/consts/issue-63952.32bit.stderr create mode 100644 src/test/ui/consts/miri_unleashed/const_refers_to_static2.32bit.stderr create mode 100644 src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr create mode 100644 src/test/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr create mode 100644 src/test/ui/consts/std/alloc.32bit.stderr create mode 100644 src/test/ui/consts/validate_never_arrays.32bit.stderr diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr b/src/test/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr new file mode 100644 index 00000000000..415a53a5627 --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr @@ -0,0 +1,72 @@ +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:29:21 + | +LL | get_flag::(); + | ^^^^ expected `char`, found `u8` + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:31:14 + | +LL | get_flag::<7, 'c'>(); + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:33:14 + | +LL | get_flag::<42, 0x5ad>(); + | ^^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:33:18 + | +LL | get_flag::<42, 0x5ad>(); + | ^^^^^ expected `char`, found `u8` + +error[E0080]: it is undefined behavior to use this value + --> $DIR/invalid-patterns.rs:38:21 + | +LL | get_flag::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + __ __ __ __ │ ░░░░ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/invalid-patterns.rs:40:14 + | +LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x42, but expected a boolean + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 42 │ B + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/invalid-patterns.rs:42:14 + | +LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x42, but expected a boolean + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 42 │ B + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/invalid-patterns.rs:42:47 + | +LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + __ __ __ __ │ ░░░░ + } + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0080, E0308. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-err4.32bit.stderr b/src/test/ui/consts/const-err4.32bit.stderr new file mode 100644 index 00000000000..1dbda8cbcd0 --- /dev/null +++ b/src/test/ui/consts/const-err4.32bit.stderr @@ -0,0 +1,14 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/const-err4.rs:9:11 + | +LL | Boo = [unsafe { Foo { b: () }.a }; 4][3], + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + __ __ __ __ │ ░░░░ + } + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr new file mode 100644 index 00000000000..92d990f1498 --- /dev/null +++ b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr @@ -0,0 +1,14 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/alloc_intrinsic_uninit.rs:9:1 + | +LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at ., but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc1──╼ │ ╾──╼ + } + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr new file mode 100644 index 00000000000..c14457490ac --- /dev/null +++ b/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr @@ -0,0 +1,26 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/ref_to_int_match.rs:26:1 + | +LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc2, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc2──╼ │ ╾──╼ + } + +error: could not evaluate constant pattern + --> $DIR/ref_to_int_match.rs:8:14 + | +LL | 10..=BAR => {}, + | ^^^ + +error: could not evaluate constant pattern + --> $DIR/ref_to_int_match.rs:8:14 + | +LL | 10..=BAR => {}, + | ^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/transmute-const.32bit.stderr b/src/test/ui/consts/const-eval/transmute-const.32bit.stderr new file mode 100644 index 00000000000..89c72207883 --- /dev/null +++ b/src/test/ui/consts/const-eval/transmute-const.32bit.stderr @@ -0,0 +1,14 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/transmute-const.rs:4:1 + | +LL | static FOO: bool = unsafe { mem::transmute(3u8) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03, but expected a boolean + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 03 │ . + } + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr new file mode 100644 index 00000000000..2274366fa21 --- /dev/null +++ b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr @@ -0,0 +1,146 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:24:1 + | +LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000001 at ., but expected a valid enum tag + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 01 00 00 00 │ .... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:27:1 + | +LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc8 at ., but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc8──╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:30:1 + | +LL | const BAD_ENUM_WRAPPED: Wrap = unsafe { mem::transmute(&1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc12 at .0., but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc12─╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:42:1 + | +LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000000 at ., but expected a valid enum tag + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 00 00 00 00 │ .... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:44:1 + | +LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc18 at ., but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc18─╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:47:1 + | +LL | const BAD_ENUM2_WRAPPED: Wrap = unsafe { mem::transmute(&0) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc22 at .0., but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc22─╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:56:1 + | +LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at ., but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + __ __ __ __ │ ░░░░ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:60:1 + | +LL | const BAD_ENUM2_OPTION_PTR: Option = unsafe { mem::transmute(&0) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc28 at ., but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc28─╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:77:1 + | +LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at ..0 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 01 │ . + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:79:1 + | +LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Never at ..0 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 03 │ . + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:87:1 + | +LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0xffffffff at ..0.1, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + 78 00 00 00 ff ff ff ff │ x....... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:92:1 + | +LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Never at ..0.1 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + 00 00 00 00 00 00 00 00 │ ........ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-enum.rs:94:1 + | +LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at ..0.1 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + 00 00 00 00 00 00 00 00 │ ........ + } + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-int-array.32bit.stderr b/src/test/ui/consts/const-eval/ub-int-array.32bit.stderr new file mode 100644 index 00000000000..c13271a1e5e --- /dev/null +++ b/src/test/ui/consts/const-eval/ub-int-array.32bit.stderr @@ -0,0 +1,54 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-int-array.rs:14:1 + | +LL | / const UNINIT_INT_0: [u32; 3] = unsafe { +LL | | +LL | | +LL | | [ +... | +LL | | ] +LL | | }; + | |__^ type validation failed: encountered uninitialized bytes at [0] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 12, align: 4) { + __ __ __ __ 01 00 00 00 02 00 00 00 │ ░░░░........ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-int-array.rs:23:1 + | +LL | / const UNINIT_INT_1: [u32; 3] = unsafe { +LL | | +LL | | +LL | | mem::transmute( +... | +LL | | ) +LL | | }; + | |__^ type validation failed: encountered uninitialized bytes at [1] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 12, align: 4) { + 00 00 00 00 01 __ 01 01 02 02 __ 02 │ .....░....░. + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-int-array.rs:43:1 + | +LL | / const UNINIT_INT_2: [u32; 3] = unsafe { +LL | | +LL | | +LL | | mem::transmute( +... | +LL | | ) +LL | | }; + | |__^ type validation failed: encountered uninitialized bytes at [2] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 12, align: 4) { + 00 00 00 00 01 01 01 01 02 02 02 __ │ ...........░ + } + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr b/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr new file mode 100644 index 00000000000..3affde739af --- /dev/null +++ b/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr @@ -0,0 +1,90 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-nonnull.rs:12:1 + | +LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 00 00 00 00 │ .... + } + +error: any use of this value will cause an error + --> $DIR/ub-nonnull.rs:19:30 + | +LL | / const OUT_OF_BOUNDS_PTR: NonNull = { unsafe { +LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle +LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL! +LL | | let out_of_bounds_ptr = &ptr[255]; + | | ^^^^^^^^ memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of alloc10 which has size 1 +LL | | +LL | | mem::transmute(out_of_bounds_ptr) +LL | | } }; + | |____- + | +note: the lint level is defined here + --> $DIR/ub-nonnull.rs:15:8 + | +LL | #[deny(const_err)] // this triggers a `const_err` so validation does not even happen + | ^^^^^^^^^ + = 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 #71800 + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-nonnull.rs:24:1 + | +LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 00 │ . + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-nonnull.rs:26:1 + | +LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 00 00 00 00 │ .... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-nonnull.rs:34:1 + | +LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at .0, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + __ │ ░ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-nonnull.rs:42:1 + | +LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 10..=30 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 2a 00 00 00 │ *... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-nonnull.rs:48:1 + | +LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 20, but expected something less or equal to 10, or greater or equal to 30 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 14 00 00 00 │ .... + } + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr new file mode 100644 index 00000000000..32e13baa3f5 --- /dev/null +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr @@ -0,0 +1,124 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-ref-ptr.rs:13:1 + | +LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered an unaligned reference (required 2 byte alignment but found 1) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc2──╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-ref-ptr.rs:17:1 + | +LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered an unaligned box (required 2 byte alignment but found 1) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc6──╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-ref-ptr.rs:21:1 + | +LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a NULL reference + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 00 00 00 00 │ .... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-ref-ptr.rs:24:1 + | +LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a NULL box + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 00 00 00 00 │ .... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-ref-ptr.rs:30:1 + | +LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc14, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc14─╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-ref-ptr.rs:33:1 + | +LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at ., but expected plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc20─╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-ref-ptr.rs:36:1 + | +LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at ., but expected plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc25─╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-ref-ptr.rs:39:1 + | +LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (created from integer) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 39 05 00 00 │ 9... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-ref-ptr.rs:42:1 + | +LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (created from integer) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 39 05 00 00 │ 9... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-ref-ptr.rs:45:1 + | +LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized raw pointer + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + __ __ __ __ │ ░░░░ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-ref-ptr.rs:47:1 + | +LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a function pointer + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + __ __ __ __ │ ░░░░ + } + +error: aborting due to 11 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-uninhabit.32bit.stderr b/src/test/ui/consts/const-eval/ub-uninhabit.32bit.stderr new file mode 100644 index 00000000000..4155a8a2ef9 --- /dev/null +++ b/src/test/ui/consts/const-eval/ub-uninhabit.32bit.stderr @@ -0,0 +1,32 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-uninhabit.rs:15:1 + | +LL | const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Bar + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 0, align: 1) {} + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-uninhabit.rs:18:1 + | +LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Bar at . + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 01 00 00 00 │ .... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-uninhabit.rs:21:1 + | +LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Bar at [0] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 0, align: 1) {} + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-upvars.32bit.stderr b/src/test/ui/consts/const-eval/ub-upvars.32bit.stderr new file mode 100644 index 00000000000..62756518a00 --- /dev/null +++ b/src/test/ui/consts/const-eval/ub-upvars.32bit.stderr @@ -0,0 +1,18 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-upvars.rs:6:1 + | +LL | / const BAD_UPVAR: &dyn FnOnce() = &{ +LL | | let bad_ref: &'static u16 = unsafe { mem::transmute(0usize) }; +LL | | let another_var = 13; +LL | | move || { let _ = bad_ref; let _ = another_var; } +LL | | }; + | |__^ type validation failed: encountered a NULL reference at ... + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─alloc2──╼ ╾─alloc3──╼ │ ╾──╼╾──╼ + } + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr new file mode 100644 index 00000000000..7ca5c647d88 --- /dev/null +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr @@ -0,0 +1,309 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:38:1 + | +LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (going beyond the bounds of its allocation) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─allocN──╼ e7 03 00 00 │ ╾──╼.... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:40:1 + | +LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object at .0 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─allocN─╼ ff ff ff ff │ ╾──╼.... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:43:1 + | +LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─allocN─╼ ╾─allocN─╼ │ ╾──╼╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:46:1 + | +LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─allocN─╼ ╾─allocN─╼ │ ╾──╼╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:48:1 + | +LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─allocN─╼ ff ff ff ff │ ╾──╼.... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:52:1 + | +LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in `str` at . + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─allocN─╼ 01 00 00 00 │ ╾──╼.... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:55:1 + | +LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in `str` at ..0 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─allocN─╼ 01 00 00 00 │ ╾──╼.... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:62:1 + | +LL | / const SLICE_LENGTH_UNINIT: &[u8] = unsafe { +LL | | +LL | | let uninit_len = MaybeUninit:: { uninit: () }; +LL | | mem::transmute((42, uninit_len)) +LL | | }; + | |__^ type validation failed: encountered uninitialized reference + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + 2a 00 00 00 __ __ __ __ │ *...░░░░ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:68:1 + | +LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (going beyond the bounds of its allocation) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─allocN─╼ e7 03 00 00 │ ╾──╼.... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:71:1 + | +LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─allocN─╼ ╾─allocN─╼ │ ╾──╼╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:74:1 + | +LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (going beyond the bounds of its allocation) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─allocN─╼ e7 03 00 00 │ ╾──╼.... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:77:1 + | +LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─allocN─╼ ╾─allocN─╼ │ ╾──╼╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:81:1 + | +LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at .[0], but expected a boolean + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─allocN─╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:87:1 + | +LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at ..0, but expected a boolean + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─allocN─╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:90:1 + | +LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at ..1[0], but expected a boolean + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─allocN─╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:97:1 + | +LL | / const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { +LL | | +LL | | let uninit_len = MaybeUninit:: { uninit: () }; +LL | | mem::transmute((42, uninit_len)) +LL | | }; + | |__^ type validation failed: encountered uninitialized raw pointer + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + 2a 00 00 00 __ __ __ __ │ *...░░░░ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:105:1 + | +LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable at .0 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:108:1 + | +LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable at .0 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:111:1 + | +LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling vtable pointer in wide pointer at .0 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾allocN─╼ 04 00 00 00 │ ╾──╼.... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:113:1 + | +LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered unaligned vtable pointer in wide pointer + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:115:1 + | +LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:117:1 + | +LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function) + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:119:1 + | +LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function) at .0 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:123:1 + | +LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at .., but expected a boolean + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:127:1 + | +LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling vtable pointer in wide pointer + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾allocN─╼ 00 00 00 00 │ ╾──╼.... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:129:1 + | +LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + } + +error[E0080]: could not evaluate static initializer + --> $DIR/ub-wide-ptr.rs:135:5 + | +LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ inbounds test failed: 0x0 is not a valid pointer + +error[E0080]: could not evaluate static initializer + --> $DIR/ub-wide-ptr.rs:139:5 + | +LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset N, but is outside bounds of allocN which has size N + +error: aborting due to 28 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.32bit.stderr b/src/test/ui/consts/const-eval/union-const-eval-field.32bit.stderr new file mode 100644 index 00000000000..472bd214de7 --- /dev/null +++ b/src/test/ui/consts/const-eval/union-const-eval-field.32bit.stderr @@ -0,0 +1,14 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/union-const-eval-field.rs:29:5 + | +LL | const FIELD3: Field3 = unsafe { UNION.field3 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + __ __ __ __ __ __ __ __ │ ░░░░░░░░ + } + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/union-ice.32bit.stderr b/src/test/ui/consts/const-eval/union-ice.32bit.stderr new file mode 100644 index 00000000000..f8502ad66c5 --- /dev/null +++ b/src/test/ui/consts/const-eval/union-ice.32bit.stderr @@ -0,0 +1,47 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/union-ice.rs:15:1 + | +LL | const FIELD3: Field3 = unsafe { UNION.field3 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + __ __ __ __ __ __ __ __ │ ░░░░░░░░ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/union-ice.rs:17:1 + | +LL | / const FIELD_PATH: Struct = Struct { +LL | | a: 42, +LL | | b: unsafe { UNION.field3 }, +LL | | }; + | |__^ type validation failed: encountered uninitialized bytes at .b, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 12, align: 4) { + __ __ __ __ __ __ __ __ 2a __ __ __ │ ░░░░░░░░*░░░ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/union-ice.rs:27:1 + | +LL | / const FIELD_PATH2: Struct2 = Struct2 { +LL | | b: [ +LL | | 21, +LL | | unsafe { UNION.field3 }, +... | +LL | | a: 42, +LL | | }; + | |__^ type validation failed: encountered uninitialized bytes at .b[1] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 36, align: 4) { + 0x00 │ 15 00 00 00 00 00 00 00 __ __ __ __ __ __ __ __ │ ........░░░░░░░░ + 0x10 │ 17 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 │ ................ + 0x20 │ 2a __ __ __ │ *░░░ + } + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/union-ub.32bit.stderr b/src/test/ui/consts/const-eval/union-ub.32bit.stderr new file mode 100644 index 00000000000..d3e4bad968b --- /dev/null +++ b/src/test/ui/consts/const-eval/union-ub.32bit.stderr @@ -0,0 +1,25 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/union-ub.rs:33:1 + | +LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x2a, but expected a boolean + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + 2a │ * + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/union-ub.rs:35:1 + | +LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a boolean + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 1, align: 1) { + __ │ ░ + } + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr new file mode 100644 index 00000000000..bb91b43e20b --- /dev/null +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr @@ -0,0 +1,56 @@ +warning: any use of this value will cause an error + --> $DIR/validate_uninhabited_zsts.rs:6:14 + | +LL | unsafe { std::mem::transmute(()) } + | ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | transmuting to uninhabited type + | inside `foo` at $DIR/validate_uninhabited_zsts.rs:6:14 + | inside `FOO` at $DIR/validate_uninhabited_zsts.rs:16:26 +... +LL | const FOO: [Empty; 3] = [foo(); 3]; + | ----------------------------------- + | +note: the lint level is defined here + --> $DIR/validate_uninhabited_zsts.rs:15:8 + | +LL | #[warn(const_err)] + | ^^^^^^^^^ + = 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 #71800 + +error[E0080]: it is undefined behavior to use this value + --> $DIR/validate_uninhabited_zsts.rs:19:1 + | +LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Empty at [0] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 0, align: 1) {} + +warning: the type `!` does not permit zero-initialization + --> $DIR/validate_uninhabited_zsts.rs:6:14 + | +LL | unsafe { std::mem::transmute(()) } + | ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done + | + = note: `#[warn(invalid_value)]` on by default + = note: the `!` type has no valid value + +warning: the type `Empty` does not permit zero-initialization + --> $DIR/validate_uninhabited_zsts.rs:19:35 + | +LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done + | + = note: enums with no variants have no valid value + +error: aborting due to previous error; 3 warnings emitted + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-points-to-static.32bit.stderr b/src/test/ui/consts/const-points-to-static.32bit.stderr new file mode 100644 index 00000000000..c582678e2d6 --- /dev/null +++ b/src/test/ui/consts/const-points-to-static.32bit.stderr @@ -0,0 +1,22 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/const-points-to-static.rs:6:1 + | +LL | const TEST: &u8 = &MY_STATIC; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a reference pointing to a static variable + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc0──╼ │ ╾──╼ + } + +warning: skipping const checks + | +help: skipping check that does not even have a feature gate + --> $DIR/const-points-to-static.rs:6:20 + | +LL | const TEST: &u8 = &MY_STATIC; + | ^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-points-to-static.rs b/src/test/ui/consts/const-points-to-static.rs index 8a97a9fec01..4359230685f 100644 --- a/src/test/ui/consts/const-points-to-static.rs +++ b/src/test/ui/consts/const-points-to-static.rs @@ -7,7 +7,7 @@ const TEST: &u8 = &MY_STATIC; //~^ ERROR it is undefined behavior to use this value //~| NOTE encountered a reference pointing to a static variable //~| NOTE undefined behavior -//~| NOTE the raw bytes of the constant (size: 8, align: 8) +//~| NOTE the raw bytes of the constant static MY_STATIC: u8 = 4; diff --git a/src/test/ui/consts/issue-63952.32bit.stderr b/src/test/ui/consts/issue-63952.32bit.stderr new file mode 100644 index 00000000000..6d52ed065bf --- /dev/null +++ b/src/test/ui/consts/issue-63952.32bit.stderr @@ -0,0 +1,20 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/issue-63952.rs:17:1 + | +LL | / const SLICE_WAY_TOO_LONG: &[u8] = unsafe { +LL | | SliceTransmute { +LL | | repr: SliceRepr { +LL | | ptr: &42, +... | +LL | | .slice +LL | | }; + | |__^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─alloc3──╼ ff ff ff ff │ ╾──╼.... + } + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.32bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.32bit.stderr new file mode 100644 index 00000000000..6ca18290b43 --- /dev/null +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.32bit.stderr @@ -0,0 +1,55 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refers_to_static2.rs:11:1 + | +LL | / const REF_INTERIOR_MUT: &usize = { +LL | | +LL | | +LL | | +LL | | static FOO: AtomicUsize = AtomicUsize::new(0); +LL | | unsafe { &*(&FOO as *const _ as *const usize) } +LL | | }; + | |__^ type validation failed: encountered a reference pointing to a static variable + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc0──╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refers_to_static2.rs:20:1 + | +LL | / const READ_IMMUT: &usize = { +LL | | +LL | | +LL | | +LL | | static FOO: usize = 0; +LL | | &FOO +LL | | }; + | |__^ type validation failed: encountered a reference pointing to a static variable + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc1──╼ │ ╾──╼ + } + +warning: skipping const checks + | +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static2.rs:16:18 + | +LL | unsafe { &*(&FOO as *const _ as *const usize) } + | ^^^ +help: skipping check for `const_raw_ptr_deref` feature + --> $DIR/const_refers_to_static2.rs:16:14 + | +LL | unsafe { &*(&FOO as *const _ as *const usize) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static2.rs:25:6 + | +LL | &FOO + | ^^^ + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr new file mode 100644 index 00000000000..73d1d7c5b95 --- /dev/null +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr @@ -0,0 +1,184 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refers_to_static_cross_crate.rs:12:1 + | +LL | / const SLICE_MUT: &[u8; 1] = { +LL | | +LL | | +LL | | +LL | | unsafe { &static_cross_crate::ZERO } +LL | | }; + | |__^ type validation failed: encountered a reference pointing to a static variable + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc0──╼ │ ╾──╼ + } + +error: could not evaluate constant pattern + --> $DIR/const_refers_to_static_cross_crate.rs:47:9 + | +LL | SLICE_MUT => true, + | ^^^^^^^^^ + +error[E0080]: it is undefined behavior to use this value + --> $DIR/const_refers_to_static_cross_crate.rs:19:1 + | +LL | / const U8_MUT: &u8 = { +LL | | +LL | | +LL | | +LL | | unsafe { &static_cross_crate::ZERO[0] } +LL | | }; + | |__^ type validation failed: encountered a reference pointing to a static variable + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc0──╼ │ ╾──╼ + } + +error: could not evaluate constant pattern + --> $DIR/const_refers_to_static_cross_crate.rs:56:9 + | +LL | U8_MUT => true, + | ^^^^^^ + +warning: any use of this value will cause an error + --> $DIR/const_refers_to_static_cross_crate.rs:29:15 + | +LL | / const U8_MUT2: &u8 = { +LL | | unsafe { &(*static_cross_crate::ZERO_REF)[0] } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static +LL | | +LL | | +LL | | +LL | | +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/const_refers_to_static_cross_crate.rs:27:8 + | +LL | #[warn(const_err)] + | ^^^^^^^^^ + = 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 #71800 + +error: could not evaluate constant pattern + --> $DIR/const_refers_to_static_cross_crate.rs:67:9 + | +LL | U8_MUT2 => true, + | ^^^^^^^ + +warning: any use of this value will cause an error + --> $DIR/const_refers_to_static_cross_crate.rs:37:51 + | +LL | / const U8_MUT3: &u8 = { +LL | | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } + | | ^^^^^^^^^^^ constant accesses static +LL | | +LL | | +... | +LL | | +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/const_refers_to_static_cross_crate.rs:35:8 + | +LL | #[warn(const_err)] + | ^^^^^^^^^ + = 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 #71800 + +error: could not evaluate constant pattern + --> $DIR/const_refers_to_static_cross_crate.rs:75:9 + | +LL | U8_MUT3 => true, + | ^^^^^^^ + +error: could not evaluate constant pattern + --> $DIR/const_refers_to_static_cross_crate.rs:47:9 + | +LL | SLICE_MUT => true, + | ^^^^^^^^^ + +error: could not evaluate constant pattern + --> $DIR/const_refers_to_static_cross_crate.rs:56:9 + | +LL | U8_MUT => true, + | ^^^^^^ + +error: could not evaluate constant pattern + --> $DIR/const_refers_to_static_cross_crate.rs:67:9 + | +LL | U8_MUT2 => true, + | ^^^^^^^ + +error: could not evaluate constant pattern + --> $DIR/const_refers_to_static_cross_crate.rs:75:9 + | +LL | U8_MUT3 => true, + | ^^^^^^^ + +warning: skipping const checks + | +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static_cross_crate.rs:16:15 + | +LL | unsafe { &static_cross_crate::ZERO } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static_cross_crate.rs:16:15 + | +LL | unsafe { &static_cross_crate::ZERO } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static_cross_crate.rs:23:15 + | +LL | unsafe { &static_cross_crate::ZERO[0] } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static_cross_crate.rs:23:15 + | +LL | unsafe { &static_cross_crate::ZERO[0] } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static_cross_crate.rs:23:15 + | +LL | unsafe { &static_cross_crate::ZERO[0] } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static_cross_crate.rs:29:17 + | +LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static_cross_crate.rs:37:20 + | +LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static_cross_crate.rs:37:20 + | +LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static_cross_crate.rs:37:20 + | +LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check for `const_panic` feature + --> $DIR/const_refers_to_static_cross_crate.rs:37:77 + | +LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } + | ^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static_cross_crate.rs:37:20 + | +LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 10 previous errors; 3 warnings emitted + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr b/src/test/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr new file mode 100644 index 00000000000..62126ef2bab --- /dev/null +++ b/src/test/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr @@ -0,0 +1,56 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/mutable_references_err.rs:17:1 + | +LL | / const MUH: Meh = Meh { +LL | | x: &UnsafeCell::new(42), +LL | | }; + | |__^ type validation failed: encountered `UnsafeCell` in a `const` at .x. + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc2──╼ │ ╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/mutable_references_err.rs:27:1 + | +LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered `UnsafeCell` in a `const` at ...x + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─alloc6──╼ ╾─alloc7──╼ │ ╾──╼╾──╼ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/mutable_references_err.rs:31:1 + | +LL | const BLUNT: &mut i32 = &mut 42; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered mutable reference in a `const` + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + ╾─alloc10─╼ │ ╾──╼ + } + +warning: skipping const checks + | +help: skipping check that does not even have a feature gate + --> $DIR/mutable_references_err.rs:18:8 + | +LL | x: &UnsafeCell::new(42), + | ^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/mutable_references_err.rs:27:27 + | +LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/mutable_references_err.rs:31:25 + | +LL | const BLUNT: &mut i32 = &mut 42; + | ^^^^^^^ + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/std/alloc.32bit.stderr b/src/test/ui/consts/std/alloc.32bit.stderr new file mode 100644 index 00000000000..bb9ccbba376 --- /dev/null +++ b/src/test/ui/consts/std/alloc.32bit.stderr @@ -0,0 +1,14 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/alloc.rs:8:1 + | +LL | const LAYOUT_INVALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0 at .align_, but expected something greater or equal to 1 + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + 00 10 00 00 00 00 00 00 │ ........ + } + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/validate_never_arrays.32bit.stderr b/src/test/ui/consts/validate_never_arrays.32bit.stderr new file mode 100644 index 00000000000..2d1bba391e8 --- /dev/null +++ b/src/test/ui/consts/validate_never_arrays.32bit.stderr @@ -0,0 +1,36 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/validate_never_arrays.rs:4:1 + | +LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at .[0] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 4, align: 4) { + 01 00 00 00 │ .... + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/validate_never_arrays.rs:7:1 + | +LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at .[0] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + 01 00 00 00 01 00 00 00 │ ........ + } + +error[E0080]: it is undefined behavior to use this value + --> $DIR/validate_never_arrays.rs:8:1 + | +LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at .[0] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + 01 00 00 00 2a 00 00 00 │ ....*... + } + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0080`. From ce6658818da9844d7adb85a573952ba081b466ac Mon Sep 17 00:00:00 2001 From: JohnTitor Date: Wed, 31 Mar 2021 18:48:28 +0900 Subject: [PATCH 235/370] Add a regression test for issue-68830 --- .../issue-68830-spurious-diagnostics.rs | 23 +++++++++++++++++++ .../issue-68830-spurious-diagnostics.stderr | 9 ++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/test/ui/specialization/issue-68830-spurious-diagnostics.rs create mode 100644 src/test/ui/specialization/issue-68830-spurious-diagnostics.stderr diff --git a/src/test/ui/specialization/issue-68830-spurious-diagnostics.rs b/src/test/ui/specialization/issue-68830-spurious-diagnostics.rs new file mode 100644 index 00000000000..d11ec798332 --- /dev/null +++ b/src/test/ui/specialization/issue-68830-spurious-diagnostics.rs @@ -0,0 +1,23 @@ +// A regression test for #68830. This checks we don't emit +// a verbose `conflicting implementations` error. + +#![feature(specialization)] +#![allow(incomplete_features)] + +struct BadStruct { + err: MissingType //~ ERROR: cannot find type `MissingType` in this scope +} + +trait MyTrait { + fn foo(); +} + +impl MyTrait for D { + default fn foo() {} +} + +impl MyTrait for BadStruct { + fn foo() {} +} + +fn main() {} diff --git a/src/test/ui/specialization/issue-68830-spurious-diagnostics.stderr b/src/test/ui/specialization/issue-68830-spurious-diagnostics.stderr new file mode 100644 index 00000000000..833f61dca8c --- /dev/null +++ b/src/test/ui/specialization/issue-68830-spurious-diagnostics.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `MissingType` in this scope + --> $DIR/issue-68830-spurious-diagnostics.rs:8:10 + | +LL | err: MissingType + | ^^^^^^^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. From dbacfbc3681622d634233bcf36504ec898f91818 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 30 Mar 2021 14:26:40 +0000 Subject: [PATCH 236/370] Add a new normalization query just for mir constants --- compiler/rustc_infer/src/infer/resolve.rs | 5 +++ compiler/rustc_middle/src/mir/mod.rs | 11 +++++-- .../rustc_middle/src/mir/type_foldable.rs | 4 +++ compiler/rustc_middle/src/query/mod.rs | 7 +++++ compiler/rustc_middle/src/ty/erase_regions.rs | 5 +++ compiler/rustc_middle/src/ty/fold.rs | 5 +++ .../src/ty/normalize_erasing_regions.rs | 6 ++++ compiler/rustc_middle/src/ty/subst.rs | 5 +++ .../rustc_mir/src/monomorphize/collector.rs | 31 ++++++++++++++++++- compiler/rustc_mir/src/util/pretty.rs | 6 +++- compiler/rustc_query_impl/src/keys.rs | 9 ++++++ .../src/traits/query/normalize.rs | 5 +++ .../src/normalize_erasing_regions.rs | 27 +++++++++++----- .../associated-consts/defaults-cyclic-fail.rs | 2 +- .../const-eval/conditional_array_execution.rs | 2 +- .../const-eval/const-eval-query-stack.rs | 3 +- .../const-eval/const-eval-query-stack.stderr | 16 ++++++---- src/test/ui/consts/const-eval/issue-44578.rs | 2 +- .../missing-lifetimes-in-signature.nll.stderr | 11 ------- 19 files changed, 128 insertions(+), 34 deletions(-) delete mode 100644 src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index d72be0134fb..48b8ee17594 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -1,5 +1,6 @@ use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use super::{FixupError, FixupResult, InferCtxt, Span}; +use rustc_middle::mir; use rustc_middle::ty::fold::{TypeFolder, TypeVisitor}; use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable}; @@ -46,6 +47,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> { ct.super_fold_with(self) } } + + fn fold_mir_const(&mut self, constant: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { + constant.super_fold_with(self) + } } /// The opportunistic region resolver opportunistically resolves regions diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 807d6394800..5b637a39d17 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2410,7 +2410,8 @@ pub struct Constant<'tcx> { pub literal: ConstantKind<'tcx>, } -#[derive(Clone, Copy, PartialEq, PartialOrd, TyEncodable, TyDecodable, Hash, HashStable, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, TyEncodable, TyDecodable, Hash, HashStable, Debug)] +#[derive(Lift)] pub enum ConstantKind<'tcx> { /// This constant came from the type system Ty(&'tcx ty::Const<'tcx>), @@ -2709,7 +2710,13 @@ impl<'tcx> Display for Constant<'tcx> { ty::FnDef(..) => {} _ => write!(fmt, "const ")?, } - match self.literal { + Display::fmt(&self.literal, fmt) + } +} + +impl<'tcx> Display for ConstantKind<'tcx> { + fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { + match *self { ConstantKind::Ty(c) => pretty_print_const(c, fmt, true), ConstantKind::Val(val, ty) => pretty_print_const_value(val, ty, fmt, true), } diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index cb599277270..ceed4fd2467 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -348,6 +348,10 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> { + fn fold_with>(self, folder: &mut F) -> Self { + folder.fold_mir_const(self) + } + fn super_fold_with>(self, folder: &mut F) -> Self { match self { ConstantKind::Ty(c) => ConstantKind::Ty(c.fold_with(folder)), diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index fbd5af9d0a9..732df8bb6c5 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1482,6 +1482,13 @@ rustc_queries! { desc { "normalizing `{}`", goal.value } } + /// Do not call this query directly: invoke `normalize_erasing_regions` instead. + query normalize_mir_const_after_erasing_regions( + goal: ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>> + ) -> mir::ConstantKind<'tcx> { + desc { "normalizing `{}`", goal.value } + } + query implied_outlives_bounds( goal: CanonicalTyGoal<'tcx> ) -> Result< diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 4412ba9408c..468e433ecd6 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -1,3 +1,4 @@ +use crate::mir; use crate::ty::fold::{TypeFoldable, TypeFolder}; use crate::ty::{self, Ty, TyCtxt, TypeFlags}; @@ -65,4 +66,8 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { _ => self.tcx.lifetimes.re_erased, } } + + fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { + c.super_fold_with(self) + } } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index a6a1d1f73bb..029d3e1f237 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -30,6 +30,7 @@ //! //! These methods return true to indicate that the visitor has found what it is //! looking for, and does not need to visit anything else. +use crate::mir; use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags}; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -179,6 +180,10 @@ pub trait TypeFolder<'tcx>: Sized { fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { c.super_fold_with(self) } + + fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { + bug!("most type folders should not be folding MIR datastructures: {:?}", c) + } } pub trait TypeVisitor<'tcx>: Sized { diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 9d97815a5f1..2a8502cab41 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -7,6 +7,7 @@ //! `normalize_generic_arg_after_erasing_regions` query for each type //! or constant found within. (This underlying query is what is cached.) +use crate::mir; use crate::ty::fold::{TypeFoldable, TypeFolder}; use crate::ty::subst::{Subst, SubstsRef}; use crate::ty::{self, Ty, TyCtxt}; @@ -101,4 +102,9 @@ impl TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> { let arg = self.param_env.and(c.into()); self.tcx.normalize_generic_arg_after_erasing_regions(arg).expect_const() } + + fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { + let arg = self.param_env.and(c); + self.tcx.normalize_mir_const_after_erasing_regions(arg) + } } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 5d1b976ae97..becc09a4ce0 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -1,5 +1,6 @@ // Type substitutions. +use crate::mir; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::sty::{ClosureSubsts, GeneratorSubsts}; @@ -503,6 +504,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { c.super_fold_with(self) } } + + fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { + c.super_fold_with(self) + } } impl<'a, 'tcx> SubstFolder<'a, 'tcx> { diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index 5cc1d7082d1..fd5dbfb186e 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -184,7 +184,6 @@ use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::GrowableBitSet; -use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{AllocId, ConstValue}; use rustc_middle::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar}; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; @@ -193,6 +192,7 @@ use rustc_middle::mir::{self, Local, Location}; use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::{middle::codegen_fn_attrs::CodegenFnAttrFlags, mir::visit::TyContext}; use rustc_session::config::EntryFnType; use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP}; use smallvec::SmallVec; @@ -638,6 +638,35 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.super_rvalue(rvalue, location); } + /// This does not walk the constant, as it has been handled entirely here and trying + /// to walk it would attempt to evaluate the `ty::Const` inside, which doesn't necessarily + /// work, as some constants cannot be represented in the type system. + fn visit_constant(&mut self, constant: &mir::Constant<'tcx>, location: Location) { + let literal = self.monomorphize(constant.literal); + let val = match literal { + mir::ConstantKind::Val(val, _) => val, + mir::ConstantKind::Ty(ct) => match ct.val { + ty::ConstKind::Value(val) => val, + ty::ConstKind::Unevaluated(ct) => { + let param_env = ty::ParamEnv::reveal_all(); + match self.tcx.const_eval_resolve(param_env, ct, None) { + // The `monomorphize` call should have evaluated that constant already. + Ok(val) => val, + Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => return, + Err(ErrorHandled::TooGeneric) => span_bug!( + self.body.source_info(location).span, + "collection encountered polymorphic constant: {:?}", + literal + ), + } + } + _ => return, + }, + }; + collect_const_value(self.tcx, val, self.output); + self.visit_ty(literal.ty(), TyContext::Location(location)); + } + fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, location: Location) { debug!("visiting const {:?} @ {:?}", *constant, location); diff --git a/compiler/rustc_mir/src/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs index 8fa44e4ded3..3b88aec16b2 100644 --- a/compiler/rustc_mir/src/util/pretty.rs +++ b/compiler/rustc_mir/src/util/pretty.rs @@ -452,7 +452,11 @@ impl Visitor<'tcx> for ExtraComments<'tcx> { match literal { ConstantKind::Ty(literal) => self.push(&format!("+ literal: {:?}", literal)), ConstantKind::Val(val, ty) => { - self.push(&format!("+ literal: {:?}, {}", val, ty)) + // To keep the diffs small, we render this almost like we render ty::Const + self.push(&format!( + "+ literal: Const {{ ty: {}, val: Value({:?}) }}", + ty, val + )) } } } diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs index e467f419863..1fdb37398f9 100644 --- a/compiler/rustc_query_impl/src/keys.rs +++ b/compiler/rustc_query_impl/src/keys.rs @@ -255,6 +255,15 @@ impl<'tcx> Key for GenericArg<'tcx> { } } +impl<'tcx> Key for mir::ConstantKind<'tcx> { + fn query_crate(&self) -> CrateNum { + LOCAL_CRATE + } + fn default_span(&self, _: TyCtxt<'_>) -> Span { + DUMMY_SP + } +} + impl<'tcx> Key for &'tcx ty::Const<'tcx> { fn query_crate(&self) -> CrateNum { LOCAL_CRATE diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index c908e1418c1..eb7ea8715c2 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -10,6 +10,7 @@ use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal}; use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::traits::Normalized; +use rustc_middle::mir; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -214,4 +215,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { let constant = constant.super_fold_with(self); constant.eval(self.infcx.tcx, self.param_env) } + + fn fold_mir_const(&mut self, constant: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { + constant.super_fold_with(self) + } } diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 1213e553908..5ad0684fe6e 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -1,24 +1,35 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::subst::GenericArg; use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable}; use rustc_trait_selection::traits::query::normalize::AtExt; use rustc_trait_selection::traits::{Normalized, ObligationCause}; use std::sync::atomic::Ordering; crate fn provide(p: &mut Providers) { - *p = Providers { normalize_generic_arg_after_erasing_regions, ..*p }; + *p = Providers { + normalize_generic_arg_after_erasing_regions: |tcx, goal| { + debug!("normalize_generic_arg_after_erasing_regions(goal={:#?})", goal); + + tcx.sess + .perf_stats + .normalize_generic_arg_after_erasing_regions + .fetch_add(1, Ordering::Relaxed); + normalize_after_erasing_regions(tcx, goal) + }, + normalize_mir_const_after_erasing_regions: |tcx, goal| { + normalize_after_erasing_regions(tcx, goal) + }, + ..*p + }; } -fn normalize_generic_arg_after_erasing_regions<'tcx>( +#[instrument(level = "debug", skip(tcx))] +fn normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + Copy>( tcx: TyCtxt<'tcx>, - goal: ParamEnvAnd<'tcx, GenericArg<'tcx>>, -) -> GenericArg<'tcx> { - debug!("normalize_generic_arg_after_erasing_regions(goal={:#?})", goal); - + goal: ParamEnvAnd<'tcx, T>, +) -> T { let ParamEnvAnd { param_env, value } = goal; - tcx.sess.perf_stats.normalize_generic_arg_after_erasing_regions.fetch_add(1, Ordering::Relaxed); tcx.infer_ctxt().enter(|infcx| { let cause = ObligationCause::dummy(); match infcx.at(&cause, param_env).normalize(value) { diff --git a/src/test/ui/associated-consts/defaults-cyclic-fail.rs b/src/test/ui/associated-consts/defaults-cyclic-fail.rs index 9fb1bbebc96..d9ff0b09c28 100644 --- a/src/test/ui/associated-consts/defaults-cyclic-fail.rs +++ b/src/test/ui/associated-consts/defaults-cyclic-fail.rs @@ -1,5 +1,5 @@ // build-fail -//~^ ERROR cycle detected when normalizing `<() as Tr>::A` +//~^ ERROR cycle detected when normalizing // Cyclic assoc. const defaults don't error unless *used* trait Tr { diff --git a/src/test/ui/consts/const-eval/conditional_array_execution.rs b/src/test/ui/consts/const-eval/conditional_array_execution.rs index 9b99a685b63..bd517e568ea 100644 --- a/src/test/ui/consts/const-eval/conditional_array_execution.rs +++ b/src/test/ui/consts/const-eval/conditional_array_execution.rs @@ -10,7 +10,7 @@ const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; fn main() { println!("{}", FOO); - //~^ ERROR + //~^ ERROR evaluation of constant value failed //~| WARN erroneous constant used [const_err] //~| WARN this was previously accepted by the compiler but is being phased out } diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.rs b/src/test/ui/consts/const-eval/const-eval-query-stack.rs index 8c3959cc11a..017d49d8b26 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.rs +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.rs @@ -1,5 +1,4 @@ -//~ERROR constructed but no error reported -// compile-flags: -Ztreat-err-as-bug=2 +// compile-flags: -Ztreat-err-as-bug=1 // build-fail // failure-status: 101 // rustc-env:RUST_BACKTRACE=1 diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr index 6a205ce9787..4f16cd96a96 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr @@ -1,5 +1,5 @@ warning: any use of this value will cause an error - --> $DIR/const-eval-query-stack.rs:20:16 + --> $DIR/const-eval-query-stack.rs:19:16 | LL | const X: i32 = 1 / 0; | ---------------^^^^^- @@ -7,7 +7,7 @@ LL | const X: i32 = 1 / 0; | attempt to divide `1_i32` by zero | note: the lint level is defined here - --> $DIR/const-eval-query-stack.rs:19:8 + --> $DIR/const-eval-query-stack.rs:18:8 | LL | #[warn(const_err)] | ^^^^^^^^^ @@ -15,12 +15,16 @@ LL | #[warn(const_err)] = note: for more information, see issue #71800 error[E0080]: evaluation of constant value failed - --> $DIR/const-eval-query-stack.rs:24:28 + --> $DIR/const-eval-query-stack.rs:23:28 | LL | let x: &'static i32 = &X; | ^ referenced constant has errors + query stack during panic: -#0 [normalize_generic_arg_after_erasing_regions] normalizing `main::promoted[1]` -#1 [optimized_mir] optimizing MIR for `main` -#2 [collect_and_partition_mono_items] collect_and_partition_mono_items +#0 [eval_to_allocation_raw] const-evaluating + checking `main::promoted[1]` +#1 [eval_to_const_value_raw] simplifying constant for the type system `main::promoted[1]` +#2 [eval_to_const_value_raw] simplifying constant for the type system `main::promoted[1]` +#3 [normalize_mir_const_after_erasing_regions] normalizing `main::promoted[1]` +#4 [optimized_mir] optimizing MIR for `main` +#5 [collect_and_partition_mono_items] collect_and_partition_mono_items end of query stack diff --git a/src/test/ui/consts/const-eval/issue-44578.rs b/src/test/ui/consts/const-eval/issue-44578.rs index 79f1301a2f9..a88e2197048 100644 --- a/src/test/ui/consts/const-eval/issue-44578.rs +++ b/src/test/ui/consts/const-eval/issue-44578.rs @@ -25,5 +25,5 @@ impl Foo for u16 { fn main() { println!("{}", as Foo>::AMT); - //~^ ERROR evaluation of constant value failed [E0080] + //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr deleted file mode 100644 index 916a6c2bf12..00000000000 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/missing-lifetimes-in-signature.rs:36:11 - | -LL | fn baz(g: G, dest: &mut T) -> impl FnOnce() + '_ - | - ^^ undeclared lifetime - | | - | help: consider introducing lifetime `'a` here: `'a,` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0261`. From 4e8edfb5c2a995a13cb15ee7a0e7e3bbdd3e8574 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 30 Mar 2021 16:08:53 +0000 Subject: [PATCH 237/370] Forward some layouts to prevent recomputation --- compiler/rustc_mir/src/interpret/intrinsics.rs | 2 +- compiler/rustc_mir/src/interpret/operand.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir/src/interpret/intrinsics.rs b/compiler/rustc_mir/src/interpret/intrinsics.rs index 9804421c1fc..d74ef66a4b2 100644 --- a/compiler/rustc_mir/src/interpret/intrinsics.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics.rs @@ -171,7 +171,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; let val = self.tcx.const_eval_global_id(self.param_env, gid, Some(self.tcx.span))?; - let val = self.const_val_to_op(val, ty, None)?; + let val = self.const_val_to_op(val, ty, Some(dest.layout))?; self.copy_op(&val, dest)?; } diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index c70b57e631a..c987028f13e 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -578,7 +578,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { match val { mir::ConstantKind::Ty(ct) => self.const_to_op(ct, layout), - mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, ty, None), + mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, ty, layout), } } From d139968d1959df425be9390892a3b4387c950aac Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 31 Mar 2021 09:13:25 +0000 Subject: [PATCH 238/370] bail out early when substituting mir constants that don't need substituting --- compiler/rustc_middle/src/ty/subst.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index becc09a4ce0..48db2d11f52 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -506,6 +506,9 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { } fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { + if !c.needs_subst() { + return c; + } c.super_fold_with(self) } } From 74af01b989a798ddd7d2b8e368f460db27a7c658 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 31 Mar 2021 11:33:15 +0000 Subject: [PATCH 239/370] Revert tests --- .../ui/associated-consts/defaults-cyclic-fail.rs | 2 +- .../consts/const-eval/const-eval-query-stack.rs | 3 ++- .../const-eval/const-eval-query-stack.stderr | 16 ++++++---------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/test/ui/associated-consts/defaults-cyclic-fail.rs b/src/test/ui/associated-consts/defaults-cyclic-fail.rs index d9ff0b09c28..9fb1bbebc96 100644 --- a/src/test/ui/associated-consts/defaults-cyclic-fail.rs +++ b/src/test/ui/associated-consts/defaults-cyclic-fail.rs @@ -1,5 +1,5 @@ // build-fail -//~^ ERROR cycle detected when normalizing +//~^ ERROR cycle detected when normalizing `<() as Tr>::A` // Cyclic assoc. const defaults don't error unless *used* trait Tr { diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.rs b/src/test/ui/consts/const-eval/const-eval-query-stack.rs index 017d49d8b26..8c3959cc11a 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.rs +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.rs @@ -1,4 +1,5 @@ -// compile-flags: -Ztreat-err-as-bug=1 +//~ERROR constructed but no error reported +// compile-flags: -Ztreat-err-as-bug=2 // build-fail // failure-status: 101 // rustc-env:RUST_BACKTRACE=1 diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr index 4f16cd96a96..e6fecef9fb3 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr @@ -1,5 +1,5 @@ warning: any use of this value will cause an error - --> $DIR/const-eval-query-stack.rs:19:16 + --> $DIR/const-eval-query-stack.rs:20:16 | LL | const X: i32 = 1 / 0; | ---------------^^^^^- @@ -7,7 +7,7 @@ LL | const X: i32 = 1 / 0; | attempt to divide `1_i32` by zero | note: the lint level is defined here - --> $DIR/const-eval-query-stack.rs:18:8 + --> $DIR/const-eval-query-stack.rs:19:8 | LL | #[warn(const_err)] | ^^^^^^^^^ @@ -15,16 +15,12 @@ LL | #[warn(const_err)] = note: for more information, see issue #71800 error[E0080]: evaluation of constant value failed - --> $DIR/const-eval-query-stack.rs:23:28 + --> $DIR/const-eval-query-stack.rs:24:28 | LL | let x: &'static i32 = &X; | ^ referenced constant has errors - query stack during panic: -#0 [eval_to_allocation_raw] const-evaluating + checking `main::promoted[1]` -#1 [eval_to_const_value_raw] simplifying constant for the type system `main::promoted[1]` -#2 [eval_to_const_value_raw] simplifying constant for the type system `main::promoted[1]` -#3 [normalize_mir_const_after_erasing_regions] normalizing `main::promoted[1]` -#4 [optimized_mir] optimizing MIR for `main` -#5 [collect_and_partition_mono_items] collect_and_partition_mono_items +#0 [normalize_mir_const_after_erasing_regions] normalizing `main::promoted[1]` +#1 [optimized_mir] optimizing MIR for `main` +#2 [collect_and_partition_mono_items] collect_and_partition_mono_items end of query stack From e7821e5475b0628eb9cb87534dad131c577de03c Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Wed, 31 Mar 2021 12:11:24 +0200 Subject: [PATCH 240/370] Fix documentation of conversion from String to OsString --- library/std/src/ffi/os_str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 14914287cb1..6fc97d628d7 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -361,7 +361,7 @@ impl OsString { impl From for OsString { /// Converts a [`String`] into a [`OsString`]. /// - /// The conversion copies the data, and includes an allocation on the heap. + /// This conversion does not allocate or copy memory. #[inline] fn from(s: String) -> OsString { OsString { inner: Buf::from_string(s) } From f5e7dbb20a4090f089f09a116ab7a75ad4296398 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Wed, 31 Mar 2021 12:24:37 +0200 Subject: [PATCH 241/370] Add a few missing links, fix a typo --- library/std/src/ffi/os_str.rs | 2 +- library/std/src/path.rs | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 6fc97d628d7..ecaab670349 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -858,7 +858,7 @@ impl From> for Box { #[stable(feature = "os_string_from_box", since = "1.18.0")] impl From> for OsString { - /// Converts a [`Box`]`<`[`OsStr`]`>` into a `OsString` without copying or + /// Converts a [`Box`]`<`[`OsStr`]`>` into an [`OsString`] without copying or /// allocating. #[inline] fn from(boxed: Box) -> OsString { diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 57c892f32b1..984c9b41567 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1467,7 +1467,7 @@ impl> From<&T> for PathBuf { #[stable(feature = "rust1", since = "1.0.0")] impl From for PathBuf { - /// Converts a `OsString` into a `PathBuf` + /// Converts a [`OsString`] into a [`PathBuf`] /// /// This conversion does not allocate or copy memory. #[inline] @@ -1478,7 +1478,7 @@ impl From for PathBuf { #[stable(feature = "from_path_buf_for_os_string", since = "1.14.0")] impl From for OsString { - /// Converts a `PathBuf` into a `OsString` + /// Converts a [`PathBuf`] into a [`OsString`] /// /// This conversion does not allocate or copy memory. #[inline] @@ -1489,7 +1489,7 @@ impl From for OsString { #[stable(feature = "rust1", since = "1.0.0")] impl From for PathBuf { - /// Converts a `String` into a `PathBuf` + /// Converts a [`String`] into a [`PathBuf`] /// /// This conversion does not allocate or copy memory. #[inline] @@ -1595,7 +1595,7 @@ impl<'a> From> for PathBuf { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Arc { - /// Converts a `PathBuf` into an `Arc` by moving the `PathBuf` data into a new `Arc` buffer. + /// Converts a [`PathBuf`] into an [`Arc`] by moving the [`PathBuf`] data into a new [`Arc`] buffer. #[inline] fn from(s: PathBuf) -> Arc { let arc: Arc = Arc::from(s.into_os_string()); @@ -1605,7 +1605,7 @@ impl From for Arc { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From<&Path> for Arc { - /// Converts a `Path` into an `Arc` by copying the `Path` data into a new `Arc` buffer. + /// Converts a [`Path`] into an [`Arc`] by copying the [`Path`] data into a new [`Arc`] buffer. #[inline] fn from(s: &Path) -> Arc { let arc: Arc = Arc::from(s.as_os_str()); @@ -1615,7 +1615,7 @@ impl From<&Path> for Arc { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Rc { - /// Converts a `PathBuf` into an `Rc` by moving the `PathBuf` data into a new `Rc` buffer. + /// Converts a [`PathBuf`] into an [`Rc`] by moving the [`PathBuf`] data into a new `Rc` buffer. #[inline] fn from(s: PathBuf) -> Rc { let rc: Rc = Rc::from(s.into_os_string()); @@ -1625,7 +1625,7 @@ impl From for Rc { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From<&Path> for Rc { - /// Converts a `Path` into an `Rc` by copying the `Path` data into a new `Rc` buffer. + /// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new `Rc` buffer. #[inline] fn from(s: &Path) -> Rc { let rc: Rc = Rc::from(s.as_os_str()); From 4955d755d3ffdfecfd2c22139c65fe1a10d60939 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Thu, 7 Jan 2021 00:41:55 -0500 Subject: [PATCH 242/370] Some rebinds and dummys --- .../rustc_infer/src/infer/higher_ranked/mod.rs | 5 ++++- compiler/rustc_middle/src/ty/relate.rs | 7 +++---- .../rustc_mir/src/borrow_check/type_check/mod.rs | 2 +- compiler/rustc_mir/src/monomorphize/mod.rs | 8 +++++--- .../src/traits/auto_trait.rs | 5 +++-- .../src/traits/object_safety.rs | 16 ++++++++++------ .../src/traits/select/confirmation.rs | 2 +- compiler/rustc_typeck/src/astconv/mod.rs | 2 +- compiler/rustc_typeck/src/bounds.rs | 2 +- 9 files changed, 29 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index e794903fca3..679e98bada2 100644 --- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs @@ -50,7 +50,10 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> { debug!("higher_ranked_sub: OK result={:?}", result); - Ok(ty::Binder::bind(result)) + // We related `a_prime` and `b_prime`, which just had any bound vars + // replaced with placeholders or infer vars, respectively. Relating + // them should not introduce new bound vars. + Ok(ty::Binder::dummy(result)) }) } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index e2bbb31263a..76ba07864cf 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -619,10 +619,9 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List Ok(ty::Binder::bind(Trait( - relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), - ))), - (Projection(a), Projection(b)) => Ok(ty::Binder::bind(Projection( + (Trait(a), Trait(b)) => Ok(ep_a + .rebind(Trait(relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder()))), + (Projection(a), Projection(b)) => Ok(ep_a.rebind(Projection( relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), ))), (AutoTrait(a), AutoTrait(b)) if a == b => Ok(ep_a.rebind(AutoTrait(a))), diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs index fddd1401868..3248554e204 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -2028,7 +2028,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { traits::ObligationCauseCode::RepeatVec(is_const_fn), ), self.param_env, - ty::Binder::bind(ty::TraitRef::new( + ty::Binder::dummy(ty::TraitRef::new( self.tcx().require_lang_item( LangItem::Copy, Some(self.last_span), diff --git a/compiler/rustc_mir/src/monomorphize/mod.rs b/compiler/rustc_mir/src/monomorphize/mod.rs index d2586f0f84d..fd3f3b3a080 100644 --- a/compiler/rustc_mir/src/monomorphize/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/mod.rs @@ -1,6 +1,6 @@ use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_hir::lang_items::LangItem; @@ -8,14 +8,16 @@ pub mod collector; pub mod partitioning; pub mod polymorphize; -pub fn custom_coerce_unsize_info<'tcx>( +fn custom_coerce_unsize_info<'tcx>( tcx: TyCtxt<'tcx>, source_ty: Ty<'tcx>, target_ty: Ty<'tcx>, ) -> CustomCoerceUnsized { let def_id = tcx.require_lang_item(LangItem::CoerceUnsized, None); - let trait_ref = ty::Binder::bind(ty::TraitRef { + debug_assert!(!source_ty.has_escaping_bound_vars()); + debug_assert!(!target_ty.has_escaping_bound_vars()); + let trait_ref = ty::Binder::dummy(ty::TraitRef { def_id, substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]), }); diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index b38e3fbaab4..cb66dc7e5d9 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -82,9 +82,10 @@ impl<'tcx> AutoTraitFinder<'tcx> { ) -> AutoTraitResult { let tcx = self.tcx; + debug_assert!(!ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef { def_id: trait_did, substs: tcx.mk_substs_trait(ty, &[]) }; - let trait_pred = ty::Binder::bind(trait_ref); + let trait_pred = ty::Binder::dummy(trait_ref); let bail_out = tcx.infer_ctxt().enter(|infcx| { let mut selcx = SelectionContext::with_negative(&infcx, true); @@ -280,7 +281,7 @@ impl AutoTraitFinder<'tcx> { let mut already_visited = FxHashSet::default(); let mut predicates = VecDeque::new(); - predicates.push_back(ty::Binder::bind(ty::TraitPredicate { + predicates.push_back(ty::Binder::dummy(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: trait_did, substs: infcx.tcx.mk_substs_trait(ty, &[]), diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 7de20e477fe..b5a458db607 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -757,7 +757,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( struct IllegalSelfTypeVisitor<'tcx> { tcx: TyCtxt<'tcx>, trait_def_id: DefId, - supertraits: Option>>, + supertraits: Option>, } impl<'tcx> TypeVisitor<'tcx> for IllegalSelfTypeVisitor<'tcx> { @@ -778,8 +778,10 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( // Compute supertraits of current trait lazily. if self.supertraits.is_none() { let trait_ref = - ty::Binder::bind(ty::TraitRef::identity(self.tcx, self.trait_def_id)); - self.supertraits = Some(traits::supertraits(self.tcx, trait_ref).collect()); + ty::Binder::dummy(ty::TraitRef::identity(self.tcx, self.trait_def_id)); + self.supertraits = Some( + traits::supertraits(self.tcx, trait_ref).map(|t| t.def_id()).collect(), + ); } // Determine whether the trait reference `Foo as @@ -790,9 +792,11 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( // direct equality here because all of these types // are part of the formal parameter listing, and // hence there should be no inference variables. - let projection_trait_ref = ty::Binder::bind(data.trait_ref(self.tcx)); - let is_supertrait_of_current_trait = - self.supertraits.as_ref().unwrap().contains(&projection_trait_ref); + let is_supertrait_of_current_trait = self + .supertraits + .as_ref() + .unwrap() + .contains(&data.trait_ref(self.tcx).def_id); if is_supertrait_of_current_trait { ControlFlow::CONTINUE // do not walk contained types, do not report error, do collect $200 diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 272930f6bb9..0dc0dd871fe 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -748,7 +748,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause, obligation.recursion_depth + 1, obligation.param_env, - ty::Binder::bind(outlives).to_predicate(tcx), + obligation.predicate.rebind(outlives).to_predicate(tcx), )); } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index dbc518da8c8..183dab39e9e 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1090,7 +1090,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let late_bound_in_trait_ref = tcx.collect_constrained_late_bound_regions(&projection_ty); let late_bound_in_ty = - tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(ty)); + tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(ty)); debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref); debug!("late_bound_in_ty = {:?}", late_bound_in_ty); diff --git a/compiler/rustc_typeck/src/bounds.rs b/compiler/rustc_typeck/src/bounds.rs index 7ba90ad8819..3bbf0ba63b8 100644 --- a/compiler/rustc_typeck/src/bounds.rs +++ b/compiler/rustc_typeck/src/bounds.rs @@ -57,7 +57,7 @@ impl<'tcx> Bounds<'tcx> { // If it could be sized, and is, add the `Sized` predicate. let sized_predicate = self.implicitly_sized.and_then(|span| { tcx.lang_items().sized_trait().map(|sized| { - let trait_ref = ty::Binder::bind(ty::TraitRef { + let trait_ref = ty::Binder::dummy(ty::TraitRef { def_id: sized, substs: tcx.mk_substs_trait(param_ty, &[]), }); From 97a22a4f9cee6d48d0dad51e638c5f2306de084f Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Mon, 1 Jun 2020 19:23:23 -0400 Subject: [PATCH 243/370] Add u32 for bound variables to Binder --- compiler/rustc_middle/src/traits/mod.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 4 ++-- compiler/rustc_middle/src/ty/sty.rs | 21 +++++++++++---------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 90b82020551..922d14bc2f5 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -341,7 +341,7 @@ impl ObligationCauseCode<'_> { // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(ObligationCauseCode<'_>, 32); +static_assert_size!(ObligationCauseCode<'_>, 40); #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum StatementAsExpression { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c0025cf3fc8..8fc35193498 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -302,7 +302,7 @@ impl<'tcx> TyS<'tcx> { // `TyS` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(TyS<'_>, 32); +static_assert_size!(TyS<'_>, 40); impl<'tcx> Ord for TyS<'tcx> { fn cmp(&self, other: &TyS<'tcx>) -> Ordering { @@ -366,7 +366,7 @@ crate struct PredicateInner<'tcx> { } #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(PredicateInner<'_>, 40); +static_assert_size!(PredicateInner<'_>, 48); #[derive(Clone, Copy, Lift)] pub struct Predicate<'tcx> { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index b8fe7aa7fd0..c7896d2b1e8 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -232,7 +232,7 @@ impl TyKind<'tcx> { // `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(TyKind<'_>, 24); +static_assert_size!(TyKind<'_>, 32); /// A closure can be modeled as a struct that looks like: /// @@ -957,7 +957,7 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> { /// /// `Decodable` and `Encodable` are implemented for `Binder` using the `impl_binder_encode_decode!` macro. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub struct Binder(T); +pub struct Binder(T, u32); impl Binder { /// Wraps `value` in a binder, asserting that `value` does not @@ -969,12 +969,12 @@ impl Binder { T: TypeFoldable<'tcx>, { debug_assert!(!value.has_escaping_bound_vars()); - Binder(value) + Binder(value, 0) } /// Wraps `value` in a binder, binding higher-ranked vars (if any). pub fn bind(value: T) -> Binder { - Binder(value) + Binder(value, 0) } /// Skips the binder and returns the "bound" value. This is a @@ -998,7 +998,7 @@ impl Binder { } pub fn as_ref(&self) -> Binder<&T> { - Binder(&self.0) + Binder(&self.0, self.1) } pub fn map_bound_ref(&self, f: F) -> Binder @@ -1012,7 +1012,7 @@ impl Binder { where F: FnOnce(T) -> U, { - Binder(f(self.0)) + Binder(f(self.0), self.1) } /// Wraps a `value` in a binder, using the same bound variables as the @@ -1025,7 +1025,7 @@ impl Binder { /// because bound vars aren't allowed to change here, whereas they are /// in `bind`. This may be (debug) asserted in the future. pub fn rebind(&self, value: U) -> Binder { - Binder(value) + Binder(value, self.1) } /// Unwraps and returns the value within, but only if it contains @@ -1056,7 +1056,7 @@ impl Binder { where F: FnOnce(T, U) -> R, { - Binder(f(self.0, u.0)) + Binder(f(self.0, u.0), self.1) } /// Splits the contents into two things that share the same binder @@ -1070,13 +1070,14 @@ impl Binder { F: FnOnce(T) -> (U, V), { let (u, v) = f(self.0); - (Binder(u), Binder(v)) + (Binder(u, self.1), Binder(v, self.1)) } } impl Binder> { pub fn transpose(self) -> Option> { - self.0.map(Binder) + let bound_vars = self.1; + self.0.map(|v| Binder(v, bound_vars)) } } From 7509aa108c6bb852062e72de6fef5297f0d624e9 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Wed, 31 Mar 2021 16:08:20 +0200 Subject: [PATCH 244/370] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More links, one more occurrence of “a OsString” Co-authored-by: Yuki Okushi --- library/std/src/path.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 984c9b41567..f4020a42879 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1467,7 +1467,7 @@ impl> From<&T> for PathBuf { #[stable(feature = "rust1", since = "1.0.0")] impl From for PathBuf { - /// Converts a [`OsString`] into a [`PathBuf`] + /// Converts an [`OsString`] into a [`PathBuf`] /// /// This conversion does not allocate or copy memory. #[inline] @@ -1478,7 +1478,7 @@ impl From for PathBuf { #[stable(feature = "from_path_buf_for_os_string", since = "1.14.0")] impl From for OsString { - /// Converts a [`PathBuf`] into a [`OsString`] + /// Converts a [`PathBuf`] into an [`OsString`] /// /// This conversion does not allocate or copy memory. #[inline] From 74851f4cf3ab455ed92e6f762ac3d50f37bc4daf Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Tue, 2 Jun 2020 17:10:22 -0400 Subject: [PATCH 245/370] count bound vars --- compiler/rustc_middle/src/ty/fold.rs | 48 +++++++++++++++++++++++++ compiler/rustc_middle/src/ty/sty.rs | 52 ++++++++++++++++++++++++---- 2 files changed, 93 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index a6a1d1f73bb..15ce0ad3970 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -888,6 +888,54 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { #[derive(Debug, PartialEq, Eq, Copy, Clone)] struct FoundFlags; +crate struct CountBoundVars { + crate outer_index: ty::DebruijnIndex, + crate bound_tys: FxHashSet, + crate bound_regions: FxHashSet, + crate bound_consts: FxHashSet, +} + +impl<'tcx> TypeVisitor<'tcx> for CountBoundVars { + type BreakTy = (); + + fn visit_binder>(&mut self, t: &Binder) -> ControlFlow { + self.outer_index.shift_in(1); + let result = t.super_visit_with(self); + self.outer_index.shift_out(1); + result + } + + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + match t.kind { + ty::Bound(debruijn, ty) if debruijn == self.outer_index => { + self.bound_tys.insert(ty); + ControlFlow::CONTINUE + } + _ => t.super_visit_with(self), + } + } + + fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { + match r { + ty::ReLateBound(debruijn, re) if *debruijn == self.outer_index => { + self.bound_regions.insert(*re); + ControlFlow::CONTINUE + } + _ => r.super_visit_with(self), + } + } + + fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> ControlFlow { + match ct.val { + ty::ConstKind::Bound(debruijn, c) if debruijn == self.outer_index => { + self.bound_consts.insert(c); + ControlFlow::CONTINUE + } + _ => ct.super_visit_with(self), + } + } +} + // FIXME: Optimize for checking for infer flags struct HasTypeFlagsVisitor { flags: ty::TypeFlags, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c7896d2b1e8..7c7afc0b296 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -959,24 +959,58 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> { #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub struct Binder(T, u32); -impl Binder { +impl<'tcx, T> Binder +where + T: TypeFoldable<'tcx>, +{ /// Wraps `value` in a binder, asserting that `value` does not /// contain any bound vars that would be bound by the /// binder. This is commonly used to 'inject' a value T into a /// different binding level. - pub fn dummy<'tcx>(value: T) -> Binder - where - T: TypeFoldable<'tcx>, - { + pub fn dummy(value: T) -> Binder { debug_assert!(!value.has_escaping_bound_vars()); Binder(value, 0) } /// Wraps `value` in a binder, binding higher-ranked vars (if any). pub fn bind(value: T) -> Binder { - Binder(value, 0) - } + use crate::ty::fold::CountBoundVars; + use rustc_data_structures::fx::FxHashSet; + let mut counter = CountBoundVars { + outer_index: ty::INNERMOST, + bound_tys: FxHashSet::default(), + bound_regions: FxHashSet::default(), + bound_consts: FxHashSet::default(), + }; + value.visit_with(&mut counter); + let bound_tys = counter.bound_tys.len(); + let bound_regions = if !counter.bound_regions.is_empty() { + let mut env = false; + let mut anons = FxHashSet::default(); + let mut named = FxHashSet::default(); + for br in counter.bound_regions { + match br.kind { + ty::BrAnon(idx) => { + anons.insert(idx); + } + ty::BrNamed(def_id, _) => { + named.insert(def_id); + } + ty::BrEnv => env = true, + } + } + (if env { 1 } else { 0 }) + anons.len() + named.len() + } else { + 0 + }; + let bound_consts = counter.bound_consts.len(); + let bound_vars = bound_tys + bound_regions + bound_consts; + Binder(value, bound_vars as u32) + } +} + +impl Binder { /// Skips the binder and returns the "bound" value. This is a /// risky thing to do because it's easy to get confused about /// De Bruijn indices and the like. It is usually better to @@ -997,6 +1031,10 @@ impl Binder { self.0 } + pub fn bound_vars(&self) -> u32 { + self.1 + } + pub fn as_ref(&self) -> Binder<&T> { Binder(&self.0, self.1) } From 62a49c3bb8e0c82ee40b482f08a21a65f90b874b Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Mon, 5 Oct 2020 16:51:33 -0400 Subject: [PATCH 246/370] Add tcx lifetime to Binder --- .../src/infer/canonical/canonicalizer.rs | 2 +- compiler/rustc_infer/src/infer/combine.rs | 12 +-- compiler/rustc_infer/src/infer/equate.rs | 6 +- .../src/infer/error_reporting/mod.rs | 2 +- compiler/rustc_infer/src/infer/glb.rs | 6 +- .../src/infer/higher_ranked/mod.rs | 8 +- compiler/rustc_infer/src/infer/lub.rs | 6 +- compiler/rustc_infer/src/infer/mod.rs | 2 +- .../rustc_infer/src/infer/nll_relate/mod.rs | 16 ++-- compiler/rustc_infer/src/infer/sub.rs | 6 +- compiler/rustc_infer/src/traits/mod.rs | 2 +- compiler/rustc_lint/src/context.rs | 2 +- compiler/rustc_middle/src/ich/impls_ty.rs | 2 +- compiler/rustc_middle/src/infer/canonical.rs | 2 +- compiler/rustc_middle/src/ty/_match.rs | 6 +- compiler/rustc_middle/src/ty/codec.rs | 14 ++-- compiler/rustc_middle/src/ty/context.rs | 34 ++++---- compiler/rustc_middle/src/ty/erase_regions.rs | 2 +- compiler/rustc_middle/src/ty/error.rs | 4 +- compiler/rustc_middle/src/ty/flags.rs | 6 +- compiler/rustc_middle/src/ty/fold.rs | 59 +++++++++---- compiler/rustc_middle/src/ty/mod.rs | 32 ++++---- .../src/ty/normalize_erasing_regions.rs | 4 +- compiler/rustc_middle/src/ty/print/mod.rs | 4 +- compiler/rustc_middle/src/ty/print/pretty.rs | 46 +++++------ compiler/rustc_middle/src/ty/relate.rs | 16 ++-- .../rustc_middle/src/ty/structural_impls.rs | 14 ++-- compiler/rustc_middle/src/ty/sty.rs | 82 +++++++++---------- compiler/rustc_middle/src/ty/subst.rs | 5 +- compiler/rustc_middle/src/ty/util.rs | 2 +- .../src/borrow_check/universal_regions.rs | 6 +- .../src/interpret/intrinsics/type_name.rs | 2 +- compiler/rustc_symbol_mangling/src/legacy.rs | 2 +- compiler/rustc_symbol_mangling/src/v0.rs | 4 +- .../rustc_trait_selection/src/opaque_types.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 30 +++---- .../src/traits/select/confirmation.rs | 2 +- .../src/traits/select/mod.rs | 11 ++- .../rustc_trait_selection/src/traits/util.rs | 4 +- .../rustc_trait_selection/src/traits/wf.rs | 4 +- compiler/rustc_traits/src/chalk/lowering.rs | 17 ++-- compiler/rustc_typeck/src/astconv/mod.rs | 2 +- compiler/rustc_typeck/src/bounds.rs | 2 +- compiler/rustc_typeck/src/check/dropck.rs | 6 +- .../rustc_typeck/src/check/method/confirm.rs | 2 +- .../rustc_typeck/src/check/method/probe.rs | 2 +- 46 files changed, 274 insertions(+), 228 deletions(-) diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index aa4fd055d5e..392553a80f9 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -293,7 +293,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { self.tcx } - fn fold_binder(&mut self, t: ty::Binder) -> ty::Binder + fn fold_binder(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T> where T: TypeFoldable<'tcx>, { diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index ffe947d209d..debf1082537 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -545,9 +545,9 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { fn binders( &mut self, - a: ty::Binder, - b: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> + a: ty::Binder<'tcx, T>, + b: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> where T: Relate<'tcx>, { @@ -840,9 +840,9 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { fn binders( &mut self, - a: ty::Binder, - b: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> + a: ty::Binder<'tcx, T>, + b: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> where T: Relate<'tcx>, { diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index 7c388b5503e..45ba50bb634 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -124,9 +124,9 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> { fn binders( &mut self, - a: ty::Binder, - b: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> + a: ty::Binder<'tcx, T>, + b: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> where T: Relate<'tcx>, { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index a18c9569a8c..a91bd9ce2ff 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -514,7 +514,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { fn print_dyn_existential( self, - _predicates: &'tcx ty::List>>, + _predicates: &'tcx ty::List>>, ) -> Result { Err(NonTrivialPath) } diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index ccba904df9e..02662043dba 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -85,9 +85,9 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> { fn binders( &mut self, - a: ty::Binder, - b: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> + a: ty::Binder<'tcx, T>, + b: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> where T: Relate<'tcx>, { diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index 679e98bada2..d460222df8a 100644 --- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs @@ -11,10 +11,10 @@ use rustc_middle::ty::{self, Binder, TypeFoldable}; impl<'a, 'tcx> CombineFields<'a, 'tcx> { pub fn higher_ranked_sub( &mut self, - a: Binder, - b: Binder, + a: Binder<'tcx, T>, + b: Binder<'tcx, T>, a_is_expected: bool, - ) -> RelateResult<'tcx, Binder> + ) -> RelateResult<'tcx, Binder<'tcx, T>> where T: Relate<'tcx>, { @@ -69,7 +69,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// the [rustc dev guide]. /// /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html - pub fn replace_bound_vars_with_placeholders(&self, binder: ty::Binder) -> T + pub fn replace_bound_vars_with_placeholders(&self, binder: ty::Binder<'tcx, T>) -> T where T: TypeFoldable<'tcx>, { diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index 9f43fac0916..4fa8f2f1a6a 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -85,9 +85,9 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> { fn binders( &mut self, - a: ty::Binder, - b: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> + a: ty::Binder<'tcx, T>, + b: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> where T: Relate<'tcx>, { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 9fb045e8e40..eaec6b46bcd 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1406,7 +1406,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { &self, span: Span, lbrct: LateBoundRegionConversionTime, - value: ty::Binder, + value: ty::Binder<'tcx, T>, ) -> (T, BTreeMap>) where T: TypeFoldable<'tcx>, diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index e5eb771603c..fc9ea07866c 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -157,7 +157,7 @@ where fn create_scope( &mut self, - value: ty::Binder>, + value: ty::Binder<'tcx, impl Relate<'tcx>>, universally_quantified: UniversallyQuantified, ) -> BoundRegionScope<'tcx> { let mut scope = BoundRegionScope::default(); @@ -608,9 +608,9 @@ where fn binders( &mut self, - a: ty::Binder, - b: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> + a: ty::Binder<'tcx, T>, + b: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> where T: Relate<'tcx>, { @@ -744,7 +744,7 @@ struct ScopeInstantiator<'me, 'tcx> { impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> { fn visit_binder>( &mut self, - t: &ty::Binder, + t: &ty::Binder<'tcx, T>, ) -> ControlFlow { self.target_index.shift_in(1); t.super_visit_with(self); @@ -997,9 +997,9 @@ where fn binders( &mut self, - a: ty::Binder, - _: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> + a: ty::Binder<'tcx, T>, + _: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> where T: Relate<'tcx>, { diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index 66871985158..bf5f328233d 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -162,9 +162,9 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> { fn binders( &mut self, - a: ty::Binder, - b: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> + a: ty::Binder<'tcx, T>, + b: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> where T: Relate<'tcx>, { diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 0882d682e15..a33234a91fa 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -128,7 +128,7 @@ impl<'tcx> FulfillmentError<'tcx> { } impl<'tcx> TraitObligation<'tcx> { - pub fn self_ty(&self) -> ty::Binder> { + pub fn self_ty(&self) -> ty::Binder<'tcx, Ty<'tcx>> { self.predicate.map_bound(|p| p.self_ty()) } } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index e4403f879ff..14bd823ea22 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -909,7 +909,7 @@ impl<'tcx> LateContext<'tcx> { fn print_dyn_existential( self, - _predicates: &'tcx ty::List>>, + _predicates: &'tcx ty::List>>, ) -> Result { Ok(()) } diff --git a/compiler/rustc_middle/src/ich/impls_ty.rs b/compiler/rustc_middle/src/ich/impls_ty.rs index 573b514e844..60b1564d4c5 100644 --- a/compiler/rustc_middle/src/ich/impls_ty.rs +++ b/compiler/rustc_middle/src/ich/impls_ty.rs @@ -118,7 +118,7 @@ impl<'tcx> HashStable> for ty::BoundVar { } } -impl<'a, T> HashStable> for ty::Binder +impl<'a, 'tcx, T> HashStable> for ty::Binder<'tcx, T> where T: HashStable>, { diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 7ed4cbf034f..5d0987193fa 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -277,7 +277,7 @@ impl<'tcx, V> Canonical<'tcx, V> { } pub type QueryOutlivesConstraint<'tcx> = - ty::Binder, Region<'tcx>>>; + ty::Binder<'tcx, ty::OutlivesPredicate, Region<'tcx>>>; TrivialTypeFoldableAndLiftImpls! { for <'tcx> { diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index a5962e3b3ba..8e2c79701af 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -112,9 +112,9 @@ impl TypeRelation<'tcx> for Match<'tcx> { fn binders( &mut self, - a: ty::Binder, - b: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> + a: ty::Binder<'tcx, T>, + b: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> where T: Relate<'tcx>, { diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 59e1695cdb9..3a38f0c8521 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -120,7 +120,7 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable for Ty<'tcx> { } } -impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::Binder> { +impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::Binder<'tcx, ty::PredicateKind<'tcx>> { fn encode(&self, e: &mut E) -> Result<(), E::Error> { encode_with_shorthand(e, &self.skip_binder(), TyEncoder::predicate_shorthands) } @@ -226,8 +226,8 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable for Ty<'tcx> { } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Binder> { - fn decode(decoder: &mut D) -> Result>, D::Error> { +impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Binder<'tcx, ty::PredicateKind<'tcx>> { + fn decode(decoder: &mut D) -> Result>, D::Error> { // Handle shorthands first, if we have an usize > 0x80. Ok(ty::Binder::bind(if decoder.positioned_at_shorthand() { let pos = decoder.read_usize()?; @@ -319,7 +319,7 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List> { } impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> - for ty::List>> + for ty::List>> { fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { let len = decoder.read_usize()?; @@ -382,7 +382,7 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [mir::abstract_const::N impl_decodable_via_ref! { &'tcx ty::TypeckResults<'tcx>, &'tcx ty::List>, - &'tcx ty::List>>, + &'tcx ty::List>>, &'tcx Allocation, &'tcx mir::Body<'tcx>, &'tcx mir::UnsafetyCheckResult, @@ -488,12 +488,12 @@ macro_rules! implement_ty_decoder { macro_rules! impl_binder_encode_decode { ($($t:ty),+ $(,)?) => { $( - impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::Binder<$t> { + impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::Binder<'tcx, $t> { fn encode(&self, e: &mut E) -> Result<(), E::Error> { self.as_ref().skip_binder().encode(e) } } - impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Binder<$t> { + impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Binder<'tcx, $t> { fn decode(decoder: &mut D) -> Result { Ok(ty::Binder::bind(Decodable::decode(decoder)?)) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 94c1758b25c..a7c05b42755 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -87,7 +87,8 @@ pub struct CtxtInterners<'tcx> { substs: InternedSet<'tcx, InternalSubsts<'tcx>>, canonical_var_infos: InternedSet<'tcx, List>>, region: InternedSet<'tcx, RegionKind>, - poly_existential_predicates: InternedSet<'tcx, List>>>, + poly_existential_predicates: + InternedSet<'tcx, List>>>, predicate: InternedSet<'tcx, PredicateInner<'tcx>>, predicates: InternedSet<'tcx, List>>, projs: InternedSet<'tcx, List>, @@ -136,7 +137,10 @@ impl<'tcx> CtxtInterners<'tcx> { } #[inline(never)] - fn intern_predicate(&self, kind: Binder>) -> &'tcx PredicateInner<'tcx> { + fn intern_predicate( + &self, + kind: Binder<'tcx, PredicateKind<'tcx>>, + ) -> &'tcx PredicateInner<'tcx> { self.predicate .intern(kind, |kind| { let flags = super::flags::FlagComputation::for_predicate(kind); @@ -449,7 +453,7 @@ pub struct TypeckResults<'tcx> { /// Stores the type, expression, span and optional scope span of all types /// that are live across the yield of this generator (if a generator). - pub generator_interior_types: ty::Binder>>, + pub generator_interior_types: ty::Binder<'tcx, Vec>>, /// We sometimes treat byte string literals (which are of type `&[u8; N]`) /// as `&[u8]`, depending on the pattern in which they are used. @@ -1616,7 +1620,7 @@ nop_lift! {allocation; &'a Allocation => &'tcx Allocation} nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>} nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>} -nop_list_lift! {poly_existential_predicates; ty::Binder> => ty::Binder>} +nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>} nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>} nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>} nop_list_lift! {projs; ProjectionKind => ProjectionKind} @@ -1965,8 +1969,8 @@ impl<'tcx> Hash for Interned<'tcx, PredicateInner<'tcx>> { } } -impl<'tcx> Borrow>> for Interned<'tcx, PredicateInner<'tcx>> { - fn borrow<'a>(&'a self) -> &'a Binder> { +impl<'tcx> Borrow>> for Interned<'tcx, PredicateInner<'tcx>> { + fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> { &self.0.kind } } @@ -2072,7 +2076,7 @@ slice_interners!( substs: _intern_substs(GenericArg<'tcx>), canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>), poly_existential_predicates: - _intern_poly_existential_predicates(ty::Binder>), + _intern_poly_existential_predicates(ty::Binder<'tcx, ExistentialPredicate<'tcx>>), predicates: _intern_predicates(Predicate<'tcx>), projs: _intern_projs(ProjectionKind), place_elems: _intern_place_elems(PlaceElem<'tcx>), @@ -2158,7 +2162,7 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline] - pub fn mk_predicate(self, binder: Binder>) -> Predicate<'tcx> { + pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> { let inner = self.interners.intern_predicate(binder); Predicate { inner } } @@ -2167,7 +2171,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn reuse_or_mk_predicate( self, pred: Predicate<'tcx>, - binder: Binder>, + binder: Binder<'tcx, PredicateKind<'tcx>>, ) -> Predicate<'tcx> { if pred.kind() != binder { self.mk_predicate(binder) } else { pred } } @@ -2334,7 +2338,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_dynamic( self, - obj: &'tcx List>>, + obj: &'tcx List>>, reg: ty::Region<'tcx>, ) -> Ty<'tcx> { self.mk_ty(Dynamic(obj, reg)) @@ -2361,7 +2365,7 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline] - pub fn mk_generator_witness(self, types: ty::Binder<&'tcx List>>) -> Ty<'tcx> { + pub fn mk_generator_witness(self, types: ty::Binder<'tcx, &'tcx List>>) -> Ty<'tcx> { self.mk_ty(GeneratorWitness(types)) } @@ -2466,8 +2470,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn intern_poly_existential_predicates( self, - eps: &[ty::Binder>], - ) -> &'tcx List>> { + eps: &[ty::Binder<'tcx, ExistentialPredicate<'tcx>>], + ) -> &'tcx List>> { assert!(!eps.is_empty()); assert!( eps.array_windows() @@ -2533,8 +2537,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn mk_poly_existential_predicates< I: InternAs< - [ty::Binder>], - &'tcx List>>, + [ty::Binder<'tcx, ExistentialPredicate<'tcx>>], + &'tcx List>>, >, >( self, diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 4412ba9408c..79e88662f65 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -43,7 +43,7 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { if ty.needs_infer() { ty.super_fold_with(self) } else { self.tcx.erase_regions_ty(ty) } } - fn fold_binder(&mut self, t: ty::Binder) -> ty::Binder + fn fold_binder(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T> where T: TypeFoldable<'tcx>, { diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index f19cc998449..4767e5743c2 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -57,7 +57,9 @@ pub enum TypeError<'tcx> { CyclicTy(Ty<'tcx>), CyclicConst(&'tcx ty::Const<'tcx>), ProjectionMismatched(ExpectedFound), - ExistentialMismatch(ExpectedFound<&'tcx ty::List>>>), + ExistentialMismatch( + ExpectedFound<&'tcx ty::List>>>, + ), ObjectUnsafeCoercion(DefId), ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>), diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index d6dc81c5b78..01bc5cc761c 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -22,7 +22,7 @@ impl FlagComputation { result } - pub fn for_predicate(binder: ty::Binder>) -> FlagComputation { + pub fn for_predicate(binder: ty::Binder<'tcx, ty::PredicateKind<'_>>) -> FlagComputation { let mut result = FlagComputation::new(); result.add_predicate(binder); result @@ -53,7 +53,7 @@ impl FlagComputation { /// Adds the flags/depth from a set of types that appear within the current type, but within a /// region binder. - fn bound_computation(&mut self, value: ty::Binder, f: F) + fn bound_computation(&mut self, value: ty::Binder<'_, T>, f: F) where F: FnOnce(&mut Self, T), { @@ -204,7 +204,7 @@ impl FlagComputation { } } - fn add_predicate(&mut self, binder: ty::Binder>) { + fn add_predicate(&mut self, binder: ty::Binder<'tcx, ty::PredicateKind<'_>>) { self.bound_computation(binder, |computation, atom| computation.add_predicate_atom(atom)); } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 15ce0ad3970..fe26314ae2f 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -161,7 +161,7 @@ impl TypeFoldable<'tcx> for hir::Constness { pub trait TypeFolder<'tcx>: Sized { fn tcx<'a>(&'a self) -> TyCtxt<'tcx>; - fn fold_binder(&mut self, t: Binder) -> Binder + fn fold_binder(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> where T: TypeFoldable<'tcx>, { @@ -184,7 +184,10 @@ pub trait TypeFolder<'tcx>: Sized { pub trait TypeVisitor<'tcx>: Sized { type BreakTy = !; - fn visit_binder>(&mut self, t: &Binder) -> ControlFlow { + fn visit_binder>( + &mut self, + t: &Binder<'tcx, T>, + ) -> ControlFlow { t.super_visit_with(self) } @@ -322,7 +325,7 @@ impl<'tcx> TyCtxt<'tcx> { fn visit_binder>( &mut self, - t: &Binder, + t: &Binder<'tcx, T>, ) -> ControlFlow { self.outer_index.shift_in(1); let result = t.as_ref().skip_binder().visit_with(self); @@ -400,7 +403,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { self.tcx } - fn fold_binder>(&mut self, t: ty::Binder) -> ty::Binder { + fn fold_binder>( + &mut self, + t: ty::Binder<'tcx, T>, + ) -> ty::Binder<'tcx, T> { self.current_index.shift_in(1); let t = t.super_fold_with(self); self.current_index.shift_out(1); @@ -460,7 +466,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { self.tcx } - fn fold_binder>(&mut self, t: ty::Binder) -> ty::Binder { + fn fold_binder>( + &mut self, + t: ty::Binder<'tcx, T>, + ) -> ty::Binder<'tcx, T> { self.current_index.shift_in(1); let t = t.super_fold_with(self); self.current_index.shift_out(1); @@ -538,7 +547,7 @@ impl<'tcx> TyCtxt<'tcx> { /// contain escaping bound types. pub fn replace_late_bound_regions( self, - value: Binder, + value: Binder<'tcx, T>, mut fld_r: F, ) -> (T, BTreeMap>) where @@ -588,7 +597,7 @@ impl<'tcx> TyCtxt<'tcx> { /// types. pub fn replace_bound_vars( self, - value: Binder, + value: Binder<'tcx, T>, mut fld_r: F, fld_t: G, fld_c: H, @@ -607,7 +616,11 @@ impl<'tcx> TyCtxt<'tcx> { /// Replaces any late-bound regions bound in `value` with /// free variants attached to `all_outlive_scope`. - pub fn liberate_late_bound_regions(self, all_outlive_scope: DefId, value: ty::Binder) -> T + pub fn liberate_late_bound_regions( + self, + all_outlive_scope: DefId, + value: ty::Binder<'tcx, T>, + ) -> T where T: TypeFoldable<'tcx>, { @@ -626,7 +639,7 @@ impl<'tcx> TyCtxt<'tcx> { /// variables will also be equated. pub fn collect_constrained_late_bound_regions( self, - value: &Binder, + value: &Binder<'tcx, T>, ) -> FxHashSet where T: TypeFoldable<'tcx>, @@ -637,7 +650,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns a set of all late-bound regions that appear in `value` anywhere. pub fn collect_referenced_late_bound_regions( self, - value: &Binder, + value: &Binder<'tcx, T>, ) -> FxHashSet where T: TypeFoldable<'tcx>, @@ -647,7 +660,7 @@ impl<'tcx> TyCtxt<'tcx> { fn collect_late_bound_regions( self, - value: &Binder, + value: &Binder<'tcx, T>, just_constraint: bool, ) -> FxHashSet where @@ -661,7 +674,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Replaces any late-bound regions bound in `value` with `'erased`. Useful in codegen but also /// method lookup and a few other places where precise region relationships are not required. - pub fn erase_late_bound_regions(self, value: Binder) -> T + pub fn erase_late_bound_regions(self, value: Binder<'tcx, T>) -> T where T: TypeFoldable<'tcx>, { @@ -676,7 +689,7 @@ impl<'tcx> TyCtxt<'tcx> { /// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become /// structurally identical. For example, `for<'a, 'b> fn(&'a isize, &'b isize)` and /// `for<'a, 'b> fn(&'b isize, &'a isize)` will become identical after anonymization. - pub fn anonymize_late_bound_regions(self, sig: Binder) -> Binder + pub fn anonymize_late_bound_regions(self, sig: Binder<'tcx, T>) -> Binder<'tcx, T> where T: TypeFoldable<'tcx>, { @@ -719,7 +732,10 @@ impl TypeFolder<'tcx> for Shifter<'tcx> { self.tcx } - fn fold_binder>(&mut self, t: ty::Binder) -> ty::Binder { + fn fold_binder>( + &mut self, + t: ty::Binder<'tcx, T>, + ) -> ty::Binder<'tcx, T> { self.current_index.shift_in(1); let t = t.super_fold_with(self); self.current_index.shift_out(1); @@ -828,7 +844,10 @@ struct HasEscapingVarsVisitor { impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { type BreakTy = FoundEscapingVars; - fn visit_binder>(&mut self, t: &Binder) -> ControlFlow { + fn visit_binder>( + &mut self, + t: &Binder<'tcx, T>, + ) -> ControlFlow { self.outer_index.shift_in(1); let result = t.super_visit_with(self); self.outer_index.shift_out(1); @@ -898,7 +917,10 @@ crate struct CountBoundVars { impl<'tcx> TypeVisitor<'tcx> for CountBoundVars { type BreakTy = (); - fn visit_binder>(&mut self, t: &Binder) -> ControlFlow { + fn visit_binder>( + &mut self, + t: &Binder<'tcx, T>, + ) -> ControlFlow { self.outer_index.shift_in(1); let result = t.super_visit_with(self); self.outer_index.shift_out(1); @@ -1022,7 +1044,10 @@ impl LateBoundRegionsCollector { } impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector { - fn visit_binder>(&mut self, t: &Binder) -> ControlFlow { + fn visit_binder>( + &mut self, + t: &Binder<'tcx, T>, + ) -> ControlFlow { self.current_index.shift_in(1); let result = t.super_visit_with(self); self.current_index.shift_out(1); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8fc35193498..29f82b47305 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -359,7 +359,7 @@ impl ty::EarlyBoundRegion { #[derive(Debug)] crate struct PredicateInner<'tcx> { - kind: Binder>, + kind: Binder<'tcx, PredicateKind<'tcx>>, flags: TypeFlags, /// See the comment for the corresponding field of [TyS]. outer_exclusive_binder: ty::DebruijnIndex, @@ -389,9 +389,9 @@ impl Hash for Predicate<'_> { impl<'tcx> Eq for Predicate<'tcx> {} impl<'tcx> Predicate<'tcx> { - /// Gets the inner `Binder>`. + /// Gets the inner `Binder<'tcx, PredicateKind<'tcx>>`. #[inline] - pub fn kind(self) -> Binder> { + pub fn kind(self) -> Binder<'tcx, PredicateKind<'tcx>> { self.inner.kind } } @@ -556,7 +556,7 @@ pub struct TraitPredicate<'tcx> { pub trait_ref: TraitRef<'tcx>, } -pub type PolyTraitPredicate<'tcx> = ty::Binder>; +pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; impl<'tcx> TraitPredicate<'tcx> { pub fn def_id(self) -> DefId { @@ -574,7 +574,7 @@ impl<'tcx> PolyTraitPredicate<'tcx> { self.skip_binder().def_id() } - pub fn self_ty(self) -> ty::Binder> { + pub fn self_ty(self) -> ty::Binder<'tcx, Ty<'tcx>> { self.map_bound(|trait_ref| trait_ref.self_ty()) } } @@ -584,8 +584,8 @@ impl<'tcx> PolyTraitPredicate<'tcx> { pub struct OutlivesPredicate(pub A, pub B); // `A: B` pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate, ty::Region<'tcx>>; pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate, ty::Region<'tcx>>; -pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder>; -pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder>; +pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>; +pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>; #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable)] @@ -594,7 +594,7 @@ pub struct SubtypePredicate<'tcx> { pub a: Ty<'tcx>, pub b: Ty<'tcx>, } -pub type PolySubtypePredicate<'tcx> = ty::Binder>; +pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>; /// This kind of predicate has no *direct* correspondent in the /// syntax, but it roughly corresponds to the syntactic forms: @@ -615,7 +615,7 @@ pub struct ProjectionPredicate<'tcx> { pub ty: Ty<'tcx>, } -pub type PolyProjectionPredicate<'tcx> = Binder>; +pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>; impl<'tcx> PolyProjectionPredicate<'tcx> { /// Returns the `DefId` of the trait of the associated item being projected. @@ -637,7 +637,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { self.map_bound(|predicate| predicate.projection_ty.trait_ref(tcx)) } - pub fn ty(&self) -> Binder> { + pub fn ty(&self) -> Binder<'tcx, Ty<'tcx>> { self.map_bound(|predicate| predicate.ty) } @@ -671,7 +671,7 @@ pub trait ToPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx>; } -impl ToPredicate<'tcx> for Binder> { +impl ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> { #[inline(always)] fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { tcx.mk_predicate(self) @@ -694,11 +694,11 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - ConstnessAnd { - value: self.value.map_bound(|trait_ref| ty::TraitPredicate { trait_ref }), - constness: self.constness, - } - .to_predicate(tcx) + self.value + .map_bound(|trait_ref| { + PredicateKind::Trait(ty::TraitPredicate { trait_ref }, self.constness) + }) + .to_predicate(tcx) } } diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 9d97815a5f1..3b0cb8d4215 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -38,7 +38,7 @@ impl<'tcx> TyCtxt<'tcx> { } } - /// If you have a `Binder`, you can do this to strip out the + /// If you have a `Binder<'tcx, T>`, you can do this to strip out the /// late-bound regions and then normalize the result, yielding up /// a `T` (with regions erased). This is appropriate when the /// binder is being instantiated at the call site. @@ -49,7 +49,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn normalize_erasing_late_bound_regions( self, param_env: ty::ParamEnv<'tcx>, - value: ty::Binder, + value: ty::Binder<'tcx, T>, ) -> T where T: TypeFoldable<'tcx>, diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index a47846828bd..13e2122a619 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -63,7 +63,7 @@ pub trait Printer<'tcx>: Sized { fn print_dyn_existential( self, - predicates: &'tcx ty::List>>, + predicates: &'tcx ty::List>>, ) -> Result; fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result; @@ -346,7 +346,7 @@ impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for Ty<'tcx> { } impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> - for &'tcx ty::List>> + for &'tcx ty::List>> { type Output = P::DynExistential; type Error = P::Error; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f23c64cb036..acb5c474164 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -202,7 +202,7 @@ pub trait PrettyPrinter<'tcx>: self.print_def_path(def_id, substs) } - fn in_binder(self, value: &ty::Binder) -> Result + fn in_binder(self, value: &ty::Binder<'tcx, T>) -> Result where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>, { @@ -211,7 +211,7 @@ pub trait PrettyPrinter<'tcx>: fn wrap_binder Result>( self, - value: &ty::Binder, + value: &ty::Binder<'tcx, T>, f: F, ) -> Result where @@ -765,7 +765,7 @@ pub trait PrettyPrinter<'tcx>: fn pretty_print_dyn_existential( mut self, - predicates: &'tcx ty::List>>, + predicates: &'tcx ty::List>>, ) -> Result { // Generate the main trait ref, including associated types. let mut first = true; @@ -1432,7 +1432,7 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { fn print_dyn_existential( self, - predicates: &'tcx ty::List>>, + predicates: &'tcx ty::List>>, ) -> Result { self.pretty_print_dyn_existential(predicates) } @@ -1571,7 +1571,7 @@ impl PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { Ok(self) } - fn in_binder(self, value: &ty::Binder) -> Result + fn in_binder(self, value: &ty::Binder<'tcx, T>) -> Result where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>, { @@ -1580,7 +1580,7 @@ impl PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { fn wrap_binder Result>( self, - value: &ty::Binder, + value: &ty::Binder<'tcx, T>, f: C, ) -> Result where @@ -1763,7 +1763,7 @@ impl FmtPrinter<'_, '_, F> { impl FmtPrinter<'_, 'tcx, F> { pub fn name_all_regions( mut self, - value: &ty::Binder, + value: &ty::Binder<'tcx, T>, ) -> Result<(Self, (T, BTreeMap>)), fmt::Error> where T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, @@ -1830,7 +1830,7 @@ impl FmtPrinter<'_, 'tcx, F> { Ok((self, new_value)) } - pub fn pretty_in_binder(self, value: &ty::Binder) -> Result + pub fn pretty_in_binder(self, value: &ty::Binder<'tcx, T>) -> Result where T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, { @@ -1844,7 +1844,7 @@ impl FmtPrinter<'_, 'tcx, F> { pub fn pretty_wrap_binder Result>( self, - value: &ty::Binder, + value: &ty::Binder<'tcx, T>, f: C, ) -> Result where @@ -1858,7 +1858,7 @@ impl FmtPrinter<'_, 'tcx, F> { Ok(inner) } - fn prepare_late_bound_region_info(&mut self, value: &ty::Binder) + fn prepare_late_bound_region_info(&mut self, value: &ty::Binder<'tcx, T>) where T: TypeFoldable<'tcx>, { @@ -1879,7 +1879,7 @@ impl FmtPrinter<'_, 'tcx, F> { } } -impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder +impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<'tcx, T> where T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx>, { @@ -1966,28 +1966,28 @@ impl ty::TraitRef<'tcx> { } } -impl ty::Binder> { - pub fn print_only_trait_path(self) -> ty::Binder> { +impl ty::Binder<'tcx, ty::TraitRef<'tcx>> { + pub fn print_only_trait_path(self) -> ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>> { self.map_bound(|tr| tr.print_only_trait_path()) } } forward_display_to_print! { Ty<'tcx>, - &'tcx ty::List>>, + &'tcx ty::List>>, &'tcx ty::Const<'tcx>, // HACK(eddyb) these are exhaustive instead of generic, // because `for<'tcx>` isn't possible yet. - ty::Binder>, - ty::Binder>, - ty::Binder>, - ty::Binder>, - ty::Binder>, - ty::Binder>, - ty::Binder>, - ty::Binder, ty::Region<'tcx>>>, - ty::Binder, ty::Region<'tcx>>>, + ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>, + ty::Binder<'tcx, ty::TraitRef<'tcx>>, + ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, + ty::Binder<'tcx, ty::FnSig<'tcx>>, + ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, + ty::Binder<'tcx, ty::SubtypePredicate<'tcx>>, + ty::Binder<'tcx, ty::ProjectionPredicate<'tcx>>, + ty::Binder<'tcx, ty::OutlivesPredicate, ty::Region<'tcx>>>, + ty::Binder<'tcx, ty::OutlivesPredicate, ty::Region<'tcx>>>, ty::OutlivesPredicate, ty::Region<'tcx>>, ty::OutlivesPredicate, ty::Region<'tcx>> diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 76ba07864cf..ca60339da0d 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -93,9 +93,9 @@ pub trait TypeRelation<'tcx>: Sized { fn binders( &mut self, - a: ty::Binder, - b: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> + a: ty::Binder<'tcx, T>, + b: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> where T: Relate<'tcx>; } @@ -594,7 +594,7 @@ fn check_const_value_eq>( }) } -impl<'tcx> Relate<'tcx> for &'tcx ty::List>> { +impl<'tcx> Relate<'tcx> for &'tcx ty::List>> { fn relate>( relation: &mut R, a: Self, @@ -684,12 +684,12 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::Const<'tcx> { } } -impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for ty::Binder { +impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for ty::Binder<'tcx, T> { fn relate>( relation: &mut R, - a: ty::Binder, - b: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> { + a: ty::Binder<'tcx, T>, + b: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> { relation.binders(a, b) } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 2da23b331e0..dd4bb029747 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -454,10 +454,14 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> { } } -impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder { - type Lifted = ty::Binder; +impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<'a, T> +where + >::Lifted: TypeFoldable<'tcx>, +{ + type Lifted = ty::Binder<'tcx, T::Lifted>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { - self.map_bound(|v| tcx.lift(v)).transpose() + // FIXME: need to lift inner values + tcx.lift(self.skip_binder()).map(|v| ty::Binder::bind(v)) } } @@ -749,7 +753,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { } } -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder { +impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> { fn super_fold_with>(self, folder: &mut F) -> Self { self.map_bound(|ty| ty.fold_with(folder)) } @@ -767,7 +771,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder { } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List>> { +impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List>> { fn super_fold_with>(self, folder: &mut F) -> Self { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v)) } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 7c7afc0b296..c6d72e78df8 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -161,7 +161,7 @@ pub enum TyKind<'tcx> { FnPtr(PolyFnSig<'tcx>), /// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`. - Dynamic(&'tcx List>>, ty::Region<'tcx>), + Dynamic(&'tcx List>>, ty::Region<'tcx>), /// The anonymous type of a closure. Used to represent the type of /// `|a| a`. @@ -173,7 +173,7 @@ pub enum TyKind<'tcx> { /// A type representing the types stored inside a generator. /// This should only appear in GeneratorInteriors. - GeneratorWitness(Binder<&'tcx List>>), + GeneratorWitness(Binder<'tcx, &'tcx List>>), /// The never type `!`. Never, @@ -747,7 +747,7 @@ impl<'tcx> ExistentialPredicate<'tcx> { } } -impl<'tcx> Binder> { +impl<'tcx> Binder<'tcx, ExistentialPredicate<'tcx>> { pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> { use crate::ty::ToPredicate; match self.skip_binder() { @@ -768,7 +768,7 @@ impl<'tcx> Binder> { } } -impl<'tcx> List>> { +impl<'tcx> List>> { /// Returns the "principal `DefId`" of this set of existential predicates. /// /// A Rust trait object type consists (in addition to a lifetime bound) @@ -794,7 +794,7 @@ impl<'tcx> List>> { /// is `{Send, Sync}`, while there is no principal. These trait objects /// have a "trivial" vtable consisting of just the size, alignment, /// and destructor. - pub fn principal(&self) -> Option>> { + pub fn principal(&self) -> Option>> { self[0] .map_bound(|this| match this { ExistentialPredicate::Trait(tr) => Some(tr), @@ -810,7 +810,7 @@ impl<'tcx> List>> { #[inline] pub fn projection_bounds<'a>( &'a self, - ) -> impl Iterator>> + 'a { + ) -> impl Iterator>> + 'a { self.iter().filter_map(|predicate| { predicate .map_bound(|pred| match pred { @@ -875,10 +875,10 @@ impl<'tcx> TraitRef<'tcx> { } } -pub type PolyTraitRef<'tcx> = Binder>; +pub type PolyTraitRef<'tcx> = Binder<'tcx, TraitRef<'tcx>>; impl<'tcx> PolyTraitRef<'tcx> { - pub fn self_ty(&self) -> Binder> { + pub fn self_ty(&self) -> Binder<'tcx, Ty<'tcx>> { self.map_bound_ref(|tr| tr.self_ty()) } @@ -931,7 +931,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> { } } -pub type PolyExistentialTraitRef<'tcx> = Binder>; +pub type PolyExistentialTraitRef<'tcx> = Binder<'tcx, ExistentialTraitRef<'tcx>>; impl<'tcx> PolyExistentialTraitRef<'tcx> { pub fn def_id(&self) -> DefId { @@ -950,16 +950,16 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> { /// Binder is a binder for higher-ranked lifetimes or types. It is part of the /// compiler's representation for things like `for<'a> Fn(&'a isize)` /// (which would be represented by the type `PolyTraitRef == -/// Binder`). Note that when we instantiate, +/// Binder<'tcx, TraitRef>`). Note that when we instantiate, /// erase, or otherwise "discharge" these bound vars, we change the -/// type from `Binder` to just `T` (see +/// type from `Binder<'tcx, T>` to just `T` (see /// e.g., `liberate_late_bound_regions`). /// /// `Decodable` and `Encodable` are implemented for `Binder` using the `impl_binder_encode_decode!` macro. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub struct Binder(T, u32); +pub struct Binder<'tcx, T>(T, u32, std::marker::PhantomData<&'tcx ()>); -impl<'tcx, T> Binder +impl<'tcx, T> Binder<'tcx, T> where T: TypeFoldable<'tcx>, { @@ -967,13 +967,13 @@ where /// contain any bound vars that would be bound by the /// binder. This is commonly used to 'inject' a value T into a /// different binding level. - pub fn dummy(value: T) -> Binder { + pub fn dummy(value: T) -> Binder<'tcx, T> { debug_assert!(!value.has_escaping_bound_vars()); - Binder(value, 0) + Binder(value, 0, std::marker::PhantomData) } /// Wraps `value` in a binder, binding higher-ranked vars (if any). - pub fn bind(value: T) -> Binder { + pub fn bind(value: T) -> Binder<'tcx, T> { use crate::ty::fold::CountBoundVars; use rustc_data_structures::fx::FxHashSet; let mut counter = CountBoundVars { @@ -1006,11 +1006,11 @@ where let bound_consts = counter.bound_consts.len(); let bound_vars = bound_tys + bound_regions + bound_consts; - Binder(value, bound_vars as u32) + Binder(value, bound_vars as u32, std::marker::PhantomData) } } -impl Binder { +impl<'tcx, T> Binder<'tcx, T> { /// Skips the binder and returns the "bound" value. This is a /// risky thing to do because it's easy to get confused about /// De Bruijn indices and the like. It is usually better to @@ -1035,22 +1035,22 @@ impl Binder { self.1 } - pub fn as_ref(&self) -> Binder<&T> { - Binder(&self.0, self.1) + pub fn as_ref(&self) -> Binder<'tcx, &T> { + Binder(&self.0, self.1, std::marker::PhantomData) } - pub fn map_bound_ref(&self, f: F) -> Binder + pub fn map_bound_ref(&self, f: F) -> Binder<'tcx, U> where F: FnOnce(&T) -> U, { self.as_ref().map_bound(f) } - pub fn map_bound(self, f: F) -> Binder + pub fn map_bound(self, f: F) -> Binder<'tcx, U> where F: FnOnce(T) -> U, { - Binder(f(self.0), self.1) + Binder(f(self.0), self.1, std::marker::PhantomData) } /// Wraps a `value` in a binder, using the same bound variables as the @@ -1062,8 +1062,8 @@ impl Binder { /// don't actually track bound vars. However, semantically, it is different /// because bound vars aren't allowed to change here, whereas they are /// in `bind`. This may be (debug) asserted in the future. - pub fn rebind(&self, value: U) -> Binder { - Binder(value, self.1) + pub fn rebind(&self, value: U) -> Binder<'tcx, U> { + Binder(value, self.1, std::marker::PhantomData) } /// Unwraps and returns the value within, but only if it contains @@ -1076,7 +1076,7 @@ impl Binder { /// binders, but that would require adjusting the debruijn /// indices, and given the shallow binding structure we often use, /// would not be that useful.) - pub fn no_bound_vars<'tcx>(self) -> Option + pub fn no_bound_vars(self) -> Option where T: TypeFoldable<'tcx>, { @@ -1090,11 +1090,11 @@ impl Binder { /// `f` should consider bound regions at depth 1 to be free, and /// anything it produces with bound regions at depth 1 will be /// bound in the resulting return value. - pub fn fuse(self, u: Binder, f: F) -> Binder + pub fn fuse(self, u: Binder<'tcx, U>, f: F) -> Binder<'tcx, R> where F: FnOnce(T, U) -> R, { - Binder(f(self.0, u.0), self.1) + Binder(f(self.0, u.0), self.1, std::marker::PhantomData) } /// Splits the contents into two things that share the same binder @@ -1103,19 +1103,19 @@ impl Binder { /// `f` should consider bound regions at depth 1 to be free, and /// anything it produces with bound regions at depth 1 will be /// bound in the resulting return values. - pub fn split(self, f: F) -> (Binder, Binder) + pub fn split(self, f: F) -> (Binder<'tcx, U>, Binder<'tcx, V>) where F: FnOnce(T) -> (U, V), { let (u, v) = f(self.0); - (Binder(u, self.1), Binder(v, self.1)) + (Binder(u, self.1, std::marker::PhantomData), Binder(v, self.1, std::marker::PhantomData)) } } -impl Binder> { - pub fn transpose(self) -> Option> { +impl<'tcx, T> Binder<'tcx, Option> { + pub fn transpose(self) -> Option> { let bound_vars = self.1; - self.0.map(|v| Binder(v, bound_vars)) + self.0.map(|v| Binder(v, bound_vars, std::marker::PhantomData)) } } @@ -1178,7 +1178,7 @@ pub struct GenSig<'tcx> { pub return_ty: Ty<'tcx>, } -pub type PolyGenSig<'tcx> = Binder>; +pub type PolyGenSig<'tcx> = Binder<'tcx, GenSig<'tcx>>; /// Signature of a function type, which we have arbitrarily /// decided to use to refer to the input/output types. @@ -1216,22 +1216,22 @@ impl<'tcx> FnSig<'tcx> { } } -pub type PolyFnSig<'tcx> = Binder>; +pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>; impl<'tcx> PolyFnSig<'tcx> { #[inline] - pub fn inputs(&self) -> Binder<&'tcx [Ty<'tcx>]> { + pub fn inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]> { self.map_bound_ref(|fn_sig| fn_sig.inputs()) } #[inline] - pub fn input(&self, index: usize) -> ty::Binder> { + pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> { self.map_bound_ref(|fn_sig| fn_sig.inputs()[index]) } - pub fn inputs_and_output(&self) -> ty::Binder<&'tcx List>> { + pub fn inputs_and_output(&self) -> ty::Binder<'tcx, &'tcx List>> { self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output) } #[inline] - pub fn output(&self) -> ty::Binder> { + pub fn output(&self) -> ty::Binder<'tcx, Ty<'tcx>> { self.map_bound_ref(|fn_sig| fn_sig.output()) } pub fn c_variadic(&self) -> bool { @@ -1245,7 +1245,7 @@ impl<'tcx> PolyFnSig<'tcx> { } } -pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder>>; +pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(HashStable)] @@ -1489,7 +1489,7 @@ pub struct ExistentialProjection<'tcx> { pub ty: Ty<'tcx>, } -pub type PolyExistentialProjection<'tcx> = Binder>; +pub type PolyExistentialProjection<'tcx> = Binder<'tcx, ExistentialProjection<'tcx>>; impl<'tcx> ExistentialProjection<'tcx> { /// Extracts the underlying existential trait reference from this projection. diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 5d1b976ae97..8352e8b4918 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -448,7 +448,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { self.tcx } - fn fold_binder>(&mut self, t: ty::Binder) -> ty::Binder { + fn fold_binder>( + &mut self, + t: ty::Binder<'tcx, T>, + ) -> ty::Binder<'tcx, T> { self.binders_passed += 1; let t = t.super_fold_with(self); self.binders_passed -= 1; diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 9c7de250c29..be9ba56f097 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -499,7 +499,7 @@ impl<'tcx> TyCtxt<'tcx> { self, closure_def_id: DefId, closure_substs: SubstsRef<'tcx>, - ) -> Option>> { + ) -> Option>> { let closure_ty = self.mk_closure(closure_def_id, closure_substs); let br = ty::BoundRegion { kind: ty::BrEnv }; let env_region = ty::ReLateBound(ty::INNERMOST, br); diff --git a/compiler/rustc_mir/src/borrow_check/universal_regions.rs b/compiler/rustc_mir/src/borrow_check/universal_regions.rs index 68fa9d8bf98..f295693781e 100644 --- a/compiler/rustc_mir/src/borrow_check/universal_regions.rs +++ b/compiler/rustc_mir/src/borrow_check/universal_regions.rs @@ -589,7 +589,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { &self, indices: &UniversalRegionIndices<'tcx>, defining_ty: DefiningTy<'tcx>, - ) -> ty::Binder<&'tcx ty::List>> { + ) -> ty::Binder<'tcx, &'tcx ty::List>> { let tcx = self.infcx.tcx; match defining_ty { DefiningTy::Closure(def_id, substs) => { @@ -657,7 +657,7 @@ trait InferCtxtExt<'tcx> { &self, origin: NllRegionVariableOrigin, all_outlive_scope: LocalDefId, - value: ty::Binder, + value: ty::Binder<'tcx, T>, indices: &mut UniversalRegionIndices<'tcx>, ) -> T where @@ -686,7 +686,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { &self, origin: NllRegionVariableOrigin, all_outlive_scope: LocalDefId, - value: ty::Binder, + value: ty::Binder<'tcx, T>, indices: &mut UniversalRegionIndices<'tcx>, ) -> T where diff --git a/compiler/rustc_mir/src/interpret/intrinsics/type_name.rs b/compiler/rustc_mir/src/interpret/intrinsics/type_name.rs index e1ec4cc5e97..ae5e78ee33f 100644 --- a/compiler/rustc_mir/src/interpret/intrinsics/type_name.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics/type_name.rs @@ -74,7 +74,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { fn print_dyn_existential( mut self, - predicates: &'tcx ty::List>>, + predicates: &'tcx ty::List>>, ) -> Result { let mut first = true; for p in predicates { diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index b0d5f340902..7d186c330ba 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -230,7 +230,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> { fn print_dyn_existential( mut self, - predicates: &'tcx ty::List>>, + predicates: &'tcx ty::List>>, ) -> Result { let mut first = true; for p in predicates { diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 12c0a147990..0bb5dd117a0 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -181,7 +181,7 @@ impl SymbolMangler<'tcx> { fn in_binder( mut self, - value: &ty::Binder, + value: &ty::Binder<'tcx, T>, print_value: impl FnOnce(Self, &T) -> Result, ) -> Result where @@ -483,7 +483,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { fn print_dyn_existential( mut self, - predicates: &'tcx ty::List>>, + predicates: &'tcx ty::List>>, ) -> Result { for predicate in predicates { self = self.in_binder(&predicate, |mut cx, predicate| { diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index d6a585e626c..b6c3768d887 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -697,7 +697,7 @@ where { fn visit_binder>( &mut self, - t: &ty::Binder, + t: &ty::Binder<'tcx, T>, ) -> ControlFlow { t.as_ref().skip_binder().visit_with(self); ControlFlow::CONTINUE 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 c1b105f1d84..326b85e1013 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -65,7 +65,7 @@ pub trait InferCtxtExt<'tcx> { &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'_>, - trait_ref: ty::Binder>, + trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, points_at_arg: bool, ); @@ -73,7 +73,7 @@ pub trait InferCtxtExt<'tcx> { &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'_>, - trait_ref: &ty::Binder>, + trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>, points_at_arg: bool, has_custom_message: bool, ) -> bool; @@ -82,14 +82,14 @@ pub trait InferCtxtExt<'tcx> { &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'_>, - trait_ref: ty::Binder>, + trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, ); fn suggest_change_mut( &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'_>, - trait_ref: ty::Binder>, + trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, points_at_arg: bool, ); @@ -98,7 +98,7 @@ pub trait InferCtxtExt<'tcx> { obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'_>, span: Span, - trait_ref: ty::Binder>, + trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, ); fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option; @@ -108,7 +108,7 @@ pub trait InferCtxtExt<'tcx> { err: &mut DiagnosticBuilder<'_>, span: Span, obligation: &PredicateObligation<'tcx>, - trait_ref: ty::Binder>, + trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, ) -> bool; fn point_at_returns_when_relevant( @@ -170,7 +170,7 @@ pub trait InferCtxtExt<'tcx> { &self, err: &mut DiagnosticBuilder<'_>, obligation: &PredicateObligation<'tcx>, - trait_ref: ty::Binder>, + trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, span: Span, ); } @@ -583,7 +583,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'_>, - trait_ref: ty::Binder>, + trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, points_at_arg: bool, ) { let self_ty = match trait_ref.self_ty().no_bound_vars() { @@ -676,7 +676,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'_>, - trait_ref: &ty::Binder>, + trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>, points_at_arg: bool, has_custom_message: bool, ) -> bool { @@ -761,7 +761,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'_>, - trait_ref: ty::Binder>, + trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, ) { let span = obligation.cause.span; @@ -824,7 +824,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'_>, - trait_ref: ty::Binder>, + trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, points_at_arg: bool, ) { let span = obligation.cause.span; @@ -896,10 +896,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'_>, span: Span, - trait_ref: ty::Binder>, + trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, ) { let is_empty_tuple = - |ty: ty::Binder>| *ty.skip_binder().kind() == ty::Tuple(ty::List::empty()); + |ty: ty::Binder<'tcx, Ty<'_>>| *ty.skip_binder().kind() == ty::Tuple(ty::List::empty()); let hir = self.tcx.hir(); let parent_node = hir.get_parent_node(obligation.cause.body_id); @@ -948,7 +948,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err: &mut DiagnosticBuilder<'_>, span: Span, obligation: &PredicateObligation<'tcx>, - trait_ref: ty::Binder>, + trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, ) -> bool { match obligation.cause.code.peel_derives() { // Only suggest `impl Trait` if the return type is unsized because it is `dyn Trait`. @@ -2190,7 +2190,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { &self, err: &mut DiagnosticBuilder<'_>, obligation: &PredicateObligation<'tcx>, - trait_ref: ty::Binder>, + trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, span: Span, ) { debug!( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 0dc0dd871fe..31685a012ca 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -272,7 +272,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &TraitObligation<'tcx>, trait_def_id: DefId, - nested: ty::Binder>>, + nested: ty::Binder<'tcx, Vec>>, ) -> ImplSourceAutoImplData> { debug!(?nested, "vtable_auto_impl"); ensure_sufficient_stack(|| { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 45680c90cdc..1c51597fff2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -204,7 +204,7 @@ struct EvaluatedCandidate<'tcx> { /// When does the builtin impl for `T: Trait` apply? enum BuiltinImplConditions<'tcx> { /// The impl is conditional on `T1, T2, ...: Trait`. - Where(ty::Binder>>), + Where(ty::Binder<'tcx, Vec>>), /// There is no built-in impl. There may be some other /// candidate (a where-clause or user-defined impl). None, @@ -1673,7 +1673,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Bar where struct Bar { x: T, y: u32 } -> [i32, u32] /// Zed where enum Zed { A(T), B(u32) } -> [i32, u32] /// ``` - fn constituent_types_for_ty(&self, t: ty::Binder>) -> ty::Binder>> { + fn constituent_types_for_ty( + &self, + t: ty::Binder<'tcx, Ty<'tcx>>, + ) -> ty::Binder<'tcx, Vec>> { match *t.skip_binder().kind() { ty::Uint(_) | ty::Int(_) @@ -1746,7 +1749,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause: ObligationCause<'tcx>, recursion_depth: usize, trait_def_id: DefId, - types: ty::Binder>>, + types: ty::Binder<'tcx, Vec>>, ) -> Vec> { // Because the types were potentially derived from // higher-ranked obligations they may reference late-bound @@ -1767,7 +1770,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .skip_binder() // binder moved -\ .iter() .flat_map(|ty| { - let ty: ty::Binder> = types.rebind(ty); // <----/ + let ty: ty::Binder<'tcx, Ty<'tcx>> = types.rebind(ty); // <----/ self.infcx.commit_unconditionally(|_| { let placeholder_ty = self.infcx.replace_bound_vars_with_placeholders(ty); diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 8888ea2c849..fd94f9f7998 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -328,7 +328,7 @@ pub fn closure_trait_ref_and_return_type( self_ty: Ty<'tcx>, sig: ty::PolyFnSig<'tcx>, tuple_arguments: TupleArgumentsFlag, -) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>)> { +) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>)> { let arguments_tuple = match tuple_arguments { TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()), @@ -346,7 +346,7 @@ pub fn generator_trait_ref_and_outputs( fn_trait_def_id: DefId, self_ty: Ty<'tcx>, sig: ty::PolyGenSig<'tcx>, -) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { +) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { debug_assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 3d5f8d128dc..f592cf1cd24 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -704,7 +704,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { fn from_object_ty( &mut self, ty: Ty<'tcx>, - data: &'tcx ty::List>>, + data: &'tcx ty::List>>, region: ty::Region<'tcx>, ) { // Imagine a type like this: @@ -767,7 +767,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { /// `infer::required_region_bounds`, see that for more information. pub fn object_region_bounds<'tcx>( tcx: TyCtxt<'tcx>, - existential_predicates: &'tcx ty::List>>, + existential_predicates: &'tcx ty::List>>, ) -> Vec> { // Since we don't actually *know* the self type for an object, // this "open(err)" serves as a kind of dummy standin -- basically diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index fdf5f697e61..f9de41ee893 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -606,7 +606,7 @@ impl<'tcx> LowerInto<'tcx, Option LowerInto<'tcx, chalk_ir::Binders>>> - for &'tcx ty::List>> + for &'tcx ty::List>> { fn lower_into( self, @@ -677,7 +677,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders LowerInto<'tcx, chalk_ir::FnSig>> for ty::Binder> { +impl<'tcx> LowerInto<'tcx, chalk_ir::FnSig>> + for ty::Binder<'tcx, ty::FnSig<'tcx>> +{ fn lower_into(self, _interner: &RustInterner<'_>) -> FnSig> { chalk_ir::FnSig { abi: self.abi(), @@ -801,7 +803,7 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound crate fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>( interner: &RustInterner<'tcx>, tcx: TyCtxt<'tcx>, - ty: Binder, + ty: Binder<'tcx, T>, ) -> (T, chalk_ir::VariableKinds>, BTreeMap) { let mut bound_vars_collector = BoundVarsCollector::new(); ty.as_ref().skip_binder().visit_with(&mut bound_vars_collector); @@ -849,7 +851,10 @@ impl<'tcx> BoundVarsCollector<'tcx> { } impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { - fn visit_binder>(&mut self, t: &Binder) -> ControlFlow { + fn visit_binder>( + &mut self, + t: &Binder<'tcx, T>, + ) -> ControlFlow { self.binder_index.shift_in(1); let result = t.super_visit_with(self); self.binder_index.shift_out(1); @@ -931,7 +936,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> { self.tcx } - fn fold_binder>(&mut self, t: Binder) -> Binder { + fn fold_binder>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> { self.binder_index.shift_in(1); let result = t.super_fold_with(self); self.binder_index.shift_out(1); @@ -987,7 +992,7 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { self.tcx } - fn fold_binder>(&mut self, t: Binder) -> Binder { + fn fold_binder>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> { self.binder_index.shift_in(1); let result = t.super_fold_with(self); self.binder_index.shift_out(1); diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 183dab39e9e..1e194771709 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2450,7 +2450,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { fn compute_object_lifetime_bound( &self, span: Span, - existential_predicates: &'tcx ty::List>>, + existential_predicates: &'tcx ty::List>>, ) -> Option> // if None, use the default { let tcx = self.tcx(); diff --git a/compiler/rustc_typeck/src/bounds.rs b/compiler/rustc_typeck/src/bounds.rs index 3bbf0ba63b8..5d200640722 100644 --- a/compiler/rustc_typeck/src/bounds.rs +++ b/compiler/rustc_typeck/src/bounds.rs @@ -26,7 +26,7 @@ pub struct Bounds<'tcx> { /// A list of region bounds on the (implicit) self type. So if you /// had `T: 'a + 'b` this might would be a list `['a, 'b]` (but /// the `T` is not explicitly included). - pub region_bounds: Vec<(ty::Binder>, Span)>, + pub region_bounds: Vec<(ty::Binder<'tcx, ty::Region<'tcx>>, Span)>, /// A list of trait bounds. So if you had `T: Debug` this would be /// `T: Debug`. Note that the self-type is explicit here. diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs index 4d74962d28e..de6336b254b 100644 --- a/compiler/rustc_typeck/src/check/dropck.rs +++ b/compiler/rustc_typeck/src/check/dropck.rs @@ -354,9 +354,9 @@ impl TypeRelation<'tcx> for SimpleEqRelation<'tcx> { fn binders( &mut self, - a: ty::Binder, - b: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> + a: ty::Binder<'tcx, T>, + b: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> where T: Relate<'tcx>, { diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index fff659a91ad..901a874980d 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -550,7 +550,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { upcast_trait_refs.into_iter().next().unwrap() } - fn replace_bound_vars_with_fresh_vars(&self, value: ty::Binder) -> T + fn replace_bound_vars_with_fresh_vars(&self, value: ty::Binder<'tcx, T>) -> T where T: TypeFoldable<'tcx>, { diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 0742549f890..bfaf36e702f 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1753,7 +1753,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// region got replaced with the same variable, which requires a bit more coordination /// and/or tracking the substitution and /// so forth. - fn erase_late_bound_regions(&self, value: ty::Binder) -> T + fn erase_late_bound_regions(&self, value: ty::Binder<'tcx, T>) -> T where T: TypeFoldable<'tcx>, { From 30187c81f65aa29a53ad7c24fe3b4c7bff947094 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Mon, 5 Oct 2020 20:41:46 -0400 Subject: [PATCH 247/370] Track bound vars --- compiler/rustc_hir/src/hir.rs | 4 +- compiler/rustc_middle/src/ich/impls_ty.rs | 1 + compiler/rustc_middle/src/ty/codec.rs | 35 +- compiler/rustc_middle/src/ty/context.rs | 20 ++ compiler/rustc_middle/src/ty/fold.rs | 151 ++++++--- compiler/rustc_middle/src/ty/mod.rs | 14 +- .../rustc_middle/src/ty/structural_impls.rs | 6 +- compiler/rustc_middle/src/ty/sty.rs | 69 ++-- compiler/rustc_middle/src/ty/util.rs | 2 +- .../src/transform/check_consts/validation.rs | 9 +- .../src/traits/fulfill.rs | 2 +- .../src/traits/project.rs | 5 +- compiler/rustc_ty_utils/src/instance.rs | 2 +- compiler/rustc_typeck/src/astconv/mod.rs | 19 +- compiler/rustc_typeck/src/check/closure.rs | 17 +- .../rustc_typeck/src/check/compare_method.rs | 6 +- .../src/check/fn_ctxt/suggestions.rs | 2 +- .../src/check/generator_interior.rs | 4 +- compiler/rustc_typeck/src/check/intrinsic.rs | 2 +- .../rustc_typeck/src/check/method/confirm.rs | 2 +- compiler/rustc_typeck/src/check/method/mod.rs | 2 +- compiler/rustc_typeck/src/check/wfcheck.rs | 5 +- compiler/rustc_typeck/src/collect.rs | 34 +- src/librustdoc/clean/mod.rs | 312 +++++++++--------- src/librustdoc/clean/utils.rs | 12 +- src/test/ui/hrtb/complex.rs | 20 ++ .../repeated_projection_type.stderr | 2 +- src/test/ui/symbol-names/basic.legacy.stderr | 4 +- src/test/ui/symbol-names/impl1.legacy.stderr | 36 +- src/test/ui/symbol-names/impl1.rs | 3 +- src/test/ui/symbol-names/impl1.v0.stderr | 24 +- .../ui/symbol-names/issue-60925.legacy.stderr | 4 +- .../src/unit_return_expecting_ord.rs | 10 +- 33 files changed, 478 insertions(+), 362 deletions(-) create mode 100644 src/test/ui/hrtb/complex.rs diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 03af81ae02a..4ff5c0a678e 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -314,12 +314,12 @@ pub struct GenericArgs<'hir> { pub parenthesized: bool, } -impl GenericArgs<'_> { +impl<'tcx> GenericArgs<'tcx> { pub const fn none() -> Self { Self { args: &[], bindings: &[], parenthesized: false } } - pub fn inputs(&self) -> &[Ty<'_>] { + pub fn inputs(&self) -> &[Ty<'tcx>] { if self.parenthesized { for arg in self.args { match arg { diff --git a/compiler/rustc_middle/src/ich/impls_ty.rs b/compiler/rustc_middle/src/ich/impls_ty.rs index 60b1564d4c5..c39ea5825a7 100644 --- a/compiler/rustc_middle/src/ich/impls_ty.rs +++ b/compiler/rustc_middle/src/ich/impls_ty.rs @@ -124,6 +124,7 @@ where { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { self.as_ref().skip_binder().hash_stable(hcx, hasher); + self.bound_vars().hash_stable(hcx, hasher); } } diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 3a38f0c8521..d7767dc39cb 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -122,6 +122,7 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable for Ty<'tcx> { impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::Binder<'tcx, ty::PredicateKind<'tcx>> { fn encode(&self, e: &mut E) -> Result<(), E::Error> { + self.bound_vars().encode(e)?; encode_with_shorthand(e, &self.skip_binder(), TyEncoder::predicate_shorthands) } } @@ -228,16 +229,20 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable for Ty<'tcx> { impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Binder<'tcx, ty::PredicateKind<'tcx>> { fn decode(decoder: &mut D) -> Result>, D::Error> { + let bound_vars = Decodable::decode(decoder)?; // Handle shorthands first, if we have an usize > 0x80. - Ok(ty::Binder::bind(if decoder.positioned_at_shorthand() { - let pos = decoder.read_usize()?; - assert!(pos >= SHORTHAND_OFFSET); - let shorthand = pos - SHORTHAND_OFFSET; + Ok(ty::Binder::bind_with_vars( + if decoder.positioned_at_shorthand() { + let pos = decoder.read_usize()?; + assert!(pos >= SHORTHAND_OFFSET); + let shorthand = pos - SHORTHAND_OFFSET; - decoder.with_position(shorthand, ty::PredicateKind::decode)? - } else { - ty::PredicateKind::decode(decoder)? - })) + decoder.with_position(shorthand, ty::PredicateKind::decode)? + } else { + ty::PredicateKind::decode(decoder)? + }, + bound_vars, + )) } } @@ -379,6 +384,13 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [mir::abstract_const::N } } +impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List { + fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { + let len = decoder.read_usize()?; + Ok(decoder.tcx().mk_bound_variable_kinds((0..len).map(|_| Decodable::decode(decoder)))?) + } +} + impl_decodable_via_ref! { &'tcx ty::TypeckResults<'tcx>, &'tcx ty::List>, @@ -387,7 +399,8 @@ impl_decodable_via_ref! { &'tcx mir::Body<'tcx>, &'tcx mir::UnsafetyCheckResult, &'tcx mir::BorrowCheckResult<'tcx>, - &'tcx mir::coverage::CodeRegion + &'tcx mir::coverage::CodeRegion, + &'tcx ty::List } #[macro_export] @@ -490,12 +503,14 @@ macro_rules! impl_binder_encode_decode { $( impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::Binder<'tcx, $t> { fn encode(&self, e: &mut E) -> Result<(), E::Error> { + self.bound_vars().encode(e)?; self.as_ref().skip_binder().encode(e) } } impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Binder<'tcx, $t> { fn decode(decoder: &mut D) -> Result { - Ok(ty::Binder::bind(Decodable::decode(decoder)?)) + let bound_vars = Decodable::decode(decoder)?; + Ok(ty::Binder::bind_with_vars(Decodable::decode(decoder)?, bound_vars)) } } )* diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a7c05b42755..1f1840c0e4a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -96,6 +96,7 @@ pub struct CtxtInterners<'tcx> { const_: InternedSet<'tcx, Const<'tcx>>, /// Const allocations. allocation: InternedSet<'tcx, Allocation>, + bound_variable_kinds: InternedSet<'tcx, List>, } impl<'tcx> CtxtInterners<'tcx> { @@ -114,6 +115,7 @@ impl<'tcx> CtxtInterners<'tcx> { place_elems: Default::default(), const_: Default::default(), allocation: Default::default(), + bound_variable_kinds: Default::default(), } } @@ -1624,6 +1626,7 @@ nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>} nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>} nop_list_lift! {projs; ProjectionKind => ProjectionKind} +nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind} // This is the impl for `&'a InternalSubsts<'a>`. nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>} @@ -2080,6 +2083,7 @@ slice_interners!( predicates: _intern_predicates(Predicate<'tcx>), projs: _intern_projs(ProjectionKind), place_elems: _intern_place_elems(PlaceElem<'tcx>), + bound_variable_kinds: _intern_bound_variable_kinds(ty::BoundVariableKind), ); impl<'tcx> TyCtxt<'tcx> { @@ -2516,6 +2520,13 @@ impl<'tcx> TyCtxt<'tcx> { if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) } } + pub fn intern_bound_variable_kinds( + self, + ts: &[ty::BoundVariableKind], + ) -> &'tcx List { + if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) } + } + pub fn mk_fn_sig( self, inputs: I, @@ -2576,6 +2587,15 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned())) } + pub fn mk_bound_variable_kinds< + I: InternAs<[ty::BoundVariableKind], &'tcx List>, + >( + self, + iter: I, + ) -> I::Output { + iter.intern_with(|xs| self.intern_bound_variable_kinds(xs)) + } + /// Walks upwards from `id` to find a node which might change lint levels with attributes. /// It stops at `bound` and just returns it if reached. pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId { diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index fe26314ae2f..32101b4c8c9 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -35,6 +35,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::sso::SsoHashSet; use std::collections::BTreeMap; use std::fmt; use std::ops::ControlFlow; @@ -702,10 +703,109 @@ impl<'tcx> TyCtxt<'tcx> { r }) .0, + self, ) } } +pub struct BoundVarsCollector<'tcx> { + binder_index: ty::DebruijnIndex, + vars: BTreeMap, + // We may encounter the same variable at different levels of binding, so + // this can't just be `Ty` + visited: SsoHashSet<(ty::DebruijnIndex, Ty<'tcx>)>, +} + +impl<'tcx> BoundVarsCollector<'tcx> { + pub fn new() -> Self { + BoundVarsCollector { + binder_index: ty::INNERMOST, + vars: BTreeMap::new(), + visited: SsoHashSet::default(), + } + } + + pub fn into_vars(self, tcx: TyCtxt<'tcx>) -> &'tcx ty::List { + let max = self.vars.iter().map(|(k, _)| *k).max().unwrap_or_else(|| 0); + for i in 0..max { + if let None = self.vars.get(&i) { + panic!("Unknown variable: {:?}", i); + } + } + + tcx.mk_bound_variable_kinds(self.vars.into_iter().map(|(_, v)| v)) + } +} + +impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { + type BreakTy = (); + + fn visit_binder>( + &mut self, + t: &Binder<'tcx, T>, + ) -> ControlFlow { + self.binder_index.shift_in(1); + let result = t.super_visit_with(self); + self.binder_index.shift_out(1); + result + } + + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + if t.outer_exclusive_binder < self.binder_index + || !self.visited.insert((self.binder_index, t)) + { + return ControlFlow::CONTINUE; + } + use std::collections::btree_map::Entry; + match *t.kind() { + ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => { + match self.vars.entry(bound_ty.var.as_u32()) { + Entry::Vacant(entry) => { + entry.insert(ty::BoundVariableKind::Ty(bound_ty.kind)); + } + Entry::Occupied(entry) => match entry.get() { + ty::BoundVariableKind::Ty(_) => {} + _ => bug!("Conflicting bound vars"), + }, + } + } + + _ => (), + }; + + t.super_visit_with(self) + } + + fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { + use std::collections::btree_map::Entry; + match r { + ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind { + ty::BrNamed(_def_id, _name) => { + // FIXME + } + + ty::BrAnon(var) => match self.vars.entry(var) { + Entry::Vacant(entry) => { + entry.insert(ty::BoundVariableKind::Region(br.kind)); + } + Entry::Occupied(entry) => match entry.get() { + ty::BoundVariableKind::Region(_) => {} + _ => bug!("Conflicting bound vars"), + }, + }, + + ty::BrEnv => { + // FIXME + } + }, + + _ => (), + }; + + r.super_visit_with(self) + } +} + /////////////////////////////////////////////////////////////////////////// // Shifter // @@ -907,57 +1007,6 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { #[derive(Debug, PartialEq, Eq, Copy, Clone)] struct FoundFlags; -crate struct CountBoundVars { - crate outer_index: ty::DebruijnIndex, - crate bound_tys: FxHashSet, - crate bound_regions: FxHashSet, - crate bound_consts: FxHashSet, -} - -impl<'tcx> TypeVisitor<'tcx> for CountBoundVars { - type BreakTy = (); - - fn visit_binder>( - &mut self, - t: &Binder<'tcx, T>, - ) -> ControlFlow { - self.outer_index.shift_in(1); - let result = t.super_visit_with(self); - self.outer_index.shift_out(1); - result - } - - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { - match t.kind { - ty::Bound(debruijn, ty) if debruijn == self.outer_index => { - self.bound_tys.insert(ty); - ControlFlow::CONTINUE - } - _ => t.super_visit_with(self), - } - } - - fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { - match r { - ty::ReLateBound(debruijn, re) if *debruijn == self.outer_index => { - self.bound_regions.insert(*re); - ControlFlow::CONTINUE - } - _ => r.super_visit_with(self), - } - } - - fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> ControlFlow { - match ct.val { - ty::ConstKind::Bound(debruijn, c) if debruijn == self.outer_index => { - self.bound_consts.insert(c); - ControlFlow::CONTINUE - } - _ => ct.super_visit_with(self), - } - } -} - // FIXME: Optimize for checking for infer flags struct HasTypeFlagsVisitor { flags: ty::TypeFlags, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 29f82b47305..a09573fac02 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -67,12 +67,12 @@ pub use self::sty::BoundRegionKind::*; pub use self::sty::RegionKind::*; pub use self::sty::TyKind::*; pub use self::sty::{ - Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar, CanonicalPolyFnSig, - ClosureSubsts, ClosureSubstsParts, ConstVid, EarlyBoundRegion, ExistentialPredicate, - ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig, GeneratorSubsts, - GeneratorSubstsParts, ParamConst, ParamTy, PolyExistentialProjection, PolyExistentialTraitRef, - PolyFnSig, PolyGenSig, PolyTraitRef, ProjectionTy, Region, RegionKind, RegionVid, TraitRef, - TyKind, TypeAndMut, UpvarSubsts, + Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar, BoundVariableKind, + CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstVid, EarlyBoundRegion, + ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig, + GeneratorSubsts, GeneratorSubstsParts, ParamConst, ParamTy, PolyExistentialProjection, + PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, ProjectionTy, Region, RegionKind, + RegionVid, TraitRef, TyKind, TypeAndMut, UpvarSubsts, }; pub use self::trait_def::TraitDef; @@ -546,7 +546,7 @@ impl<'tcx> Predicate<'tcx> { let substs = trait_ref.skip_binder().substs; let pred = self.kind().skip_binder(); let new = pred.subst(tcx, substs); - tcx.reuse_or_mk_predicate(self, ty::Binder::bind(new)) + tcx.reuse_or_mk_predicate(self, ty::Binder::bind(new, tcx)) } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index dd4bb029747..a969626b370 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -460,8 +460,10 @@ where { type Lifted = ty::Binder<'tcx, T::Lifted>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { - // FIXME: need to lift inner values - tcx.lift(self.skip_binder()).map(|v| ty::Binder::bind(v)) + let bound_vars = tcx.lift(self.bound_vars()); + tcx.lift(self.skip_binder()) + .zip(bound_vars) + .map(|(value, vars)| ty::Binder::bind_with_vars(value, vars)) } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c6d72e78df8..1884df0c67b 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -5,6 +5,7 @@ use self::TyKind::*; use crate::infer::canonical::Canonical; +use crate::ty::fold::BoundVarsCollector; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::InferTy::{self, *}; use crate::ty::{ @@ -947,6 +948,14 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> { } } +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] +#[derive(HashStable)] +pub enum BoundVariableKind { + Ty(BoundTyKind), + Region(BoundRegionKind), + Const, +} + /// Binder is a binder for higher-ranked lifetimes or types. It is part of the /// compiler's representation for things like `for<'a> Fn(&'a isize)` /// (which would be represented by the type `PolyTraitRef == @@ -957,7 +966,7 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> { /// /// `Decodable` and `Encodable` are implemented for `Binder` using the `impl_binder_encode_decode!` macro. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub struct Binder<'tcx, T>(T, u32, std::marker::PhantomData<&'tcx ()>); +pub struct Binder<'tcx, T>(T, &'tcx List); impl<'tcx, T> Binder<'tcx, T> where @@ -969,48 +978,22 @@ where /// different binding level. pub fn dummy(value: T) -> Binder<'tcx, T> { debug_assert!(!value.has_escaping_bound_vars()); - Binder(value, 0, std::marker::PhantomData) + Binder(value, ty::List::empty()) } /// Wraps `value` in a binder, binding higher-ranked vars (if any). - pub fn bind(value: T) -> Binder<'tcx, T> { - use crate::ty::fold::CountBoundVars; - use rustc_data_structures::fx::FxHashSet; - let mut counter = CountBoundVars { - outer_index: ty::INNERMOST, - bound_tys: FxHashSet::default(), - bound_regions: FxHashSet::default(), - bound_consts: FxHashSet::default(), - }; - value.visit_with(&mut counter); - let bound_tys = counter.bound_tys.len(); - let bound_regions = if !counter.bound_regions.is_empty() { - let mut env = false; - let mut anons = FxHashSet::default(); - let mut named = FxHashSet::default(); - for br in counter.bound_regions { - match br.kind { - ty::BrAnon(idx) => { - anons.insert(idx); - } - ty::BrNamed(def_id, _) => { - named.insert(def_id); - } - ty::BrEnv => env = true, - } - } - (if env { 1 } else { 0 }) + anons.len() + named.len() - } else { - 0 - }; - let bound_consts = counter.bound_consts.len(); - - let bound_vars = bound_tys + bound_regions + bound_consts; - Binder(value, bound_vars as u32, std::marker::PhantomData) + pub fn bind(value: T, tcx: TyCtxt<'tcx>) -> Binder<'tcx, T> { + let mut collector = BoundVarsCollector::new(); + value.visit_with(&mut collector); + Binder(value, collector.into_vars(tcx)) } } impl<'tcx, T> Binder<'tcx, T> { + pub fn bind_with_vars(value: T, vars: &'tcx List) -> Binder<'tcx, T> { + Binder(value, vars) + } + /// Skips the binder and returns the "bound" value. This is a /// risky thing to do because it's easy to get confused about /// De Bruijn indices and the like. It is usually better to @@ -1031,12 +1014,12 @@ impl<'tcx, T> Binder<'tcx, T> { self.0 } - pub fn bound_vars(&self) -> u32 { + pub fn bound_vars(&self) -> &'tcx List { self.1 } pub fn as_ref(&self) -> Binder<'tcx, &T> { - Binder(&self.0, self.1, std::marker::PhantomData) + Binder(&self.0, self.1) } pub fn map_bound_ref(&self, f: F) -> Binder<'tcx, U> @@ -1050,7 +1033,7 @@ impl<'tcx, T> Binder<'tcx, T> { where F: FnOnce(T) -> U, { - Binder(f(self.0), self.1, std::marker::PhantomData) + Binder(f(self.0), self.1) } /// Wraps a `value` in a binder, using the same bound variables as the @@ -1063,7 +1046,7 @@ impl<'tcx, T> Binder<'tcx, T> { /// because bound vars aren't allowed to change here, whereas they are /// in `bind`. This may be (debug) asserted in the future. pub fn rebind(&self, value: U) -> Binder<'tcx, U> { - Binder(value, self.1, std::marker::PhantomData) + Binder(value, self.1) } /// Unwraps and returns the value within, but only if it contains @@ -1094,7 +1077,7 @@ impl<'tcx, T> Binder<'tcx, T> { where F: FnOnce(T, U) -> R, { - Binder(f(self.0, u.0), self.1, std::marker::PhantomData) + Binder(f(self.0, u.0), self.1) } /// Splits the contents into two things that share the same binder @@ -1108,14 +1091,14 @@ impl<'tcx, T> Binder<'tcx, T> { F: FnOnce(T) -> (U, V), { let (u, v) = f(self.0); - (Binder(u, self.1, std::marker::PhantomData), Binder(v, self.1, std::marker::PhantomData)) + (Binder(u, self.1), Binder(v, self.1)) } } impl<'tcx, T> Binder<'tcx, Option> { pub fn transpose(self) -> Option> { let bound_vars = self.1; - self.0.map(|v| Binder(v, bound_vars, std::marker::PhantomData)) + self.0.map(|v| Binder(v, bound_vars)) } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index be9ba56f097..93fbc1f53b2 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -510,7 +510,7 @@ impl<'tcx> TyCtxt<'tcx> { ty::ClosureKind::FnMut => self.mk_mut_ref(self.mk_region(env_region), closure_ty), ty::ClosureKind::FnOnce => closure_ty, }; - Some(ty::Binder::bind(env_ty)) + Some(ty::Binder::bind(env_ty, self)) } /// Returns `true` if the node pointed to by `def_id` is a `static` item. diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index 1ad7b8fbbd5..ce5e41d3e7c 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -850,9 +850,12 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { let obligation = Obligation::new( ObligationCause::dummy(), param_env, - Binder::bind(TraitPredicate { - trait_ref: TraitRef::from_method(tcx, trait_id, substs), - }), + Binder::bind( + TraitPredicate { + trait_ref: TraitRef::from_method(tcx, trait_id, substs), + }, + tcx, + ), ); let implsrc = tcx.infer_ctxt().enter(|infcx| { diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 79f65669479..fc9739f70d4 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -684,7 +684,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { /// Returns the set of inference variables contained in `substs`. fn substs_infer_vars<'a, 'tcx>( selcx: &mut SelectionContext<'a, 'tcx>, - substs: ty::Binder>, + substs: ty::Binder<'tcx, SubstsRef<'tcx>>, ) -> impl Iterator> { selcx .infcx() diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 0af6d645915..b3e5df4da0a 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1275,6 +1275,9 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>( let tcx = selcx.tcx(); let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty()); + // We get here from `poly_project_and_unify_type` which replaces bound vars + // with placeholders + debug_assert!(!self_ty.has_escaping_bound_vars()); let substs = tcx.mk_substs([self_ty.into()].iter()); let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None); @@ -1306,7 +1309,7 @@ fn confirm_pointee_candidate<'cx, 'tcx>( ty: self_ty.ptr_metadata_ty(tcx), }; - confirm_param_env_candidate(selcx, obligation, ty::Binder::bind(predicate), false) + confirm_param_env_candidate(selcx, obligation, ty::Binder::bind(predicate, tcx), false) } fn confirm_fn_pointer_candidate<'cx, 'tcx>( diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 6b9d46ee0af..874289d0293 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -115,7 +115,7 @@ fn resolve_associated_item<'tcx>( ); let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs); - let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref)))?; + let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref, tcx)))?; // Now that we know which impl is being used, we can dispatch to // the actual function: diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 1e194771709..48f2bf1518b 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -658,7 +658,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty, trait_ref.path.segments.last().unwrap(), ); - let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs)); + let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs), self.tcx()); bounds.trait_bounds.push((poly_trait_ref, span, constness)); @@ -741,7 +741,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { false, Some(self_ty), ); - let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs)); + let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs), self.tcx()); bounds.trait_bounds.push((poly_trait_ref, span, Constness::NotConst)); let mut dup_bindings = FxHashMap::default(); @@ -878,9 +878,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .instantiate_lang_item_trait_ref( *lang_item, *span, *hir_id, args, param_ty, bounds, ), - hir::GenericBound::Outlives(ref l) => bounds - .region_bounds - .push((ty::Binder::bind(self.ast_region_to_region(l, None)), l.span)), + hir::GenericBound::Outlives(ref l) => bounds.region_bounds.push(( + ty::Binder::bind(self.ast_region_to_region(l, None), self.tcx()), + l.span, + )), } } } @@ -1664,7 +1665,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }; self.one_bound_for_assoc_type( - || traits::supertraits(tcx, ty::Binder::bind(trait_ref)), + || traits::supertraits(tcx, ty::Binder::bind(trait_ref, tcx)), || "Self".to_string(), assoc_ident, span, @@ -2368,8 +2369,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!("ty_of_fn: output_ty={:?}", output_ty); - let bare_fn_ty = - ty::Binder::bind(tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi)); + let bare_fn_ty = ty::Binder::bind( + tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi), + tcx, + ); if !self.allow_ty_infer() { // We always collect the spans for placeholder types when evaluating `fn`s, but we diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs index 4099ecd435d..2f30621b019 100644 --- a/compiler/rustc_typeck/src/check/closure.rs +++ b/compiler/rustc_typeck/src/check/closure.rs @@ -571,13 +571,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, }; - let result = ty::Binder::bind(self.tcx.mk_fn_sig( - supplied_arguments, - supplied_return, - decl.c_variadic, - hir::Unsafety::Normal, - Abi::RustCall, - )); + let result = ty::Binder::bind( + self.tcx.mk_fn_sig( + supplied_arguments, + supplied_return, + decl.c_variadic, + hir::Unsafety::Normal, + Abi::RustCall, + ), + self.tcx, + ); debug!("supplied_sig_of_closure: result={:?}", result); diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 70f850084a8..f044daa4509 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -225,7 +225,7 @@ fn compare_predicate_entailment<'tcx>( let (impl_m_own_bounds, _) = infcx.replace_bound_vars_with_fresh_vars( impl_m_span, infer::HigherRankedType, - ty::Binder::bind(impl_m_own_bounds.predicates), + ty::Binder::bind(impl_m_own_bounds.predicates, tcx), ); for predicate in impl_m_own_bounds { let traits::Normalized { value: predicate, obligations } = @@ -258,14 +258,14 @@ fn compare_predicate_entailment<'tcx>( ); let impl_sig = inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, impl_sig); - let impl_fty = tcx.mk_fn_ptr(ty::Binder::bind(impl_sig)); + let impl_fty = tcx.mk_fn_ptr(ty::Binder::bind(impl_sig, tcx)); debug!("compare_impl_method: impl_fty={:?}", impl_fty); let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, tcx.fn_sig(trait_m.def_id)); let trait_sig = trait_sig.subst(tcx, trait_to_placeholder_substs); let trait_sig = inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, trait_sig); - let trait_fty = tcx.mk_fn_ptr(ty::Binder::bind(trait_sig)); + let trait_fty = tcx.mk_fn_ptr(ty::Binder::bind(trait_sig, tcx)); debug!("compare_impl_method: trait_fty={:?}", trait_fty); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index bd89c7274e7..b940e90fadb 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -486,7 +486,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let found = self.resolve_vars_with_obligations(found); if let hir::FnRetTy::Return(ty) = fn_decl.output { let ty = >::ast_ty_to_ty(self, ty); - let ty = self.tcx.erase_late_bound_regions(Binder::bind(ty)); + let ty = self.tcx.erase_late_bound_regions(Binder::bind(ty, self.tcx)); let ty = self.normalize_associated_types_in(expr.span, ty); if self.can_coerce(found, ty) { err.multipart_suggestion( diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index 91708465b3f..969359a3c21 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -202,11 +202,11 @@ pub fn resolve_interior<'a, 'tcx>( // Extract type components to build the witness type. let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty)); - let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list)); + let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list, fcx.tcx)); // Store the generator types and spans into the typeck results for this generator. visitor.fcx.inh.typeck_results.borrow_mut().generator_interior_types = - ty::Binder::bind(type_causes); + ty::Binder::bind(type_causes, fcx.tcx); debug!( "types in generator after region replacement {:?}, span = {:?}", diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index 990ed5abdbf..3b399b86718 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -366,7 +366,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { (n_tps, inputs, output, unsafety) }; let sig = tcx.mk_fn_sig(inputs.into_iter(), output, false, unsafety, Abi::RustIntrinsic); - let sig = ty::Binder::bind(sig); + let sig = ty::Binder::bind(sig, tcx); equate_intrinsic_type(tcx, it, n_tps, sig) } diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index 901a874980d..900bd2885fd 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -119,7 +119,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // We won't add these if we encountered an illegal sized bound, so that we can use // a custom error in that case. if illegal_sized_bound.is_none() { - let method_ty = self.tcx.mk_fn_ptr(ty::Binder::bind(method_sig)); + let method_ty = self.tcx.mk_fn_ptr(ty::Binder::bind(method_sig, self.tcx)); self.add_obligations(method_ty, all_substs, method_predicates); } diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index c74fd25f76d..bd7ffd057b4 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -399,7 +399,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { obligations.extend(traits::predicates_for_generics(cause.clone(), self.param_env, bounds)); // Also add an obligation for the method type being well-formed. - let method_ty = tcx.mk_fn_ptr(ty::Binder::bind(fn_sig)); + let method_ty = tcx.mk_fn_ptr(ty::Binder::bind(fn_sig, tcx)); debug!( "lookup_in_trait_adjusted: matched method method_ty={:?} obligation={:?}", method_ty, obligation diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index e7e603c8bd5..887cc42a1dd 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -1067,13 +1067,14 @@ fn check_method_receiver<'fcx, 'tcx>( debug!("check_method_receiver: sig={:?}", sig); let self_ty = fcx.normalize_associated_types_in(span, self_ty); - let self_ty = fcx.tcx.liberate_late_bound_regions(method.def_id, ty::Binder::bind(self_ty)); + let self_ty = + fcx.tcx.liberate_late_bound_regions(method.def_id, ty::Binder::bind(self_ty, fcx.tcx)); let receiver_ty = sig.inputs()[0]; let receiver_ty = fcx.normalize_associated_types_in(span, receiver_ty); let receiver_ty = - fcx.tcx.liberate_late_bound_regions(method.def_id, ty::Binder::bind(receiver_ty)); + fcx.tcx.liberate_late_bound_regions(method.def_id, ty::Binder::bind(receiver_ty, fcx.tcx)); if fcx.tcx.features().arbitrary_self_types { if !receiver_is_valid(fcx, span, receiver_ty, self_ty, true) { diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 0ef5f4d1c18..b42ef7efcbc 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1707,7 +1707,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { } diag.emit(); - ty::Binder::bind(fn_sig) + ty::Binder::bind(fn_sig, tcx) } None => >::ty_of_fn( &icx, @@ -1749,13 +1749,10 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { let ty = tcx.type_of(tcx.hir().get_parent_did(hir_id).to_def_id()); let inputs = data.fields().iter().map(|f| tcx.type_of(tcx.hir().local_def_id(f.hir_id))); - ty::Binder::bind(tcx.mk_fn_sig( - inputs, - ty, - false, - hir::Unsafety::Normal, - abi::Abi::Rust, - )) + ty::Binder::bind( + tcx.mk_fn_sig(inputs, ty, false, hir::Unsafety::Normal, abi::Abi::Rust), + tcx, + ) } Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => { @@ -2039,7 +2036,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP param.bounds.iter().for_each(|bound| match bound { hir::GenericBound::Outlives(lt) => { let bound = >::ast_region_to_region(&icx, <, None); - let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound)); + let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound), tcx); predicates.insert((outlives.to_predicate(tcx), lt.span)); } _ => bug!(), @@ -2099,9 +2096,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP } else { let span = bound_pred.bounded_ty.span; let re_root_empty = tcx.lifetimes.re_root_empty; - let predicate = ty::Binder::bind(ty::PredicateKind::TypeOutlives( - ty::OutlivesPredicate(ty, re_root_empty), - )); + let predicate = ty::Binder::bind( + ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate( + ty, + re_root_empty, + )), + tcx, + ); predicates.insert((predicate.to_predicate(tcx), span)); } } @@ -2144,9 +2145,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP let region = >::ast_region_to_region(&icx, lifetime, None); predicates.insert(( - ty::Binder::bind(ty::PredicateKind::TypeOutlives( - ty::OutlivesPredicate(ty, region), - )) + ty::Binder::bind( + ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate( + ty, region, + )), + tcx, + ) .to_predicate(tcx), lifetime.span, )); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4d33a1e6961..dac42058b1b 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -48,42 +48,42 @@ crate use self::types::Type::*; crate use self::types::Visibility::{Inherited, Public}; crate use self::types::*; -crate trait Clean { - fn clean(&self, cx: &mut DocContext<'_>) -> T; +crate trait Clean<'tcx, T> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> T; } -impl, U> Clean> for [T] { - fn clean(&self, cx: &mut DocContext<'_>) -> Vec { +impl<'tcx, T: Clean<'tcx, U>, U> Clean<'tcx, Vec> for [T] { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Vec { self.iter().map(|x| x.clean(cx)).collect() } } -impl, U, V: Idx> Clean> for IndexVec { - fn clean(&self, cx: &mut DocContext<'_>) -> IndexVec { +impl<'tcx, T: Clean<'tcx, U>, U, V: Idx> Clean<'tcx, IndexVec> for IndexVec { + fn clean(&self, cx: &mut DocContext<'tcx>) -> IndexVec { self.iter().map(|x| x.clean(cx)).collect() } } -impl, U> Clean for &T { - fn clean(&self, cx: &mut DocContext<'_>) -> U { +impl<'tcx, T: Clean<'tcx, U>, U> Clean<'tcx, U> for &T { + fn clean(&self, cx: &mut DocContext<'tcx>) -> U { (**self).clean(cx) } } -impl, U> Clean for Rc { - fn clean(&self, cx: &mut DocContext<'_>) -> U { +impl<'tcx, T: Clean<'tcx, U>, U> Clean<'tcx, U> for Rc { + fn clean(&self, cx: &mut DocContext<'tcx>) -> U { (**self).clean(cx) } } -impl, U> Clean> for Option { - fn clean(&self, cx: &mut DocContext<'_>) -> Option { +impl<'tcx, T: Clean<'tcx, U>, U> Clean<'tcx, Option> for Option { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Option { self.as_ref().map(|v| v.clean(cx)) } } -impl Clean for CrateNum { - fn clean(&self, cx: &mut DocContext<'_>) -> ExternalCrate { +impl<'tcx> Clean<'tcx, ExternalCrate> for CrateNum { + fn clean(&self, cx: &mut DocContext<'tcx>) -> ExternalCrate { let tcx = cx.tcx; let root = DefId { krate: *self, index: CRATE_DEF_INDEX }; let krate_span = tcx.def_span(root); @@ -204,8 +204,8 @@ impl Clean for CrateNum { } } -impl Clean for doctree::Module<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for doctree::Module<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let mut items: Vec = vec![]; items.extend(self.foreigns.iter().map(|x| x.clean(cx))); items.extend(self.mods.iter().map(|x| x.clean(cx))); @@ -237,14 +237,14 @@ impl Clean for doctree::Module<'_> { } } -impl Clean for [ast::Attribute] { - fn clean(&self, cx: &mut DocContext<'_>) -> Attributes { +impl<'tcx> Clean<'tcx, Attributes> for [ast::Attribute] { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Attributes { Attributes::from_ast(cx.sess().diagnostic(), self, None) } } -impl Clean for hir::GenericBound<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound { +impl<'tcx> Clean<'tcx, GenericBound> for hir::GenericBound<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericBound { match *self { hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)), hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => { @@ -270,8 +270,8 @@ impl Clean for hir::GenericBound<'_> { } } -impl Clean for (ty::TraitRef<'_>, &[TypeBinding]) { - fn clean(&self, cx: &mut DocContext<'_>) -> Type { +impl<'tcx> Clean<'tcx, Type> for (ty::TraitRef<'tcx>, &[TypeBinding]) { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { let (trait_ref, bounds) = *self; inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait); let path = external_path( @@ -289,8 +289,8 @@ impl Clean for (ty::TraitRef<'_>, &[TypeBinding]) { } } -impl<'tcx> Clean for ty::TraitRef<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound { +impl<'tcx> Clean<'tcx, GenericBound> for ty::TraitRef<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericBound { GenericBound::TraitBound( PolyTrait { trait_: (*self, &[][..]).clean(cx), generic_params: vec![] }, hir::TraitBoundModifier::None, @@ -298,8 +298,8 @@ impl<'tcx> Clean for ty::TraitRef<'tcx> { } } -impl Clean for (ty::PolyTraitRef<'_>, &[TypeBinding]) { - fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound { +impl<'tcx> Clean<'tcx, GenericBound> for (ty::PolyTraitRef<'tcx>, &[TypeBinding]) { + fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericBound { let (poly_trait_ref, bounds) = *self; let poly_trait_ref = poly_trait_ref.lift_to_tcx(cx.tcx).unwrap(); @@ -326,14 +326,14 @@ impl Clean for (ty::PolyTraitRef<'_>, &[TypeBinding]) { } } -impl<'tcx> Clean for ty::PolyTraitRef<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound { +impl<'tcx> Clean<'tcx, GenericBound> for ty::PolyTraitRef<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericBound { (*self, &[][..]).clean(cx) } } -impl<'tcx> Clean>> for InternalSubsts<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> Option> { +impl<'tcx> Clean<'tcx, Option>> for InternalSubsts<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Option> { let mut v = Vec::new(); v.extend(self.regions().filter_map(|r| r.clean(cx)).map(GenericBound::Outlives)); v.extend(self.types().map(|t| { @@ -346,8 +346,8 @@ impl<'tcx> Clean>> for InternalSubsts<'tcx> { } } -impl Clean for hir::Lifetime { - fn clean(&self, cx: &mut DocContext<'_>) -> Lifetime { +impl<'tcx> Clean<'tcx, Lifetime> for hir::Lifetime { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Lifetime { let def = cx.tcx.named_region(self.hir_id); match def { Some( @@ -365,8 +365,8 @@ impl Clean for hir::Lifetime { } } -impl Clean for hir::GenericParam<'_> { - fn clean(&self, _: &mut DocContext<'_>) -> Lifetime { +impl<'tcx> Clean<'tcx, Lifetime> for hir::GenericParam<'tcx> { + fn clean(&self, _: &mut DocContext<'tcx>) -> Lifetime { match self.kind { hir::GenericParamKind::Lifetime { .. } => { if !self.bounds.is_empty() { @@ -389,8 +389,8 @@ impl Clean for hir::GenericParam<'_> { } } -impl Clean for hir::ConstArg { - fn clean(&self, cx: &mut DocContext<'_>) -> Constant { +impl<'tcx> Clean<'tcx, Constant> for hir::ConstArg { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Constant { Constant { type_: cx .tcx @@ -401,14 +401,14 @@ impl Clean for hir::ConstArg { } } -impl Clean for ty::GenericParamDef { - fn clean(&self, _cx: &mut DocContext<'_>) -> Lifetime { +impl<'tcx> Clean<'tcx, Lifetime> for ty::GenericParamDef { + fn clean(&self, _cx: &mut DocContext<'tcx>) -> Lifetime { Lifetime(self.name) } } -impl Clean> for ty::RegionKind { - fn clean(&self, _cx: &mut DocContext<'_>) -> Option { +impl<'tcx> Clean<'tcx, Option> for ty::RegionKind { + fn clean(&self, _cx: &mut DocContext<'tcx>) -> Option { match *self { ty::ReStatic => Some(Lifetime::statik()), ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name) }) => { @@ -429,8 +429,8 @@ impl Clean> for ty::RegionKind { } } -impl Clean for hir::WherePredicate<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate { +impl<'tcx> Clean<'tcx, WherePredicate> for hir::WherePredicate<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> WherePredicate { match *self { hir::WherePredicate::BoundPredicate(ref wbp) => WherePredicate::BoundPredicate { ty: wbp.bounded_ty.clean(cx), @@ -449,8 +449,8 @@ impl Clean for hir::WherePredicate<'_> { } } -impl<'a> Clean> for ty::Predicate<'a> { - fn clean(&self, cx: &mut DocContext<'_>) -> Option { +impl<'a> Clean<'a, Option> for ty::Predicate<'a> { + fn clean(&self, cx: &mut DocContext<'a>) -> Option { let bound_predicate = self.kind(); match bound_predicate.skip_binder() { ty::PredicateKind::Trait(pred, _) => Some(bound_predicate.rebind(pred).clean(cx)), @@ -469,8 +469,8 @@ impl<'a> Clean> for ty::Predicate<'a> { } } -impl<'a> Clean for ty::PolyTraitPredicate<'a> { - fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate { +impl<'tcx> Clean<'tcx, WherePredicate> for ty::PolyTraitPredicate<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> WherePredicate { let poly_trait_ref = self.map_bound(|pred| pred.trait_ref); WherePredicate::BoundPredicate { ty: poly_trait_ref.skip_binder().self_ty().clean(cx), @@ -479,10 +479,10 @@ impl<'a> Clean for ty::PolyTraitPredicate<'a> { } } -impl<'tcx> Clean> +impl<'tcx> Clean<'tcx, Option> for ty::OutlivesPredicate, ty::Region<'tcx>> { - fn clean(&self, cx: &mut DocContext<'_>) -> Option { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Option { let ty::OutlivesPredicate(a, b) = self; if let (ty::ReEmpty(_), ty::ReEmpty(_)) = (a, b) { @@ -496,8 +496,10 @@ impl<'tcx> Clean> } } -impl<'tcx> Clean> for ty::OutlivesPredicate, ty::Region<'tcx>> { - fn clean(&self, cx: &mut DocContext<'_>) -> Option { +impl<'tcx> Clean<'tcx, Option> + for ty::OutlivesPredicate, ty::Region<'tcx>> +{ + fn clean(&self, cx: &mut DocContext<'tcx>) -> Option { let ty::OutlivesPredicate(ty, lt) = self; if let ty::ReEmpty(_) = lt { @@ -511,15 +513,15 @@ impl<'tcx> Clean> for ty::OutlivesPredicate, ty: } } -impl<'tcx> Clean for ty::ProjectionPredicate<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate { +impl<'tcx> Clean<'tcx, WherePredicate> for ty::ProjectionPredicate<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> WherePredicate { let ty::ProjectionPredicate { projection_ty, ty } = self; WherePredicate::EqPredicate { lhs: projection_ty.clean(cx), rhs: ty.clean(cx) } } } -impl<'tcx> Clean for ty::ProjectionTy<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> Type { +impl<'tcx> Clean<'tcx, Type> for ty::ProjectionTy<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { let lifted = self.lift_to_tcx(cx.tcx).unwrap(); let trait_ = match lifted.trait_ref(cx.tcx).clean(cx) { GenericBound::TraitBound(t, _) => t.trait_, @@ -533,8 +535,8 @@ impl<'tcx> Clean for ty::ProjectionTy<'tcx> { } } -impl Clean for ty::GenericParamDef { - fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef { +impl<'tcx> Clean<'tcx, GenericParamDef> for ty::GenericParamDef { + fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericParamDef { let (name, kind) = match self.kind { ty::GenericParamDefKind::Lifetime => (self.name, GenericParamDefKind::Lifetime), ty::GenericParamDefKind::Type { has_default, synthetic, .. } => { @@ -563,8 +565,8 @@ impl Clean for ty::GenericParamDef { } } -impl Clean for hir::GenericParam<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef { +impl<'tcx> Clean<'tcx, GenericParamDef> for hir::GenericParam<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericParamDef { let (name, kind) = match self.kind { hir::GenericParamKind::Lifetime { .. } => { let name = if !self.bounds.is_empty() { @@ -606,8 +608,8 @@ impl Clean for hir::GenericParam<'_> { } } -impl Clean for hir::Generics<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Generics { +impl<'tcx> Clean<'tcx, Generics> for hir::Generics<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Generics { // Synthetic type-parameters are inserted after normal ones. // In order for normal parameters to be able to refer to synthetic ones, // scans them first. @@ -686,8 +688,8 @@ impl Clean for hir::Generics<'_> { } } -impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx>) { - fn clean(&self, cx: &mut DocContext<'_>) -> Generics { +impl<'a, 'tcx> Clean<'tcx, Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx>) { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Generics { use self::WherePredicate as WP; use std::collections::BTreeMap; @@ -851,13 +853,13 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx } } -fn clean_fn_or_proc_macro( - item: &hir::Item<'_>, - sig: &'a hir::FnSig<'a>, - generics: &'a hir::Generics<'a>, +fn clean_fn_or_proc_macro<'a, 'tcx>( + item: &hir::Item<'tcx>, + sig: &'a hir::FnSig<'tcx>, + generics: &'a hir::Generics<'tcx>, body_id: hir::BodyId, name: &mut Symbol, - cx: &mut DocContext<'_>, + cx: &mut DocContext<'tcx>, ) -> ItemKind { let attrs = cx.tcx.hir().attrs(item.hir_id()); let macro_kind = attrs.iter().find_map(|a| { @@ -911,16 +913,18 @@ fn clean_fn_or_proc_macro( } } -impl<'a> Clean for (&'a hir::FnSig<'a>, &'a hir::Generics<'a>, hir::BodyId) { - fn clean(&self, cx: &mut DocContext<'_>) -> Function { +impl<'a, 'tcx> Clean<'tcx, Function> + for (&'a hir::FnSig<'tcx>, &'a hir::Generics<'tcx>, hir::BodyId) +{ + fn clean(&self, cx: &mut DocContext<'tcx>) -> Function { let (generics, decl) = enter_impl_trait(cx, |cx| (self.1.clean(cx), (&*self.0.decl, self.2).clean(cx))); Function { decl, generics, header: self.0.header } } } -impl<'a> Clean for (&'a [hir::Ty<'a>], &'a [Ident]) { - fn clean(&self, cx: &mut DocContext<'_>) -> Arguments { +impl<'a, 'tcx> Clean<'tcx, Arguments> for (&'a [hir::Ty<'tcx>], &'a [Ident]) { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Arguments { Arguments { values: self .0 @@ -938,8 +942,8 @@ impl<'a> Clean for (&'a [hir::Ty<'a>], &'a [Ident]) { } } -impl<'a> Clean for (&'a [hir::Ty<'a>], hir::BodyId) { - fn clean(&self, cx: &mut DocContext<'_>) -> Arguments { +impl<'a, 'tcx> Clean<'tcx, Arguments> for (&'a [hir::Ty<'tcx>], hir::BodyId) { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Arguments { let body = cx.tcx.hir().body(self.1); Arguments { @@ -948,7 +952,7 @@ impl<'a> Clean for (&'a [hir::Ty<'a>], hir::BodyId) { .iter() .enumerate() .map(|(i, ty)| Argument { - name: name_from_pat(&body.params[i].pat), + name: Symbol::intern(&rustc_hir_pretty::param_to_string(&body.params[i])), type_: ty.clean(cx), }) .collect(), @@ -956,13 +960,13 @@ impl<'a> Clean for (&'a [hir::Ty<'a>], hir::BodyId) { } } -impl<'a, A: Copy> Clean for (&'a hir::FnDecl<'a>, A) +impl<'a, 'tcx, A: Copy> Clean<'tcx, FnDecl> for (&'a hir::FnDecl<'tcx>, A) where - (&'a [hir::Ty<'a>], A): Clean, + (&'a [hir::Ty<'a>], A): Clean<'tcx, Arguments>, { - fn clean(&self, cx: &mut DocContext<'_>) -> FnDecl { + fn clean(&self, cx: &mut DocContext<'tcx>) -> FnDecl { FnDecl { - inputs: (self.0.inputs, self.1).clean(cx), + inputs: (&self.0.inputs[..], self.1).clean(cx), output: self.0.output.clean(cx), c_variadic: self.0.c_variadic, attrs: Attributes::default(), @@ -970,8 +974,8 @@ where } } -impl<'tcx> Clean for (DefId, ty::PolyFnSig<'tcx>) { - fn clean(&self, cx: &mut DocContext<'_>) -> FnDecl { +impl<'tcx> Clean<'tcx, FnDecl> for (DefId, ty::PolyFnSig<'tcx>) { + fn clean(&self, cx: &mut DocContext<'tcx>) -> FnDecl { let (did, sig) = *self; let mut names = if did.is_local() { &[] } else { cx.tcx.fn_arg_names(did) }.iter(); @@ -994,8 +998,8 @@ impl<'tcx> Clean for (DefId, ty::PolyFnSig<'tcx>) { } } -impl Clean for hir::FnRetTy<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> FnRetTy { +impl<'tcx> Clean<'tcx, FnRetTy> for hir::FnRetTy<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> FnRetTy { match *self { Self::Return(ref typ) => Return(typ.clean(cx)), Self::DefaultReturn(..) => DefaultReturn, @@ -1003,7 +1007,7 @@ impl Clean for hir::FnRetTy<'_> { } } -impl Clean for hir::IsAuto { +impl Clean<'_, bool> for hir::IsAuto { fn clean(&self, _: &mut DocContext<'_>) -> bool { match *self { hir::IsAuto::Yes => true, @@ -1012,15 +1016,15 @@ impl Clean for hir::IsAuto { } } -impl Clean for hir::TraitRef<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Type { +impl<'tcx> Clean<'tcx, Type> for hir::TraitRef<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { let path = self.path.clean(cx); resolve_type(cx, path, self.hir_ref_id) } } -impl Clean for hir::PolyTraitRef<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> PolyTrait { +impl<'tcx> Clean<'tcx, PolyTrait> for hir::PolyTraitRef<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> PolyTrait { PolyTrait { trait_: self.trait_ref.clean(cx), generic_params: self.bound_generic_params.clean(cx), @@ -1028,14 +1032,14 @@ impl Clean for hir::PolyTraitRef<'_> { } } -impl Clean for hir::def::DefKind { - fn clean(&self, _: &mut DocContext<'_>) -> TypeKind { +impl<'tcx> Clean<'tcx, TypeKind> for hir::def::DefKind { + fn clean(&self, _: &mut DocContext<'tcx>) -> TypeKind { (*self).into() } } -impl Clean for hir::TraitItem<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for hir::TraitItem<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let local_did = self.def_id.to_def_id(); cx.with_param_env(local_did, |cx| { let inner = match self.kind { @@ -1075,8 +1079,8 @@ impl Clean for hir::TraitItem<'_> { } } -impl Clean for hir::ImplItem<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for hir::ImplItem<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let local_did = self.def_id.to_def_id(); cx.with_param_env(local_did, |cx| { let inner = match self.kind { @@ -1124,8 +1128,8 @@ impl Clean for hir::ImplItem<'_> { } } -impl Clean for ty::AssocItem { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for ty::AssocItem { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let tcx = cx.tcx; let kind = match self.kind { ty::AssocKind::Const => { @@ -1276,7 +1280,7 @@ impl Clean for ty::AssocItem { } } -fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { +fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type { use rustc_hir::GenericParamCount; let hir::Ty { hir_id, span, ref kind } = *hir_ty; let qpath = match kind { @@ -1428,8 +1432,8 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { } } -impl Clean for hir::Ty<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Type { +impl<'tcx> Clean<'tcx, Type> for hir::Ty<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { use rustc_hir::*; match self.kind { @@ -1531,8 +1535,8 @@ fn normalize(cx: &mut DocContext<'tcx>, ty: Ty<'_>) -> Option> { } } -impl<'tcx> Clean for Ty<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> Type { +impl<'tcx> Clean<'tcx, Type> for Ty<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { debug!("cleaning type: {:?}", self); let ty = normalize(cx, self).unwrap_or(self); match *ty.kind() { @@ -1739,8 +1743,8 @@ impl<'tcx> Clean for Ty<'tcx> { } } -impl<'tcx> Clean for ty::Const<'tcx> { - fn clean(&self, cx: &mut DocContext<'_>) -> Constant { +impl<'tcx> Clean<'tcx, Constant> for ty::Const<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Constant { // FIXME: instead of storing the stringified expression, store `self` directly instead. Constant { type_: self.ty.clean(cx), @@ -1749,8 +1753,8 @@ impl<'tcx> Clean for ty::Const<'tcx> { } } -impl Clean for hir::FieldDef<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for hir::FieldDef<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let what_rustc_thinks = Item::from_hir_id_and_parts( self.hir_id, Some(self.ident.name), @@ -1762,8 +1766,8 @@ impl Clean for hir::FieldDef<'_> { } } -impl Clean for ty::FieldDef { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl Clean<'tcx, Item> for ty::FieldDef { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let what_rustc_thinks = Item::from_def_id_and_parts( self.did, Some(self.ident.name), @@ -1775,8 +1779,8 @@ impl Clean for ty::FieldDef { } } -impl Clean for hir::Visibility<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Visibility { +impl<'tcx> Clean<'tcx, Visibility> for hir::Visibility<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Visibility { match self.node { hir::VisibilityKind::Public => Visibility::Public, hir::VisibilityKind::Inherited => Visibility::Inherited, @@ -1793,8 +1797,8 @@ impl Clean for hir::Visibility<'_> { } } -impl Clean for ty::Visibility { - fn clean(&self, _cx: &mut DocContext<'_>) -> Visibility { +impl<'tcx> Clean<'tcx, Visibility> for ty::Visibility { + fn clean(&self, _cx: &mut DocContext<'tcx>) -> Visibility { match *self { ty::Visibility::Public => Visibility::Public, // NOTE: this is not quite right: `ty` uses `Invisible` to mean 'private', @@ -1808,8 +1812,8 @@ impl Clean for ty::Visibility { } } -impl Clean for rustc_hir::VariantData<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> VariantStruct { +impl<'tcx> Clean<'tcx, VariantStruct> for rustc_hir::VariantData<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> VariantStruct { VariantStruct { struct_type: CtorKind::from_hir(self), fields: self.fields().iter().map(|x| x.clean(cx)).collect(), @@ -1818,8 +1822,8 @@ impl Clean for rustc_hir::VariantData<'_> { } } -impl Clean for ty::VariantDef { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for ty::VariantDef { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let kind = match self.ctor_kind { CtorKind::Const => Variant::CLike, CtorKind::Fn => Variant::Tuple( @@ -1849,8 +1853,8 @@ impl Clean for ty::VariantDef { } } -impl Clean for hir::VariantData<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Variant { +impl<'tcx> Clean<'tcx, Variant> for hir::VariantData<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Variant { match self { hir::VariantData::Struct(..) => Variant::Struct(self.clean(cx)), hir::VariantData::Tuple(..) => { @@ -1861,14 +1865,14 @@ impl Clean for hir::VariantData<'_> { } } -impl Clean for rustc_span::Span { - fn clean(&self, _cx: &mut DocContext<'_>) -> Span { +impl<'tcx> Clean<'tcx, Span> for rustc_span::Span { + fn clean(&self, _cx: &mut DocContext<'tcx>) -> Span { Span::from_rustc_span(*self) } } -impl Clean for hir::Path<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Path { +impl<'tcx> Clean<'tcx, Path> for hir::Path<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Path { Path { global: self.is_global(), res: self.res, @@ -1877,8 +1881,8 @@ impl Clean for hir::Path<'_> { } } -impl Clean for hir::GenericArgs<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> GenericArgs { +impl<'tcx> Clean<'tcx, GenericArgs> for hir::GenericArgs<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericArgs { if self.parenthesized { let output = self.bindings[0].ty().clean(cx); GenericArgs::Parenthesized { @@ -1905,28 +1909,28 @@ impl Clean for hir::GenericArgs<'_> { } } -impl Clean for hir::PathSegment<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> PathSegment { +impl<'tcx> Clean<'tcx, PathSegment> for hir::PathSegment<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> PathSegment { PathSegment { name: self.ident.name, args: self.args().clean(cx) } } } -impl Clean for Ident { +impl<'tcx> Clean<'tcx, String> for Ident { #[inline] - fn clean(&self, cx: &mut DocContext<'_>) -> String { + fn clean(&self, cx: &mut DocContext<'tcx>) -> String { self.name.clean(cx) } } -impl Clean for Symbol { +impl<'tcx> Clean<'tcx, String> for Symbol { #[inline] - fn clean(&self, _: &mut DocContext<'_>) -> String { + fn clean(&self, _: &mut DocContext<'tcx>) -> String { self.to_string() } } -impl Clean for hir::BareFnTy<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> BareFunctionDecl { +impl<'tcx> Clean<'tcx, BareFunctionDecl> for hir::BareFnTy<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> BareFunctionDecl { let (generic_params, decl) = enter_impl_trait(cx, |cx| { (self.generic_params.clean(cx), (&*self.decl, self.param_names).clean(cx)) }); @@ -1934,8 +1938,8 @@ impl Clean for hir::BareFnTy<'_> { } } -impl Clean> for (&hir::Item<'_>, Option) { - fn clean(&self, cx: &mut DocContext<'_>) -> Vec { +impl<'tcx> Clean<'tcx, Vec> for (&hir::Item<'tcx>, Option) { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Vec { use hir::ItemKind; let (item, renamed) = self; @@ -2018,8 +2022,8 @@ impl Clean> for (&hir::Item<'_>, Option) { } } -impl Clean for hir::Variant<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for hir::Variant<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let kind = VariantItem(self.data.clean(cx)); let what_rustc_thinks = Item::from_hir_id_and_parts(self.id, Some(self.ident.name), kind, cx); @@ -2028,9 +2032,9 @@ impl Clean for hir::Variant<'_> { } } -impl Clean for ty::ImplPolarity { +impl<'tcx> Clean<'tcx, bool> for ty::ImplPolarity { /// Returns whether the impl has negative polarity. - fn clean(&self, _: &mut DocContext<'_>) -> bool { + fn clean(&self, _: &mut DocContext<'tcx>) -> bool { match self { &ty::ImplPolarity::Positive | // FIXME: do we want to do something else here? @@ -2040,7 +2044,11 @@ impl Clean for ty::ImplPolarity { } } -fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_>) -> Vec { +fn clean_impl<'tcx>( + impl_: &hir::Impl<'tcx>, + hir_id: hir::HirId, + cx: &mut DocContext<'tcx>, +) -> Vec { let tcx = cx.tcx; let mut ret = Vec::new(); let trait_ = impl_.of_trait.clean(cx); @@ -2085,11 +2093,11 @@ fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_> ret } -fn clean_extern_crate( - krate: &hir::Item<'_>, +fn clean_extern_crate<'tcx>( + krate: &hir::Item<'tcx>, name: Symbol, orig_name: Option, - cx: &mut DocContext<'_>, + cx: &mut DocContext<'tcx>, ) -> Vec { // this is the ID of the `extern crate` statement let cnum = cx.tcx.extern_mod_stmt_cnum(krate.def_id).unwrap_or(LOCAL_CRATE); @@ -2132,12 +2140,12 @@ fn clean_extern_crate( }] } -fn clean_use_statement( - import: &hir::Item<'_>, +fn clean_use_statement<'tcx>( + import: &hir::Item<'tcx>, name: Symbol, - path: &hir::Path<'_>, + path: &hir::Path<'tcx>, kind: hir::UseKind, - cx: &mut DocContext<'_>, + cx: &mut DocContext<'tcx>, ) -> Vec { // We need this comparison because some imports (for std types for example) // are "inserted" as well but directly by the compiler and they should not be @@ -2227,8 +2235,8 @@ fn clean_use_statement( vec![Item::from_def_id_and_parts(import.def_id.to_def_id(), None, ImportItem(inner), cx)] } -impl Clean for (&hir::ForeignItem<'_>, Option) { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for (&hir::ForeignItem<'tcx>, Option) { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let (item, renamed) = self; cx.with_param_env(item.def_id.to_def_id(), |cx| { let kind = match item.kind { @@ -2264,8 +2272,8 @@ impl Clean for (&hir::ForeignItem<'_>, Option) { } } -impl Clean for (&hir::MacroDef<'_>, Option) { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { +impl<'tcx> Clean<'tcx, Item> for (&hir::MacroDef<'tcx>, Option) { + fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { let (item, renamed) = self; let name = renamed.unwrap_or(item.ident.name); let tts = item.ast.body.inner_tokens().trees().collect::>(); @@ -2313,14 +2321,14 @@ impl Clean for (&hir::MacroDef<'_>, Option) { } } -impl Clean for hir::TypeBinding<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> TypeBinding { +impl<'tcx> Clean<'tcx, TypeBinding> for hir::TypeBinding<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> TypeBinding { TypeBinding { name: self.ident.name, kind: self.kind.clean(cx) } } } -impl Clean for hir::TypeBindingKind<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> TypeBindingKind { +impl<'tcx> Clean<'tcx, TypeBindingKind> for hir::TypeBindingKind<'tcx> { + fn clean(&self, cx: &mut DocContext<'tcx>) -> TypeBindingKind { match *self { hir::TypeBindingKind::Equality { ref ty } => { TypeBindingKind::Equality { ty: ty.clean(cx) } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 32bac53e8f5..ce802902f5b 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -84,12 +84,12 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate { } } -fn external_generic_args( - cx: &mut DocContext<'_>, +fn external_generic_args<'tcx>( + cx: &mut DocContext<'tcx>, trait_did: Option, has_self: bool, bindings: Vec, - substs: SubstsRef<'_>, + substs: SubstsRef<'tcx>, ) -> GenericArgs { let mut skip_self = has_self; let mut ty_kind = None; @@ -136,13 +136,13 @@ fn external_generic_args( // trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar // from Fn<(A, B,), C> to Fn(A, B) -> C -pub(super) fn external_path( - cx: &mut DocContext<'_>, +pub(super) fn external_path<'tcx>( + cx: &mut DocContext<'tcx>, name: Symbol, trait_did: Option, has_self: bool, bindings: Vec, - substs: SubstsRef<'_>, + substs: SubstsRef<'tcx>, ) -> Path { Path { global: false, diff --git a/src/test/ui/hrtb/complex.rs b/src/test/ui/hrtb/complex.rs new file mode 100644 index 00000000000..0bcda8c01cd --- /dev/null +++ b/src/test/ui/hrtb/complex.rs @@ -0,0 +1,20 @@ +// check-pass + +trait A<'a> {} +trait B<'b> {} +fn foo() where for<'a> T: A<'a> + 'a {} +trait C<'c>: for<'a> A<'a> + for<'b> B<'b> { + type As; +} +struct D where T: for<'c> C<'c, As=&'c ()> { + t: std::marker::PhantomData, +} +trait E<'e> { + type As; +} +trait F<'f>: for<'a> A<'a> + for<'e> E<'e> {} +struct G where T: for<'f> F<'f, As=&'f ()> { + t: std::marker::PhantomData, +} + +fn main() {} diff --git a/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr b/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr index 92208231b17..fa59d7a0313 100644 --- a/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr +++ b/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr @@ -1,4 +1,4 @@ -error: cannot specialize on `Binder(ProjectionPredicate(ProjectionTy { substs: [V], item_def_id: DefId(0:6 ~ repeated_projection_type[317d]::Id::This) }, (I,)))` +error: cannot specialize on `Binder(ProjectionPredicate(ProjectionTy { substs: [V], item_def_id: DefId(0:6 ~ repeated_projection_type[317d]::Id::This) }, (I,)), [])` --> $DIR/repeated_projection_type.rs:19:1 | LL | / impl> X for V { diff --git a/src/test/ui/symbol-names/basic.legacy.stderr b/src/test/ui/symbol-names/basic.legacy.stderr index 7155d88be96..3dd2b19fbf9 100644 --- a/src/test/ui/symbol-names/basic.legacy.stderr +++ b/src/test/ui/symbol-names/basic.legacy.stderr @@ -1,10 +1,10 @@ -error: symbol-name(_ZN5basic4main17hfcf1daab33c43a6aE) +error: symbol-name(_ZN5basic4main17h6c535bbea2051f85E) --> $DIR/basic.rs:8:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(basic::main::hfcf1daab33c43a6a) +error: demangling(basic::main::h6c535bbea2051f85) --> $DIR/basic.rs:8:1 | LL | #[rustc_symbol_name] diff --git a/src/test/ui/symbol-names/impl1.legacy.stderr b/src/test/ui/symbol-names/impl1.legacy.stderr index bd32a39a65c..c9c2664e6de 100644 --- a/src/test/ui/symbol-names/impl1.legacy.stderr +++ b/src/test/ui/symbol-names/impl1.legacy.stderr @@ -1,71 +1,71 @@ -error: symbol-name(_ZN5impl13foo3Foo3bar17) - --> $DIR/impl1.rs:15:9 +error: symbol-name(_ZN5impl13foo3Foo3bar17h2e76f87b171019e0E) + --> $DIR/impl1.rs:16:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(impl1::foo::Foo::bar::) - --> $DIR/impl1.rs:15:9 +error: demangling(impl1::foo::Foo::bar::h2e76f87b171019e0) + --> $DIR/impl1.rs:16:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(impl1::foo::Foo::bar) - --> $DIR/impl1.rs:15:9 + --> $DIR/impl1.rs:16:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(foo::Foo::bar) - --> $DIR/impl1.rs:22:9 + --> $DIR/impl1.rs:23:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17) - --> $DIR/impl1.rs:33:9 +error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17hb388a171ee84bca1E) + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(impl1::bar::::baz::) - --> $DIR/impl1.rs:33:9 +error: demangling(impl1::bar::::baz::hb388a171ee84bca1) + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(impl1::bar::::baz) - --> $DIR/impl1.rs:33:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(bar::::baz) - --> $DIR/impl1.rs:40:9 + --> $DIR/impl1.rs:41:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17) - --> $DIR/impl1.rs:63:13 +error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17SYMBOL_HASH) + --> $DIR/impl1.rs:64:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method::) - --> $DIR/impl1.rs:63:13 +error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method::SYMBOL_HASH) + --> $DIR/impl1.rs:64:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method) - --> $DIR/impl1.rs:63:13 + --> $DIR/impl1.rs:64:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:70:13 + --> $DIR/impl1.rs:71:13 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index 771695330d8..0a865a602f6 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -3,7 +3,8 @@ // revisions: legacy v0 //[legacy]compile-flags: -Z symbol-mangling-version=legacy //[v0]compile-flags: -Z symbol-mangling-version=v0 -//[legacy]normalize-stderr-test: "h[\w]{16}E?\)" -> ")" +//[legacy]normalize-stderr-test: "method17h[\d\w]+" -> "method17SYMBOL_HASH" +//[legacy]normalize-stderr-test: "method::h[\d\w]+" -> "method::SYMBOL_HASH" #![feature(auto_traits, rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/symbol-names/impl1.v0.stderr b/src/test/ui/symbol-names/impl1.v0.stderr index 3a6610935d6..a68a74c8552 100644 --- a/src/test/ui/symbol-names/impl1.v0.stderr +++ b/src/test/ui/symbol-names/impl1.v0.stderr @@ -1,71 +1,71 @@ error: symbol-name(_RNvMNtCs21hi0yVfW1J_5impl13fooNtB2_3Foo3bar) - --> $DIR/impl1.rs:15:9 + --> $DIR/impl1.rs:16:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(::bar) - --> $DIR/impl1.rs:15:9 + --> $DIR/impl1.rs:16:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(::bar) - --> $DIR/impl1.rs:15:9 + --> $DIR/impl1.rs:16:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(foo::Foo::bar) - --> $DIR/impl1.rs:22:9 + --> $DIR/impl1.rs:23:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ error: symbol-name(_RNvMNtCs21hi0yVfW1J_5impl13barNtNtB4_3foo3Foo3baz) - --> $DIR/impl1.rs:33:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(::baz) - --> $DIR/impl1.rs:33:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(::baz) - --> $DIR/impl1.rs:33:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(bar::::baz) - --> $DIR/impl1.rs:40:9 + --> $DIR/impl1.rs:41:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ error: symbol-name(_RNvXNCNvCs21hi0yVfW1J_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hvEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) - --> $DIR/impl1.rs:63:13 + --> $DIR/impl1.rs:64:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(<[&dyn impl1[17891616a171812d]::Foo extern "C" fn(&'a u8, ...)> + impl1[17891616a171812d]::AutoTrait; 3: usize] as impl1[17891616a171812d]::main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:63:13 + --> $DIR/impl1.rs:64:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8, ...)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:63:13 + --> $DIR/impl1.rs:64:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:70:13 + --> $DIR/impl1.rs:71:13 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/symbol-names/issue-60925.legacy.stderr b/src/test/ui/symbol-names/issue-60925.legacy.stderr index 9575875f5a8..65cc62b4d1d 100644 --- a/src/test/ui/symbol-names/issue-60925.legacy.stderr +++ b/src/test/ui/symbol-names/issue-60925.legacy.stderr @@ -1,10 +1,10 @@ -error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17hb8ca3eb2682b1b51E) +error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h6244e5288326926aE) --> $DIR/issue-60925.rs:22:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(issue_60925::foo::Foo::foo::hb8ca3eb2682b1b51) +error: demangling(issue_60925::foo::Foo::foo::h6244e5288326926a) --> $DIR/issue-60925.rs:22:9 | LL | #[rustc_symbol_name] diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs index bad3e488bb6..4c13941f665 100644 --- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs +++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs @@ -44,7 +44,7 @@ fn get_trait_predicates_for_trait_id<'tcx>( for (pred, _) in generics.predicates { if_chain! { if let PredicateKind::Trait(poly_trait_pred, _) = pred.kind().skip_binder(); - let trait_pred = cx.tcx.erase_late_bound_regions(ty::Binder::bind(poly_trait_pred)); + let trait_pred = cx.tcx.erase_late_bound_regions(pred.kind().rebind(poly_trait_pred)); if let Some(trait_def_id) = trait_id; if trait_def_id == trait_pred.trait_ref.def_id; then { @@ -58,12 +58,12 @@ fn get_trait_predicates_for_trait_id<'tcx>( fn get_projection_pred<'tcx>( cx: &LateContext<'tcx>, generics: GenericPredicates<'tcx>, - pred: TraitPredicate<'tcx>, + trait_pred: TraitPredicate<'tcx>, ) -> Option> { generics.predicates.iter().find_map(|(proj_pred, _)| { - if let ty::PredicateKind::Projection(proj_pred) = proj_pred.kind().skip_binder() { - let projection_pred = cx.tcx.erase_late_bound_regions(ty::Binder::bind(proj_pred)); - if projection_pred.projection_ty.substs == pred.trait_ref.substs { + if let ty::PredicateKind::Projection(pred) = proj_pred.kind().skip_binder() { + let projection_pred = cx.tcx.erase_late_bound_regions(proj_pred.kind().rebind(pred)); + if projection_pred.projection_ty.substs == trait_pred.trait_ref.substs { return Some(projection_pred); } } From 84f82d348c1b9d9c20579ded7e2dd2981ed454b9 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 16 Dec 2020 19:14:21 -0500 Subject: [PATCH 248/370] Revert explicit lifetimes --- compiler/rustc_hir/src/hir.rs | 4 +- src/librustdoc/clean/mod.rs | 312 +++++++++++++++++----------------- src/librustdoc/clean/utils.rs | 12 +- 3 files changed, 160 insertions(+), 168 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4ff5c0a678e..03af81ae02a 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -314,12 +314,12 @@ pub struct GenericArgs<'hir> { pub parenthesized: bool, } -impl<'tcx> GenericArgs<'tcx> { +impl GenericArgs<'_> { pub const fn none() -> Self { Self { args: &[], bindings: &[], parenthesized: false } } - pub fn inputs(&self) -> &[Ty<'tcx>] { + pub fn inputs(&self) -> &[Ty<'_>] { if self.parenthesized { for arg in self.args { match arg { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index dac42058b1b..4d33a1e6961 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -48,42 +48,42 @@ crate use self::types::Type::*; crate use self::types::Visibility::{Inherited, Public}; crate use self::types::*; -crate trait Clean<'tcx, T> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> T; +crate trait Clean { + fn clean(&self, cx: &mut DocContext<'_>) -> T; } -impl<'tcx, T: Clean<'tcx, U>, U> Clean<'tcx, Vec> for [T] { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Vec { +impl, U> Clean> for [T] { + fn clean(&self, cx: &mut DocContext<'_>) -> Vec { self.iter().map(|x| x.clean(cx)).collect() } } -impl<'tcx, T: Clean<'tcx, U>, U, V: Idx> Clean<'tcx, IndexVec> for IndexVec { - fn clean(&self, cx: &mut DocContext<'tcx>) -> IndexVec { +impl, U, V: Idx> Clean> for IndexVec { + fn clean(&self, cx: &mut DocContext<'_>) -> IndexVec { self.iter().map(|x| x.clean(cx)).collect() } } -impl<'tcx, T: Clean<'tcx, U>, U> Clean<'tcx, U> for &T { - fn clean(&self, cx: &mut DocContext<'tcx>) -> U { +impl, U> Clean for &T { + fn clean(&self, cx: &mut DocContext<'_>) -> U { (**self).clean(cx) } } -impl<'tcx, T: Clean<'tcx, U>, U> Clean<'tcx, U> for Rc { - fn clean(&self, cx: &mut DocContext<'tcx>) -> U { +impl, U> Clean for Rc { + fn clean(&self, cx: &mut DocContext<'_>) -> U { (**self).clean(cx) } } -impl<'tcx, T: Clean<'tcx, U>, U> Clean<'tcx, Option> for Option { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Option { +impl, U> Clean> for Option { + fn clean(&self, cx: &mut DocContext<'_>) -> Option { self.as_ref().map(|v| v.clean(cx)) } } -impl<'tcx> Clean<'tcx, ExternalCrate> for CrateNum { - fn clean(&self, cx: &mut DocContext<'tcx>) -> ExternalCrate { +impl Clean for CrateNum { + fn clean(&self, cx: &mut DocContext<'_>) -> ExternalCrate { let tcx = cx.tcx; let root = DefId { krate: *self, index: CRATE_DEF_INDEX }; let krate_span = tcx.def_span(root); @@ -204,8 +204,8 @@ impl<'tcx> Clean<'tcx, ExternalCrate> for CrateNum { } } -impl<'tcx> Clean<'tcx, Item> for doctree::Module<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { +impl Clean for doctree::Module<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> Item { let mut items: Vec = vec![]; items.extend(self.foreigns.iter().map(|x| x.clean(cx))); items.extend(self.mods.iter().map(|x| x.clean(cx))); @@ -237,14 +237,14 @@ impl<'tcx> Clean<'tcx, Item> for doctree::Module<'tcx> { } } -impl<'tcx> Clean<'tcx, Attributes> for [ast::Attribute] { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Attributes { +impl Clean for [ast::Attribute] { + fn clean(&self, cx: &mut DocContext<'_>) -> Attributes { Attributes::from_ast(cx.sess().diagnostic(), self, None) } } -impl<'tcx> Clean<'tcx, GenericBound> for hir::GenericBound<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericBound { +impl Clean for hir::GenericBound<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound { match *self { hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)), hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => { @@ -270,8 +270,8 @@ impl<'tcx> Clean<'tcx, GenericBound> for hir::GenericBound<'tcx> { } } -impl<'tcx> Clean<'tcx, Type> for (ty::TraitRef<'tcx>, &[TypeBinding]) { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { +impl Clean for (ty::TraitRef<'_>, &[TypeBinding]) { + fn clean(&self, cx: &mut DocContext<'_>) -> Type { let (trait_ref, bounds) = *self; inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait); let path = external_path( @@ -289,8 +289,8 @@ impl<'tcx> Clean<'tcx, Type> for (ty::TraitRef<'tcx>, &[TypeBinding]) { } } -impl<'tcx> Clean<'tcx, GenericBound> for ty::TraitRef<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericBound { +impl<'tcx> Clean for ty::TraitRef<'tcx> { + fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound { GenericBound::TraitBound( PolyTrait { trait_: (*self, &[][..]).clean(cx), generic_params: vec![] }, hir::TraitBoundModifier::None, @@ -298,8 +298,8 @@ impl<'tcx> Clean<'tcx, GenericBound> for ty::TraitRef<'tcx> { } } -impl<'tcx> Clean<'tcx, GenericBound> for (ty::PolyTraitRef<'tcx>, &[TypeBinding]) { - fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericBound { +impl Clean for (ty::PolyTraitRef<'_>, &[TypeBinding]) { + fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound { let (poly_trait_ref, bounds) = *self; let poly_trait_ref = poly_trait_ref.lift_to_tcx(cx.tcx).unwrap(); @@ -326,14 +326,14 @@ impl<'tcx> Clean<'tcx, GenericBound> for (ty::PolyTraitRef<'tcx>, &[TypeBinding] } } -impl<'tcx> Clean<'tcx, GenericBound> for ty::PolyTraitRef<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericBound { +impl<'tcx> Clean for ty::PolyTraitRef<'tcx> { + fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound { (*self, &[][..]).clean(cx) } } -impl<'tcx> Clean<'tcx, Option>> for InternalSubsts<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Option> { +impl<'tcx> Clean>> for InternalSubsts<'tcx> { + fn clean(&self, cx: &mut DocContext<'_>) -> Option> { let mut v = Vec::new(); v.extend(self.regions().filter_map(|r| r.clean(cx)).map(GenericBound::Outlives)); v.extend(self.types().map(|t| { @@ -346,8 +346,8 @@ impl<'tcx> Clean<'tcx, Option>> for InternalSubsts<'tcx> { } } -impl<'tcx> Clean<'tcx, Lifetime> for hir::Lifetime { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Lifetime { +impl Clean for hir::Lifetime { + fn clean(&self, cx: &mut DocContext<'_>) -> Lifetime { let def = cx.tcx.named_region(self.hir_id); match def { Some( @@ -365,8 +365,8 @@ impl<'tcx> Clean<'tcx, Lifetime> for hir::Lifetime { } } -impl<'tcx> Clean<'tcx, Lifetime> for hir::GenericParam<'tcx> { - fn clean(&self, _: &mut DocContext<'tcx>) -> Lifetime { +impl Clean for hir::GenericParam<'_> { + fn clean(&self, _: &mut DocContext<'_>) -> Lifetime { match self.kind { hir::GenericParamKind::Lifetime { .. } => { if !self.bounds.is_empty() { @@ -389,8 +389,8 @@ impl<'tcx> Clean<'tcx, Lifetime> for hir::GenericParam<'tcx> { } } -impl<'tcx> Clean<'tcx, Constant> for hir::ConstArg { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Constant { +impl Clean for hir::ConstArg { + fn clean(&self, cx: &mut DocContext<'_>) -> Constant { Constant { type_: cx .tcx @@ -401,14 +401,14 @@ impl<'tcx> Clean<'tcx, Constant> for hir::ConstArg { } } -impl<'tcx> Clean<'tcx, Lifetime> for ty::GenericParamDef { - fn clean(&self, _cx: &mut DocContext<'tcx>) -> Lifetime { +impl Clean for ty::GenericParamDef { + fn clean(&self, _cx: &mut DocContext<'_>) -> Lifetime { Lifetime(self.name) } } -impl<'tcx> Clean<'tcx, Option> for ty::RegionKind { - fn clean(&self, _cx: &mut DocContext<'tcx>) -> Option { +impl Clean> for ty::RegionKind { + fn clean(&self, _cx: &mut DocContext<'_>) -> Option { match *self { ty::ReStatic => Some(Lifetime::statik()), ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name) }) => { @@ -429,8 +429,8 @@ impl<'tcx> Clean<'tcx, Option> for ty::RegionKind { } } -impl<'tcx> Clean<'tcx, WherePredicate> for hir::WherePredicate<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> WherePredicate { +impl Clean for hir::WherePredicate<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate { match *self { hir::WherePredicate::BoundPredicate(ref wbp) => WherePredicate::BoundPredicate { ty: wbp.bounded_ty.clean(cx), @@ -449,8 +449,8 @@ impl<'tcx> Clean<'tcx, WherePredicate> for hir::WherePredicate<'tcx> { } } -impl<'a> Clean<'a, Option> for ty::Predicate<'a> { - fn clean(&self, cx: &mut DocContext<'a>) -> Option { +impl<'a> Clean> for ty::Predicate<'a> { + fn clean(&self, cx: &mut DocContext<'_>) -> Option { let bound_predicate = self.kind(); match bound_predicate.skip_binder() { ty::PredicateKind::Trait(pred, _) => Some(bound_predicate.rebind(pred).clean(cx)), @@ -469,8 +469,8 @@ impl<'a> Clean<'a, Option> for ty::Predicate<'a> { } } -impl<'tcx> Clean<'tcx, WherePredicate> for ty::PolyTraitPredicate<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> WherePredicate { +impl<'a> Clean for ty::PolyTraitPredicate<'a> { + fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate { let poly_trait_ref = self.map_bound(|pred| pred.trait_ref); WherePredicate::BoundPredicate { ty: poly_trait_ref.skip_binder().self_ty().clean(cx), @@ -479,10 +479,10 @@ impl<'tcx> Clean<'tcx, WherePredicate> for ty::PolyTraitPredicate<'tcx> { } } -impl<'tcx> Clean<'tcx, Option> +impl<'tcx> Clean> for ty::OutlivesPredicate, ty::Region<'tcx>> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Option { + fn clean(&self, cx: &mut DocContext<'_>) -> Option { let ty::OutlivesPredicate(a, b) = self; if let (ty::ReEmpty(_), ty::ReEmpty(_)) = (a, b) { @@ -496,10 +496,8 @@ impl<'tcx> Clean<'tcx, Option> } } -impl<'tcx> Clean<'tcx, Option> - for ty::OutlivesPredicate, ty::Region<'tcx>> -{ - fn clean(&self, cx: &mut DocContext<'tcx>) -> Option { +impl<'tcx> Clean> for ty::OutlivesPredicate, ty::Region<'tcx>> { + fn clean(&self, cx: &mut DocContext<'_>) -> Option { let ty::OutlivesPredicate(ty, lt) = self; if let ty::ReEmpty(_) = lt { @@ -513,15 +511,15 @@ impl<'tcx> Clean<'tcx, Option> } } -impl<'tcx> Clean<'tcx, WherePredicate> for ty::ProjectionPredicate<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> WherePredicate { +impl<'tcx> Clean for ty::ProjectionPredicate<'tcx> { + fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate { let ty::ProjectionPredicate { projection_ty, ty } = self; WherePredicate::EqPredicate { lhs: projection_ty.clean(cx), rhs: ty.clean(cx) } } } -impl<'tcx> Clean<'tcx, Type> for ty::ProjectionTy<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { +impl<'tcx> Clean for ty::ProjectionTy<'tcx> { + fn clean(&self, cx: &mut DocContext<'_>) -> Type { let lifted = self.lift_to_tcx(cx.tcx).unwrap(); let trait_ = match lifted.trait_ref(cx.tcx).clean(cx) { GenericBound::TraitBound(t, _) => t.trait_, @@ -535,8 +533,8 @@ impl<'tcx> Clean<'tcx, Type> for ty::ProjectionTy<'tcx> { } } -impl<'tcx> Clean<'tcx, GenericParamDef> for ty::GenericParamDef { - fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericParamDef { +impl Clean for ty::GenericParamDef { + fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef { let (name, kind) = match self.kind { ty::GenericParamDefKind::Lifetime => (self.name, GenericParamDefKind::Lifetime), ty::GenericParamDefKind::Type { has_default, synthetic, .. } => { @@ -565,8 +563,8 @@ impl<'tcx> Clean<'tcx, GenericParamDef> for ty::GenericParamDef { } } -impl<'tcx> Clean<'tcx, GenericParamDef> for hir::GenericParam<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericParamDef { +impl Clean for hir::GenericParam<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef { let (name, kind) = match self.kind { hir::GenericParamKind::Lifetime { .. } => { let name = if !self.bounds.is_empty() { @@ -608,8 +606,8 @@ impl<'tcx> Clean<'tcx, GenericParamDef> for hir::GenericParam<'tcx> { } } -impl<'tcx> Clean<'tcx, Generics> for hir::Generics<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Generics { +impl Clean for hir::Generics<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> Generics { // Synthetic type-parameters are inserted after normal ones. // In order for normal parameters to be able to refer to synthetic ones, // scans them first. @@ -688,8 +686,8 @@ impl<'tcx> Clean<'tcx, Generics> for hir::Generics<'tcx> { } } -impl<'a, 'tcx> Clean<'tcx, Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx>) { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Generics { +impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx>) { + fn clean(&self, cx: &mut DocContext<'_>) -> Generics { use self::WherePredicate as WP; use std::collections::BTreeMap; @@ -853,13 +851,13 @@ impl<'a, 'tcx> Clean<'tcx, Generics> for (&'a ty::Generics, ty::GenericPredicate } } -fn clean_fn_or_proc_macro<'a, 'tcx>( - item: &hir::Item<'tcx>, - sig: &'a hir::FnSig<'tcx>, - generics: &'a hir::Generics<'tcx>, +fn clean_fn_or_proc_macro( + item: &hir::Item<'_>, + sig: &'a hir::FnSig<'a>, + generics: &'a hir::Generics<'a>, body_id: hir::BodyId, name: &mut Symbol, - cx: &mut DocContext<'tcx>, + cx: &mut DocContext<'_>, ) -> ItemKind { let attrs = cx.tcx.hir().attrs(item.hir_id()); let macro_kind = attrs.iter().find_map(|a| { @@ -913,18 +911,16 @@ fn clean_fn_or_proc_macro<'a, 'tcx>( } } -impl<'a, 'tcx> Clean<'tcx, Function> - for (&'a hir::FnSig<'tcx>, &'a hir::Generics<'tcx>, hir::BodyId) -{ - fn clean(&self, cx: &mut DocContext<'tcx>) -> Function { +impl<'a> Clean for (&'a hir::FnSig<'a>, &'a hir::Generics<'a>, hir::BodyId) { + fn clean(&self, cx: &mut DocContext<'_>) -> Function { let (generics, decl) = enter_impl_trait(cx, |cx| (self.1.clean(cx), (&*self.0.decl, self.2).clean(cx))); Function { decl, generics, header: self.0.header } } } -impl<'a, 'tcx> Clean<'tcx, Arguments> for (&'a [hir::Ty<'tcx>], &'a [Ident]) { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Arguments { +impl<'a> Clean for (&'a [hir::Ty<'a>], &'a [Ident]) { + fn clean(&self, cx: &mut DocContext<'_>) -> Arguments { Arguments { values: self .0 @@ -942,8 +938,8 @@ impl<'a, 'tcx> Clean<'tcx, Arguments> for (&'a [hir::Ty<'tcx>], &'a [Ident]) { } } -impl<'a, 'tcx> Clean<'tcx, Arguments> for (&'a [hir::Ty<'tcx>], hir::BodyId) { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Arguments { +impl<'a> Clean for (&'a [hir::Ty<'a>], hir::BodyId) { + fn clean(&self, cx: &mut DocContext<'_>) -> Arguments { let body = cx.tcx.hir().body(self.1); Arguments { @@ -952,7 +948,7 @@ impl<'a, 'tcx> Clean<'tcx, Arguments> for (&'a [hir::Ty<'tcx>], hir::BodyId) { .iter() .enumerate() .map(|(i, ty)| Argument { - name: Symbol::intern(&rustc_hir_pretty::param_to_string(&body.params[i])), + name: name_from_pat(&body.params[i].pat), type_: ty.clean(cx), }) .collect(), @@ -960,13 +956,13 @@ impl<'a, 'tcx> Clean<'tcx, Arguments> for (&'a [hir::Ty<'tcx>], hir::BodyId) { } } -impl<'a, 'tcx, A: Copy> Clean<'tcx, FnDecl> for (&'a hir::FnDecl<'tcx>, A) +impl<'a, A: Copy> Clean for (&'a hir::FnDecl<'a>, A) where - (&'a [hir::Ty<'a>], A): Clean<'tcx, Arguments>, + (&'a [hir::Ty<'a>], A): Clean, { - fn clean(&self, cx: &mut DocContext<'tcx>) -> FnDecl { + fn clean(&self, cx: &mut DocContext<'_>) -> FnDecl { FnDecl { - inputs: (&self.0.inputs[..], self.1).clean(cx), + inputs: (self.0.inputs, self.1).clean(cx), output: self.0.output.clean(cx), c_variadic: self.0.c_variadic, attrs: Attributes::default(), @@ -974,8 +970,8 @@ where } } -impl<'tcx> Clean<'tcx, FnDecl> for (DefId, ty::PolyFnSig<'tcx>) { - fn clean(&self, cx: &mut DocContext<'tcx>) -> FnDecl { +impl<'tcx> Clean for (DefId, ty::PolyFnSig<'tcx>) { + fn clean(&self, cx: &mut DocContext<'_>) -> FnDecl { let (did, sig) = *self; let mut names = if did.is_local() { &[] } else { cx.tcx.fn_arg_names(did) }.iter(); @@ -998,8 +994,8 @@ impl<'tcx> Clean<'tcx, FnDecl> for (DefId, ty::PolyFnSig<'tcx>) { } } -impl<'tcx> Clean<'tcx, FnRetTy> for hir::FnRetTy<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> FnRetTy { +impl Clean for hir::FnRetTy<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> FnRetTy { match *self { Self::Return(ref typ) => Return(typ.clean(cx)), Self::DefaultReturn(..) => DefaultReturn, @@ -1007,7 +1003,7 @@ impl<'tcx> Clean<'tcx, FnRetTy> for hir::FnRetTy<'tcx> { } } -impl Clean<'_, bool> for hir::IsAuto { +impl Clean for hir::IsAuto { fn clean(&self, _: &mut DocContext<'_>) -> bool { match *self { hir::IsAuto::Yes => true, @@ -1016,15 +1012,15 @@ impl Clean<'_, bool> for hir::IsAuto { } } -impl<'tcx> Clean<'tcx, Type> for hir::TraitRef<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { +impl Clean for hir::TraitRef<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> Type { let path = self.path.clean(cx); resolve_type(cx, path, self.hir_ref_id) } } -impl<'tcx> Clean<'tcx, PolyTrait> for hir::PolyTraitRef<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> PolyTrait { +impl Clean for hir::PolyTraitRef<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> PolyTrait { PolyTrait { trait_: self.trait_ref.clean(cx), generic_params: self.bound_generic_params.clean(cx), @@ -1032,14 +1028,14 @@ impl<'tcx> Clean<'tcx, PolyTrait> for hir::PolyTraitRef<'tcx> { } } -impl<'tcx> Clean<'tcx, TypeKind> for hir::def::DefKind { - fn clean(&self, _: &mut DocContext<'tcx>) -> TypeKind { +impl Clean for hir::def::DefKind { + fn clean(&self, _: &mut DocContext<'_>) -> TypeKind { (*self).into() } } -impl<'tcx> Clean<'tcx, Item> for hir::TraitItem<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { +impl Clean for hir::TraitItem<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> Item { let local_did = self.def_id.to_def_id(); cx.with_param_env(local_did, |cx| { let inner = match self.kind { @@ -1079,8 +1075,8 @@ impl<'tcx> Clean<'tcx, Item> for hir::TraitItem<'tcx> { } } -impl<'tcx> Clean<'tcx, Item> for hir::ImplItem<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { +impl Clean for hir::ImplItem<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> Item { let local_did = self.def_id.to_def_id(); cx.with_param_env(local_did, |cx| { let inner = match self.kind { @@ -1128,8 +1124,8 @@ impl<'tcx> Clean<'tcx, Item> for hir::ImplItem<'tcx> { } } -impl<'tcx> Clean<'tcx, Item> for ty::AssocItem { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { +impl Clean for ty::AssocItem { + fn clean(&self, cx: &mut DocContext<'_>) -> Item { let tcx = cx.tcx; let kind = match self.kind { ty::AssocKind::Const => { @@ -1280,7 +1276,7 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem { } } -fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type { +fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { use rustc_hir::GenericParamCount; let hir::Ty { hir_id, span, ref kind } = *hir_ty; let qpath = match kind { @@ -1432,8 +1428,8 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type } } -impl<'tcx> Clean<'tcx, Type> for hir::Ty<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { +impl Clean for hir::Ty<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> Type { use rustc_hir::*; match self.kind { @@ -1535,8 +1531,8 @@ fn normalize(cx: &mut DocContext<'tcx>, ty: Ty<'_>) -> Option> { } } -impl<'tcx> Clean<'tcx, Type> for Ty<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Type { +impl<'tcx> Clean for Ty<'tcx> { + fn clean(&self, cx: &mut DocContext<'_>) -> Type { debug!("cleaning type: {:?}", self); let ty = normalize(cx, self).unwrap_or(self); match *ty.kind() { @@ -1743,8 +1739,8 @@ impl<'tcx> Clean<'tcx, Type> for Ty<'tcx> { } } -impl<'tcx> Clean<'tcx, Constant> for ty::Const<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Constant { +impl<'tcx> Clean for ty::Const<'tcx> { + fn clean(&self, cx: &mut DocContext<'_>) -> Constant { // FIXME: instead of storing the stringified expression, store `self` directly instead. Constant { type_: self.ty.clean(cx), @@ -1753,8 +1749,8 @@ impl<'tcx> Clean<'tcx, Constant> for ty::Const<'tcx> { } } -impl<'tcx> Clean<'tcx, Item> for hir::FieldDef<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { +impl Clean for hir::FieldDef<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> Item { let what_rustc_thinks = Item::from_hir_id_and_parts( self.hir_id, Some(self.ident.name), @@ -1766,8 +1762,8 @@ impl<'tcx> Clean<'tcx, Item> for hir::FieldDef<'tcx> { } } -impl Clean<'tcx, Item> for ty::FieldDef { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { +impl Clean for ty::FieldDef { + fn clean(&self, cx: &mut DocContext<'_>) -> Item { let what_rustc_thinks = Item::from_def_id_and_parts( self.did, Some(self.ident.name), @@ -1779,8 +1775,8 @@ impl Clean<'tcx, Item> for ty::FieldDef { } } -impl<'tcx> Clean<'tcx, Visibility> for hir::Visibility<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Visibility { +impl Clean for hir::Visibility<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> Visibility { match self.node { hir::VisibilityKind::Public => Visibility::Public, hir::VisibilityKind::Inherited => Visibility::Inherited, @@ -1797,8 +1793,8 @@ impl<'tcx> Clean<'tcx, Visibility> for hir::Visibility<'tcx> { } } -impl<'tcx> Clean<'tcx, Visibility> for ty::Visibility { - fn clean(&self, _cx: &mut DocContext<'tcx>) -> Visibility { +impl Clean for ty::Visibility { + fn clean(&self, _cx: &mut DocContext<'_>) -> Visibility { match *self { ty::Visibility::Public => Visibility::Public, // NOTE: this is not quite right: `ty` uses `Invisible` to mean 'private', @@ -1812,8 +1808,8 @@ impl<'tcx> Clean<'tcx, Visibility> for ty::Visibility { } } -impl<'tcx> Clean<'tcx, VariantStruct> for rustc_hir::VariantData<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> VariantStruct { +impl Clean for rustc_hir::VariantData<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> VariantStruct { VariantStruct { struct_type: CtorKind::from_hir(self), fields: self.fields().iter().map(|x| x.clean(cx)).collect(), @@ -1822,8 +1818,8 @@ impl<'tcx> Clean<'tcx, VariantStruct> for rustc_hir::VariantData<'tcx> { } } -impl<'tcx> Clean<'tcx, Item> for ty::VariantDef { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { +impl Clean for ty::VariantDef { + fn clean(&self, cx: &mut DocContext<'_>) -> Item { let kind = match self.ctor_kind { CtorKind::Const => Variant::CLike, CtorKind::Fn => Variant::Tuple( @@ -1853,8 +1849,8 @@ impl<'tcx> Clean<'tcx, Item> for ty::VariantDef { } } -impl<'tcx> Clean<'tcx, Variant> for hir::VariantData<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Variant { +impl Clean for hir::VariantData<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> Variant { match self { hir::VariantData::Struct(..) => Variant::Struct(self.clean(cx)), hir::VariantData::Tuple(..) => { @@ -1865,14 +1861,14 @@ impl<'tcx> Clean<'tcx, Variant> for hir::VariantData<'tcx> { } } -impl<'tcx> Clean<'tcx, Span> for rustc_span::Span { - fn clean(&self, _cx: &mut DocContext<'tcx>) -> Span { +impl Clean for rustc_span::Span { + fn clean(&self, _cx: &mut DocContext<'_>) -> Span { Span::from_rustc_span(*self) } } -impl<'tcx> Clean<'tcx, Path> for hir::Path<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Path { +impl Clean for hir::Path<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> Path { Path { global: self.is_global(), res: self.res, @@ -1881,8 +1877,8 @@ impl<'tcx> Clean<'tcx, Path> for hir::Path<'tcx> { } } -impl<'tcx> Clean<'tcx, GenericArgs> for hir::GenericArgs<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericArgs { +impl Clean for hir::GenericArgs<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> GenericArgs { if self.parenthesized { let output = self.bindings[0].ty().clean(cx); GenericArgs::Parenthesized { @@ -1909,28 +1905,28 @@ impl<'tcx> Clean<'tcx, GenericArgs> for hir::GenericArgs<'tcx> { } } -impl<'tcx> Clean<'tcx, PathSegment> for hir::PathSegment<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> PathSegment { +impl Clean for hir::PathSegment<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> PathSegment { PathSegment { name: self.ident.name, args: self.args().clean(cx) } } } -impl<'tcx> Clean<'tcx, String> for Ident { +impl Clean for Ident { #[inline] - fn clean(&self, cx: &mut DocContext<'tcx>) -> String { + fn clean(&self, cx: &mut DocContext<'_>) -> String { self.name.clean(cx) } } -impl<'tcx> Clean<'tcx, String> for Symbol { +impl Clean for Symbol { #[inline] - fn clean(&self, _: &mut DocContext<'tcx>) -> String { + fn clean(&self, _: &mut DocContext<'_>) -> String { self.to_string() } } -impl<'tcx> Clean<'tcx, BareFunctionDecl> for hir::BareFnTy<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> BareFunctionDecl { +impl Clean for hir::BareFnTy<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> BareFunctionDecl { let (generic_params, decl) = enter_impl_trait(cx, |cx| { (self.generic_params.clean(cx), (&*self.decl, self.param_names).clean(cx)) }); @@ -1938,8 +1934,8 @@ impl<'tcx> Clean<'tcx, BareFunctionDecl> for hir::BareFnTy<'tcx> { } } -impl<'tcx> Clean<'tcx, Vec> for (&hir::Item<'tcx>, Option) { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Vec { +impl Clean> for (&hir::Item<'_>, Option) { + fn clean(&self, cx: &mut DocContext<'_>) -> Vec { use hir::ItemKind; let (item, renamed) = self; @@ -2022,8 +2018,8 @@ impl<'tcx> Clean<'tcx, Vec> for (&hir::Item<'tcx>, Option) { } } -impl<'tcx> Clean<'tcx, Item> for hir::Variant<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { +impl Clean for hir::Variant<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> Item { let kind = VariantItem(self.data.clean(cx)); let what_rustc_thinks = Item::from_hir_id_and_parts(self.id, Some(self.ident.name), kind, cx); @@ -2032,9 +2028,9 @@ impl<'tcx> Clean<'tcx, Item> for hir::Variant<'tcx> { } } -impl<'tcx> Clean<'tcx, bool> for ty::ImplPolarity { +impl Clean for ty::ImplPolarity { /// Returns whether the impl has negative polarity. - fn clean(&self, _: &mut DocContext<'tcx>) -> bool { + fn clean(&self, _: &mut DocContext<'_>) -> bool { match self { &ty::ImplPolarity::Positive | // FIXME: do we want to do something else here? @@ -2044,11 +2040,7 @@ impl<'tcx> Clean<'tcx, bool> for ty::ImplPolarity { } } -fn clean_impl<'tcx>( - impl_: &hir::Impl<'tcx>, - hir_id: hir::HirId, - cx: &mut DocContext<'tcx>, -) -> Vec { +fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_>) -> Vec { let tcx = cx.tcx; let mut ret = Vec::new(); let trait_ = impl_.of_trait.clean(cx); @@ -2093,11 +2085,11 @@ fn clean_impl<'tcx>( ret } -fn clean_extern_crate<'tcx>( - krate: &hir::Item<'tcx>, +fn clean_extern_crate( + krate: &hir::Item<'_>, name: Symbol, orig_name: Option, - cx: &mut DocContext<'tcx>, + cx: &mut DocContext<'_>, ) -> Vec { // this is the ID of the `extern crate` statement let cnum = cx.tcx.extern_mod_stmt_cnum(krate.def_id).unwrap_or(LOCAL_CRATE); @@ -2140,12 +2132,12 @@ fn clean_extern_crate<'tcx>( }] } -fn clean_use_statement<'tcx>( - import: &hir::Item<'tcx>, +fn clean_use_statement( + import: &hir::Item<'_>, name: Symbol, - path: &hir::Path<'tcx>, + path: &hir::Path<'_>, kind: hir::UseKind, - cx: &mut DocContext<'tcx>, + cx: &mut DocContext<'_>, ) -> Vec { // We need this comparison because some imports (for std types for example) // are "inserted" as well but directly by the compiler and they should not be @@ -2235,8 +2227,8 @@ fn clean_use_statement<'tcx>( vec![Item::from_def_id_and_parts(import.def_id.to_def_id(), None, ImportItem(inner), cx)] } -impl<'tcx> Clean<'tcx, Item> for (&hir::ForeignItem<'tcx>, Option) { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { +impl Clean for (&hir::ForeignItem<'_>, Option) { + fn clean(&self, cx: &mut DocContext<'_>) -> Item { let (item, renamed) = self; cx.with_param_env(item.def_id.to_def_id(), |cx| { let kind = match item.kind { @@ -2272,8 +2264,8 @@ impl<'tcx> Clean<'tcx, Item> for (&hir::ForeignItem<'tcx>, Option) { } } -impl<'tcx> Clean<'tcx, Item> for (&hir::MacroDef<'tcx>, Option) { - fn clean(&self, cx: &mut DocContext<'tcx>) -> Item { +impl Clean for (&hir::MacroDef<'_>, Option) { + fn clean(&self, cx: &mut DocContext<'_>) -> Item { let (item, renamed) = self; let name = renamed.unwrap_or(item.ident.name); let tts = item.ast.body.inner_tokens().trees().collect::>(); @@ -2321,14 +2313,14 @@ impl<'tcx> Clean<'tcx, Item> for (&hir::MacroDef<'tcx>, Option) { } } -impl<'tcx> Clean<'tcx, TypeBinding> for hir::TypeBinding<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> TypeBinding { +impl Clean for hir::TypeBinding<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> TypeBinding { TypeBinding { name: self.ident.name, kind: self.kind.clean(cx) } } } -impl<'tcx> Clean<'tcx, TypeBindingKind> for hir::TypeBindingKind<'tcx> { - fn clean(&self, cx: &mut DocContext<'tcx>) -> TypeBindingKind { +impl Clean for hir::TypeBindingKind<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> TypeBindingKind { match *self { hir::TypeBindingKind::Equality { ref ty } => { TypeBindingKind::Equality { ty: ty.clean(cx) } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index ce802902f5b..32bac53e8f5 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -84,12 +84,12 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate { } } -fn external_generic_args<'tcx>( - cx: &mut DocContext<'tcx>, +fn external_generic_args( + cx: &mut DocContext<'_>, trait_did: Option, has_self: bool, bindings: Vec, - substs: SubstsRef<'tcx>, + substs: SubstsRef<'_>, ) -> GenericArgs { let mut skip_self = has_self; let mut ty_kind = None; @@ -136,13 +136,13 @@ fn external_generic_args<'tcx>( // trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar // from Fn<(A, B,), C> to Fn(A, B) -> C -pub(super) fn external_path<'tcx>( - cx: &mut DocContext<'tcx>, +pub(super) fn external_path( + cx: &mut DocContext<'_>, name: Symbol, trait_did: Option, has_self: bool, bindings: Vec, - substs: SubstsRef<'tcx>, + substs: SubstsRef<'_>, ) -> Path { Path { global: false, From 666859a6f85a9ddad1e29de2daa4b8eef190c062 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Sun, 15 Nov 2020 17:06:58 -0500 Subject: [PATCH 249/370] Make late and late_anon regions track the bound var position --- .../nice_region_error/find_anon_type.rs | 19 +-- .../src/middle/resolve_lifetime.rs | 9 +- compiler/rustc_resolve/src/late/lifetimes.rs | 114 ++++++++++++------ compiler/rustc_typeck/src/astconv/mod.rs | 6 +- compiler/rustc_typeck/src/collect.rs | 3 +- src/librustdoc/clean/mod.rs | 2 +- 6 files changed, 99 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs index 35b9bc96f13..58eb1e9aa12 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -115,7 +115,7 @@ impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { // error. We will then search the function parameters for a bound // region at the right depth with the same index ( - Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)), + Some(rl::Region::LateBoundAnon(debruijn_index, _, anon_index)), ty::BrAnon(br_index), ) => { debug!( @@ -143,7 +143,7 @@ impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { // error. We will then search the function parameters for a bound // region at the right depth with the same index ( - Some(rl::Region::LateBound(debruijn_index, id, _)), + Some(rl::Region::LateBound(debruijn_index, _, id, _)), ty::BrNamed(def_id, _), ) => { debug!( @@ -162,8 +162,8 @@ impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { rl::Region::Static | rl::Region::Free(_, _) | rl::Region::EarlyBound(_, _, _) - | rl::Region::LateBound(_, _, _) - | rl::Region::LateBoundAnon(_, _), + | rl::Region::LateBound(_, _, _, _) + | rl::Region::LateBoundAnon(_, _, _), ) | None, _, @@ -217,7 +217,10 @@ impl Visitor<'tcx> for TyPathVisitor<'tcx> { fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) { match (self.tcx.named_region(lifetime.hir_id), self.bound_region) { // the lifetime of the TyPath! - (Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)), ty::BrAnon(br_index)) => { + ( + Some(rl::Region::LateBoundAnon(debruijn_index, _, anon_index)), + ty::BrAnon(br_index), + ) => { if debruijn_index == self.current_index && anon_index == br_index { self.found_it = true; return; @@ -232,7 +235,7 @@ impl Visitor<'tcx> for TyPathVisitor<'tcx> { } } - (Some(rl::Region::LateBound(debruijn_index, id, _)), ty::BrNamed(def_id, _)) => { + (Some(rl::Region::LateBound(debruijn_index, _, id, _)), ty::BrNamed(def_id, _)) => { debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", debruijn_index,); debug!("id={:?}", id); debug!("def_id={:?}", def_id); @@ -246,8 +249,8 @@ impl Visitor<'tcx> for TyPathVisitor<'tcx> { Some( rl::Region::Static | rl::Region::EarlyBound(_, _, _) - | rl::Region::LateBound(_, _, _) - | rl::Region::LateBoundAnon(_, _) + | rl::Region::LateBound(_, _, _, _) + | rl::Region::LateBoundAnon(_, _, _) | rl::Region::Free(_, _), ) | None, diff --git a/compiler/rustc_middle/src/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs index 32615f6c410..98802721954 100644 --- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs +++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs @@ -39,8 +39,13 @@ impl LifetimeDefOrigin { pub enum Region { Static, EarlyBound(/* index */ u32, /* lifetime decl */ DefId, LifetimeDefOrigin), - LateBound(ty::DebruijnIndex, /* lifetime decl */ DefId, LifetimeDefOrigin), - LateBoundAnon(ty::DebruijnIndex, /* anon index */ u32), + LateBound( + ty::DebruijnIndex, + /* late-bound index */ u32, + /* lifetime decl */ DefId, + LifetimeDefOrigin, + ), + LateBoundAnon(ty::DebruijnIndex, /* late-bound index */ u32, /* anon index */ u32), Free(DefId, /* lifetime decl */ DefId), } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 698e5048f7b..8e0309225de 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -42,9 +42,9 @@ pub enum LifetimeUseSet<'tcx> { trait RegionExt { fn early(hir_map: &Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (ParamName, Region); - fn late(hir_map: &Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region); + fn late(index: u32, hir_map: &Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region); - fn late_anon(index: &Cell) -> Region; + fn late_anon(named_late_bound_vars: u32, anon_index: &Cell) -> Region; fn id(&self) -> Option; @@ -67,7 +67,7 @@ impl RegionExt for Region { (param.name.normalize_to_macros_2_0(), Region::EarlyBound(i, def_id.to_def_id(), origin)) } - fn late(hir_map: &Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region) { + fn late(idx: u32, hir_map: &Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region) { let depth = ty::INNERMOST; let def_id = hir_map.local_def_id(param.hir_id); let origin = LifetimeDefOrigin::from_param(param); @@ -75,21 +75,24 @@ impl RegionExt for Region { "Region::late: param={:?} depth={:?} def_id={:?} origin={:?}", param, depth, def_id, origin, ); - (param.name.normalize_to_macros_2_0(), Region::LateBound(depth, def_id.to_def_id(), origin)) + ( + param.name.normalize_to_macros_2_0(), + Region::LateBound(depth, idx, def_id.to_def_id(), origin), + ) } - fn late_anon(index: &Cell) -> Region { + fn late_anon(named_late_bound_vars: u32, index: &Cell) -> Region { let i = index.get(); index.set(i + 1); let depth = ty::INNERMOST; - Region::LateBoundAnon(depth, i) + Region::LateBoundAnon(depth, named_late_bound_vars + i, i) } fn id(&self) -> Option { match *self { Region::Static | Region::LateBoundAnon(..) => None, - Region::EarlyBound(_, id, _) | Region::LateBound(_, id, _) | Region::Free(_, id) => { + Region::EarlyBound(_, id, _) | Region::LateBound(_, _, id, _) | Region::Free(_, id) => { Some(id) } } @@ -97,11 +100,11 @@ impl RegionExt for Region { fn shifted(self, amount: u32) -> Region { match self { - Region::LateBound(debruijn, id, origin) => { - Region::LateBound(debruijn.shifted_in(amount), id, origin) + Region::LateBound(debruijn, idx, id, origin) => { + Region::LateBound(debruijn.shifted_in(amount), idx, id, origin) } - Region::LateBoundAnon(debruijn, index) => { - Region::LateBoundAnon(debruijn.shifted_in(amount), index) + Region::LateBoundAnon(debruijn, index, anon_index) => { + Region::LateBoundAnon(debruijn.shifted_in(amount), index, anon_index) } _ => self, } @@ -109,11 +112,11 @@ impl RegionExt for Region { fn shifted_out_to_binder(self, binder: ty::DebruijnIndex) -> Region { match self { - Region::LateBound(debruijn, id, origin) => { - Region::LateBound(debruijn.shifted_out_to_binder(binder), id, origin) + Region::LateBound(debruijn, index, id, origin) => { + Region::LateBound(debruijn.shifted_out_to_binder(binder), index, id, origin) } - Region::LateBoundAnon(debruijn, index) => { - Region::LateBoundAnon(debruijn.shifted_out_to_binder(binder), index) + Region::LateBoundAnon(debruijn, index, anon_index) => { + Region::LateBoundAnon(debruijn.shifted_out_to_binder(binder), index, anon_index) } _ => self, } @@ -225,6 +228,8 @@ enum Scope<'a> { /// of the resulting opaque type. opaque_type_parent: bool, + named_late_bound_vars: u32, + s: ScopeRef<'a>, }, @@ -266,6 +271,7 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { next_early_index, track_lifetime_uses, opaque_type_parent, + named_late_bound_vars, s: _, } => f .debug_struct("Binder") @@ -273,6 +279,7 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { .field("next_early_index", next_early_index) .field("track_lifetime_uses", track_lifetime_uses) .field("opaque_type_parent", opaque_type_parent) + .field("named_late_bound_vars", named_late_bound_vars) .field("s", &"..") .finish(), Scope::Body { id, s: _ } => { @@ -294,8 +301,9 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { #[derive(Clone, Debug)] enum Elide { /// Use a fresh anonymous late-bound lifetime each time, by - /// incrementing the counter to generate sequential indices. - FreshLateAnon(Cell), + /// incrementing the counter to generate sequential indices. All + /// anonymous lifetimes must start *after* named bound vars. + FreshLateAnon(u32, Cell), /// Always use this one lifetime. Exact(Region), /// Less or more than one lifetime were found, error on unspecified. @@ -626,6 +634,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index: index + non_lifetime_count, opaque_type_parent: true, track_lifetime_uses, + named_late_bound_vars: 0, s: ROOT_SCOPE, }; self.with(scope, |old_scope, this| { @@ -676,9 +685,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { lifetimes: c .generic_params .iter() - .filter_map(|param| match param.kind { + .enumerate() + .filter_map(|(idx, param)| match param.kind { GenericParamKind::Lifetime { .. } => { - Some(Region::late(&self.tcx.hir(), param)) + Some(Region::late(idx as u32, &self.tcx.hir(), param)) } _ => None, }) @@ -687,6 +697,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index, track_lifetime_uses: true, opaque_type_parent: false, + named_late_bound_vars: c.generic_params.len() as u32, }; self.with(scope, |old_scope, this| { // a bare fn has no bounds, so everything @@ -721,7 +732,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // resolved the same as the `'_` in `&'_ Foo`. // // cc #48468 - self.resolve_elided_lifetimes(vec![lifetime]) + self.resolve_elided_lifetimes(&[lifetime]) } LifetimeName::Param(_) | LifetimeName::Static => { // If the user wrote an explicit name, use that. @@ -784,7 +795,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // well-supported at the moment, so this doesn't work. // In the future, this should be fixed and this error should be removed. let def = self.map.defs.get(&lifetime.hir_id).cloned(); - if let Some(Region::LateBound(_, def_id, _)) = def { + if let Some(Region::LateBound(_, _, def_id, _)) = def { if let Some(def_id) = def_id.as_local() { let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); // Ensure that the parent of the def is an item, not HRTB @@ -874,6 +885,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: this.scope, track_lifetime_uses: true, opaque_type_parent: false, + named_late_bound_vars: 0, }; this.with(scope, |_old_scope, this| { this.visit_generics(generics); @@ -889,6 +901,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: self.scope, track_lifetime_uses: true, opaque_type_parent: false, + named_late_bound_vars: 0, }; self.with(scope, |_old_scope, this| { this.visit_generics(generics); @@ -941,6 +954,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: self.scope, track_lifetime_uses: true, opaque_type_parent: true, + named_late_bound_vars: 0, }; self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &generics.params); @@ -1003,6 +1017,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: self.scope, track_lifetime_uses: true, opaque_type_parent: true, + named_late_bound_vars: 0, }; self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &generics.params); @@ -1024,7 +1039,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { #[tracing::instrument(level = "debug", skip(self))] fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { if lifetime_ref.is_elided() { - self.resolve_elided_lifetimes(vec![lifetime_ref]); + self.resolve_elided_lifetimes(&[lifetime_ref]); return; } if lifetime_ref.is_static() { @@ -1087,9 +1102,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }) => { let lifetimes: FxHashMap<_, _> = bound_generic_params .iter() - .filter_map(|param| match param.kind { + .enumerate() + .filter_map(|(idx, param)| match param.kind { GenericParamKind::Lifetime { .. } => { - Some(Region::late(&self.tcx.hir(), param)) + Some(Region::late(idx as u32, &self.tcx.hir(), param)) } _ => None, }) @@ -1102,6 +1118,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index, track_lifetime_uses: true, opaque_type_parent: false, + named_late_bound_vars: bound_generic_params.len() as u32, }; let result = self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &bound_generic_params); @@ -1145,6 +1162,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index: self.next_early_index(), track_lifetime_uses: true, opaque_type_parent: false, + named_late_bound_vars: 0, }; self.with(scope, |_, this| { intravisit::walk_param_bound(this, bound); @@ -1184,9 +1202,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { lifetimes: trait_ref .bound_generic_params .iter() - .filter_map(|param| match param.kind { + .enumerate() + .filter_map(|(idx, param)| match param.kind { GenericParamKind::Lifetime { .. } => { - Some(Region::late(&self.tcx.hir(), param)) + Some(Region::late(idx as u32, &self.tcx.hir(), param)) } _ => None, }) @@ -1195,6 +1214,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index, track_lifetime_uses: true, opaque_type_parent: false, + named_late_bound_vars: trait_ref.bound_generic_params.len() as u32, }; self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params); @@ -1715,7 +1735,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .values() .flat_map(|region| match region { Region::EarlyBound(_, def_id, _) - | Region::LateBound(_, def_id, _) + | Region::LateBound(_, _, def_id, _) | Region::Free(_, def_id) => Some(*def_id), Region::LateBoundAnon(..) | Region::Static => None, @@ -1886,13 +1906,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } let mut non_lifetime_count = 0; + let mut named_late_bound_vars = 0; let lifetimes = generics .params .iter() - .filter_map(|param| match param.kind { + .enumerate() + .filter_map(|(idx, param)| match param.kind { GenericParamKind::Lifetime { .. } => { if self.map.late_bound.contains(¶m.hir_id) { - Some(Region::late(&self.tcx.hir(), param)) + named_late_bound_vars += 1; + Some(Region::late(idx as u32, &self.tcx.hir(), param)) } else { Some(Region::early(&self.tcx.hir(), &mut index, param)) } @@ -1911,6 +1934,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { s: self.scope, opaque_type_parent: true, track_lifetime_uses: false, + named_late_bound_vars, }; self.with(scope, move |old_scope, this| { this.check_lifetime_params(old_scope, &generics.params); @@ -2025,7 +2049,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { if !self.trait_definition_only && self.is_in_fn_syntax { match def { Region::EarlyBound(_, _, LifetimeDefOrigin::InBand) - | Region::LateBound(_, _, LifetimeDefOrigin::InBand) => { + | Region::LateBound(_, _, _, LifetimeDefOrigin::InBand) => { struct_span_err!( self.tcx.sess, lifetime_ref.span, @@ -2044,6 +2068,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { LifetimeDefOrigin::ExplicitOrElided | LifetimeDefOrigin::Error, ) | Region::LateBound( + _, _, _, LifetimeDefOrigin::ExplicitOrElided | LifetimeDefOrigin::Error, @@ -2079,7 +2104,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } let mut elide_lifetimes = true; - let lifetimes = generic_args + let lifetimes: Vec<_> = generic_args .args .iter() .filter_map(|arg| match arg { @@ -2093,7 +2118,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { }) .collect(); if elide_lifetimes { - self.resolve_elided_lifetimes(lifetimes); + self.resolve_elided_lifetimes(&lifetimes); } else { lifetimes.iter().for_each(|lt| self.visit_lifetime(lt)); } @@ -2261,7 +2286,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { inputs: &'tcx [hir::Ty<'tcx>], output: Option<&'tcx hir::Ty<'tcx>>, ) { - let arg_scope = Scope::Elision { elide: Elide::FreshLateAnon(Cell::new(0)), s: self.scope }; + debug!("visit_fn_like_elision: enter"); + let named_late_bound_vars = match *self.scope { + Scope::Binder { named_late_bound_vars, .. } => named_late_bound_vars, + Scope::Body { .. } => 0, + _ => bug!("{:?}", self.scope), + }; + let arg_scope = Scope::Elision { + elide: Elide::FreshLateAnon(named_late_bound_vars, Cell::new(0)), + s: self.scope, + }; self.with(arg_scope, |_, this| { for input in inputs { this.visit_ty(input); @@ -2516,7 +2550,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) { if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.hir_id) { match lifetime { - Region::LateBound(debruijn, _, _) | Region::LateBoundAnon(debruijn, _) + Region::LateBound(debruijn, _, _, _) + | Region::LateBoundAnon(debruijn, _, _) if debruijn < self.outer_index => { self.have_bound_regions = true; @@ -2530,7 +2565,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } - fn resolve_elided_lifetimes(&mut self, lifetime_refs: Vec<&'tcx hir::Lifetime>) { + fn resolve_elided_lifetimes(&mut self, lifetime_refs: &[&'tcx hir::Lifetime]) { debug!("resolve_elided_lifetimes(lifetime_refs={:?})", lifetime_refs); if lifetime_refs.is_empty() { @@ -2563,9 +2598,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Elision { ref elide, ref s, .. } => { let lifetime = match *elide { - Elide::FreshLateAnon(ref counter) => { + Elide::FreshLateAnon(named_late_bound_vars, ref counter) => { for lifetime_ref in lifetime_refs { - let lifetime = Region::late_anon(counter).shifted(late_depth); + let lifetime = Region::late_anon(named_late_bound_vars, counter) + .shifted(late_depth); self.insert_lifetime(lifetime_ref, lifetime); } return; @@ -2890,7 +2926,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // A lifetime only used in a fn argument could as well // be replaced with `'_`, as that would generate a // fresh name, too. - Scope::Elision { elide: Elide::FreshLateAnon(_), .. } => break true, + Scope::Elision { elide: Elide::FreshLateAnon(_, _), .. } => break true, // In the return type or other such place, `'_` is not // going to make a fresh name, so we cannot @@ -2919,7 +2955,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } Region::Free(_, def_id) - | Region::LateBound(_, def_id, _) + | Region::LateBound(_, _, def_id, _) | Region::EarlyBound(_, def_id, _) => { // A lifetime declared by the user. let track_lifetime_uses = self.track_lifetime_uses(); diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 48f2bf1518b..711466e774d 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -210,14 +210,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let r = match tcx.named_region(lifetime.hir_id) { Some(rl::Region::Static) => tcx.lifetimes.re_static, - Some(rl::Region::LateBound(debruijn, id, _)) => { + Some(rl::Region::LateBound(debruijn, _, id, _)) => { let name = lifetime_name(id.expect_local()); let br = ty::BoundRegion { kind: ty::BrNamed(id, name) }; tcx.mk_region(ty::ReLateBound(debruijn, br)) } - Some(rl::Region::LateBoundAnon(debruijn, index)) => { - let br = ty::BoundRegion { kind: ty::BrAnon(index) }; + Some(rl::Region::LateBoundAnon(debruijn, _index, anon_index)) => { + let br = ty::BoundRegion { kind: ty::BrAnon(anon_index) }; tcx.mk_region(ty::ReLateBound(debruijn, br)) } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index b42ef7efcbc..ed4c0f8b828 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1244,7 +1244,8 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option {} Some( - rl::Region::LateBound(debruijn, _, _) | rl::Region::LateBoundAnon(debruijn, _), + rl::Region::LateBound(debruijn, _, _, _) + | rl::Region::LateBoundAnon(debruijn, _, _), ) if debruijn < self.outer_index => {} Some( rl::Region::LateBound(..) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4d33a1e6961..58869296d09 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -352,7 +352,7 @@ impl Clean for hir::Lifetime { match def { Some( rl::Region::EarlyBound(_, node_id, _) - | rl::Region::LateBound(_, node_id, _) + | rl::Region::LateBound(_, _, node_id, _) | rl::Region::Free(_, node_id), ) => { if let Some(lt) = cx.lt_substs.get(&node_id).cloned() { From 6d5efa9f040d2638318f9e8b96eab718ef664e3c Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Mon, 26 Oct 2020 14:18:31 -0400 Subject: [PATCH 250/370] Add var to BoundRegion. Add query to get bound vars for applicable items. --- compiler/rustc_hir/src/hir.rs | 6 +- .../src/infer/canonical/canonicalizer.rs | 2 +- .../src/infer/canonical/query_response.rs | 2 +- .../src/infer/canonical/substitute.rs | 9 +- compiler/rustc_middle/src/ich/impls_ty.rs | 6 +- compiler/rustc_middle/src/infer/canonical.rs | 3 +- .../src/middle/resolve_lifetime.rs | 2 + compiler/rustc_middle/src/query/mod.rs | 4 + compiler/rustc_middle/src/ty/context.rs | 13 +- compiler/rustc_middle/src/ty/fold.rs | 165 ++++- compiler/rustc_middle/src/ty/layout.rs | 52 +- compiler/rustc_middle/src/ty/mod.rs | 31 +- compiler/rustc_middle/src/ty/print/pretty.rs | 9 +- compiler/rustc_middle/src/ty/sty.rs | 71 +- compiler/rustc_middle/src/ty/util.rs | 8 +- .../src/borrow_check/diagnostics/mod.rs | 4 +- .../src/borrow_check/universal_regions.rs | 40 +- compiler/rustc_mir_build/src/build/mod.rs | 9 +- compiler/rustc_resolve/src/late.rs | 1 + compiler/rustc_resolve/src/late/lifetimes.rs | 661 +++++++++++++++--- .../rustc_resolve/src/late/supertraits.rs | 60 ++ compiler/rustc_symbol_mangling/src/v0.rs | 2 +- compiler/rustc_traits/src/chalk/db.rs | 5 +- compiler/rustc_traits/src/chalk/lowering.rs | 33 +- compiler/rustc_typeck/src/astconv/generics.rs | 2 +- compiler/rustc_typeck/src/astconv/mod.rs | 234 ++++--- compiler/rustc_typeck/src/check/closure.rs | 33 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 2 +- .../src/check/generator_interior.rs | 13 +- compiler/rustc_typeck/src/check/intrinsic.rs | 21 +- .../rustc_typeck/src/check/method/confirm.rs | 2 +- compiler/rustc_typeck/src/check/mod.rs | 1 + compiler/rustc_typeck/src/collect.rs | 26 +- compiler/rustc_typeck/src/lib.rs | 4 +- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/clean/utils.rs | 2 +- .../incremental/hashes/function_interfaces.rs | 6 +- src/test/incremental/hashes/inherent_impls.rs | 6 +- src/test/ui/associated-type-bounds/hrtb.rs | 65 ++ src/test/ui/hrtb/complex.rs | 12 +- .../escape-argument-callee.stderr | 2 +- .../escape-argument.stderr | 2 +- ...pagate-approximated-fail-no-postdom.stderr | 2 +- .../propagate-approximated-ref.stderr | 2 +- ...er-to-static-comparing-against-free.stderr | 4 +- ...oximated-shorter-to-static-no-bound.stderr | 2 +- ...mated-shorter-to-static-wrong-bound.stderr | 2 +- .../propagate-approximated-val.stderr | 2 +- .../propagate-despite-same-free-region.stderr | 2 +- ...ail-to-approximate-longer-no-bounds.stderr | 2 +- ...-to-approximate-longer-wrong-bounds.stderr | 2 +- .../return-wrong-bound-region.stderr | 2 +- ...ram-closure-approximate-lower-bound.stderr | 4 +- 53 files changed, 1274 insertions(+), 385 deletions(-) create mode 100644 compiler/rustc_resolve/src/late/supertraits.rs create mode 100644 src/test/ui/associated-type-bounds/hrtb.rs diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 03af81ae02a..6317808e7fb 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -402,7 +402,7 @@ pub enum TraitBoundModifier { /// `typeck::collect::compute_bounds` matches these against /// the "special" built-in traits (see `middle::lang_items`) and /// detects `Copy`, `Send` and `Sync`. -#[derive(Debug, HashStable_Generic)] +#[derive(Clone, Debug, HashStable_Generic)] pub enum GenericBound<'hir> { Trait(PolyTraitRef<'hir>, TraitBoundModifier), // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem` @@ -2556,7 +2556,7 @@ pub enum UseKind { /// that the `ref_id` is for. Note that `ref_id`'s value is not the `HirId` of the /// trait being referred to but just a unique `HirId` that serves as a key /// within the resolution map. -#[derive(Debug, HashStable_Generic)] +#[derive(Clone, Debug, HashStable_Generic)] pub struct TraitRef<'hir> { pub path: &'hir Path<'hir>, // Don't hash the `ref_id`. It is tracked via the thing it is used to access. @@ -2575,7 +2575,7 @@ impl TraitRef<'_> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Clone, Debug, HashStable_Generic)] pub struct PolyTraitRef<'hir> { /// The `'a` in `for<'a> Foo<&'a T>`. pub bound_generic_params: &'hir [GenericParam<'hir>], diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 392553a80f9..c68705da413 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -621,7 +621,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { let var = self.canonical_var(info, r.into()); - let br = ty::BoundRegion { kind: ty::BrAnon(var.as_u32()) }; + let br = ty::BoundRegion { var, kind: ty::BrAnon(var.as_u32()) }; let region = ty::ReLateBound(self.binder_index, br); self.tcx().mk_region(region) } diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index f000d491b99..b8ecc949588 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -439,7 +439,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { // We only allow a `ty::INNERMOST` index in substitutions. assert_eq!(debruijn, ty::INNERMOST); - opt_values[br.assert_bound_var()] = Some(*original_value); + opt_values[br.var] = Some(*original_value); } } GenericArgKind::Const(result_value) => { diff --git a/compiler/rustc_infer/src/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/substitute.rs index 387f480814a..553a11d4393 100644 --- a/compiler/rustc_infer/src/infer/canonical/substitute.rs +++ b/compiler/rustc_infer/src/infer/canonical/substitute.rs @@ -71,11 +71,10 @@ where if var_values.var_values.is_empty() { value } else { - let fld_r = - |br: ty::BoundRegion| match var_values.var_values[br.assert_bound_var()].unpack() { - GenericArgKind::Lifetime(l) => l, - r => bug!("{:?} is a region but value is {:?}", br, r), - }; + let fld_r = |br: ty::BoundRegion| match var_values.var_values[br.var].unpack() { + GenericArgKind::Lifetime(l) => l, + r => bug!("{:?} is a region but value is {:?}", br, r), + }; let fld_t = |bound_ty: ty::BoundTy| match var_values.var_values[bound_ty.var].unpack() { GenericArgKind::Type(ty) => ty, diff --git a/compiler/rustc_middle/src/ich/impls_ty.rs b/compiler/rustc_middle/src/ich/impls_ty.rs index c39ea5825a7..8e53e4ba948 100644 --- a/compiler/rustc_middle/src/ich/impls_ty.rs +++ b/compiler/rustc_middle/src/ich/impls_ty.rs @@ -70,16 +70,16 @@ impl<'a> HashStable> for ty::RegionKind { ty::ReEmpty(universe) => { universe.hash_stable(hcx, hasher); } - ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrAnon(i) }) => { + ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrAnon(i), .. }) => { db.hash_stable(hcx, hasher); i.hash_stable(hcx, hasher); } - ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrNamed(def_id, name) }) => { + ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrNamed(def_id, name), .. }) => { db.hash_stable(hcx, hasher); def_id.hash_stable(hcx, hasher); name.hash_stable(hcx, hasher); } - ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrEnv }) => { + ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrEnv, .. }) => { db.hash_stable(hcx, hasher); } ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => { diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 5d0987193fa..5df2f91f09f 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -314,7 +314,8 @@ impl<'tcx> CanonicalVarValues<'tcx> { tcx.mk_ty(ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i).into())).into() } GenericArgKind::Lifetime(..) => { - let br = ty::BoundRegion { kind: ty::BrAnon(i) }; + let br = + ty::BoundRegion { var: ty::BoundVar::from_u32(i), kind: ty::BrAnon(i) }; tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into() } GenericArgKind::Const(ct) => tcx diff --git a/compiler/rustc_middle/src/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs index 98802721954..aa6488b329e 100644 --- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs +++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs @@ -83,4 +83,6 @@ pub struct ResolveLifetimes { /// be late-bound if (a) it does NOT appear in a where-clause and /// (b) it DOES appear in the arguments. pub late_bound: FxHashMap>, + + pub late_bound_vars: FxHashMap>>, } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index fbd5af9d0a9..99d063c7eea 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1290,6 +1290,10 @@ rustc_queries! { -> Option> { desc { "looking up lifetime defaults for a region on an item" } } + query late_bound_vars_map(_: LocalDefId) + -> Option<&'tcx FxHashMap>> { + desc { "looking up late bound vars" } + } query visibility(def_id: DefId) -> ty::Visibility { eval_always diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1f1840c0e4a..bb2b00cbaea 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -810,7 +810,7 @@ impl CanonicalUserType<'tcx> { ty::ReLateBound(debruijn, br) => { // We only allow a `ty::INNERMOST` index in substitutions. assert_eq!(*debruijn, ty::INNERMOST); - cvar == br.assert_bound_var() + cvar == br.var } _ => false, }, @@ -2672,6 +2672,17 @@ impl<'tcx> TyCtxt<'tcx> { pub fn object_lifetime_defaults(self, id: HirId) -> Option> { self.object_lifetime_defaults_map(id.owner) } + + pub fn late_bound_vars(self, id: HirId) -> &'tcx List { + self.mk_bound_variable_kinds( + self.late_bound_vars_map(id.owner) + .and_then(|map| map.get(&id.local_id).cloned()) + .unwrap_or_else(|| { + bug!("No bound vars found for {:?} ({:?})", self.hir().node_to_string(id), id) + }) + .iter(), + ) + } } impl TyCtxtAt<'tcx> { diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 32101b4c8c9..368236b146f 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -634,6 +634,42 @@ impl<'tcx> TyCtxt<'tcx> { .0 } + pub fn shift_bound_var_indices(self, bound_vars: usize, value: T) -> T + where + T: TypeFoldable<'tcx>, + { + self.replace_escaping_bound_vars( + value, + |r| { + self.mk_region(ty::ReLateBound( + ty::INNERMOST, + ty::BoundRegion { + var: ty::BoundVar::from_usize(r.var.as_usize() + bound_vars), + kind: r.kind, + }, + )) + }, + |t| { + self.mk_ty(ty::Bound( + ty::INNERMOST, + ty::BoundTy { + var: ty::BoundVar::from_usize(t.var.as_usize() + bound_vars), + kind: t.kind, + }, + )) + }, + |c, ty| { + self.mk_const(ty::Const { + val: ty::ConstKind::Bound( + ty::INNERMOST, + ty::BoundVar::from_usize(c.as_usize() + bound_vars), + ), + ty, + }) + }, + ) + } + /// Returns a set of all late-bound regions that are constrained /// by `value`, meaning that if we instantiate those LBR with /// variables and equate `value` with something else, those @@ -695,16 +731,21 @@ impl<'tcx> TyCtxt<'tcx> { T: TypeFoldable<'tcx>, { let mut counter = 0; - Binder::bind( - self.replace_late_bound_regions(sig, |_| { - let br = ty::BoundRegion { kind: ty::BrAnon(counter) }; + let inner = self + .replace_late_bound_regions(sig, |_| { + let br = ty::BoundRegion { + var: ty::BoundVar::from_u32(counter), + kind: ty::BrAnon(counter), + }; let r = self.mk_region(ty::ReLateBound(ty::INNERMOST, br)); counter += 1; r }) - .0, - self, - ) + .0; + let bound_vars = self.mk_bound_variable_kinds( + (0..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i))), + ); + Binder::bind_with_vars(inner, bound_vars) } } @@ -777,27 +818,105 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { } fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { - use std::collections::btree_map::Entry; match r { - ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind { - ty::BrNamed(_def_id, _name) => { - // FIXME - } + ty::ReLateBound(index, _br) if *index == self.binder_index => { + bug!("{:?} {:?}", index, _br) + } - ty::BrAnon(var) => match self.vars.entry(var) { - Entry::Vacant(entry) => { - entry.insert(ty::BoundVariableKind::Region(br.kind)); + _ => (), + }; + + r.super_visit_with(self) + } +} + +pub struct ValidateBoundVars<'tcx> { + bound_vars: &'tcx ty::List, + binder_index: ty::DebruijnIndex, + // We may encounter the same variable at different levels of binding, so + // this can't just be `Ty` + visited: SsoHashSet<(ty::DebruijnIndex, Ty<'tcx>)>, +} + +impl<'tcx> ValidateBoundVars<'tcx> { + pub fn new(bound_vars: &'tcx ty::List) -> Self { + ValidateBoundVars { + bound_vars, + binder_index: ty::INNERMOST, + visited: SsoHashSet::default(), + } + } +} + +impl<'tcx> TypeVisitor<'tcx> for ValidateBoundVars<'tcx> { + type BreakTy = (); + + fn visit_binder>( + &mut self, + t: &Binder<'tcx, T>, + ) -> ControlFlow { + self.binder_index.shift_in(1); + let result = t.super_visit_with(self); + self.binder_index.shift_out(1); + result + } + + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + if t.outer_exclusive_binder < self.binder_index + || !self.visited.insert((self.binder_index, t)) + { + return ControlFlow::BREAK; + } + match *t.kind() { + ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => { + if self.bound_vars.len() <= bound_ty.var.as_usize() { + panic!("Not enough bound vars: {:?} not found in {:?}", t, self.bound_vars); + } + let list_var = self.bound_vars[bound_ty.var.as_usize()]; + match list_var { + ty::BoundVariableKind::Ty(kind) => { + if kind != bound_ty.kind { + panic!( + "Mismatched type kinds: {:?} doesn't var in list {:?}", + bound_ty.kind, list_var + ); + } } - Entry::Occupied(entry) => match entry.get() { - ty::BoundVariableKind::Region(_) => {} - _ => bug!("Conflicting bound vars"), - }, - }, - - ty::BrEnv => { - // FIXME + _ => panic!( + "Mismatched bound variable kinds! Expected type, found {:?}", + list_var + ), } - }, + } + + _ => (), + }; + + t.super_visit_with(self) + } + + fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { + match r { + ty::ReLateBound(index, br) if *index == self.binder_index => { + if self.bound_vars.len() <= br.var.as_usize() { + panic!("Not enough bound vars: {:?} not found in {:?}", *br, self.bound_vars); + } + let list_var = self.bound_vars[br.var.as_usize()]; + match list_var { + ty::BoundVariableKind::Region(kind) => { + if kind != br.kind { + panic!( + "Mismatched region kinds: {:?} doesn't match var ({:?}) in list ({:?})", + br.kind, list_var, self.bound_vars + ); + } + } + _ => panic!( + "Mismatched bound variable kinds! Expected region, found {:?}", + list_var + ), + } + } _ => (), }; diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 0d03cf4575f..e7bbdc3cceb 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1,3 +1,4 @@ +// ignore-tidy-filelength use crate::ich::StableHashingContext; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::mir::{GeneratorLayout, GeneratorSavedLocal}; @@ -2481,21 +2482,42 @@ impl<'tcx> ty::Instance<'tcx> { ty::Closure(def_id, substs) => { let sig = substs.as_closure().sig(); - let env_ty = tcx.closure_env_ty(def_id, substs).unwrap(); - sig.map_bound(|sig| { + let bound_vars = tcx.mk_bound_variable_kinds( + sig.bound_vars() + .iter() + .chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))), + ); + let br = ty::BoundRegion { + var: ty::BoundVar::from_usize(bound_vars.len() - 1), + kind: ty::BoundRegionKind::BrEnv, + }; + let env_region = ty::ReLateBound(ty::INNERMOST, br); + let env_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap(); + + let sig = sig.skip_binder(); + ty::Binder::bind_with_vars( tcx.mk_fn_sig( - iter::once(env_ty.skip_binder()).chain(sig.inputs().iter().cloned()), + iter::once(env_ty).chain(sig.inputs().iter().cloned()), sig.output(), sig.c_variadic, sig.unsafety, sig.abi, - ) - }) + ), + bound_vars, + ) } ty::Generator(_, substs, _) => { let sig = substs.as_generator().poly_sig(); - let br = ty::BoundRegion { kind: ty::BrEnv }; + let bound_vars = tcx.mk_bound_variable_kinds( + sig.bound_vars() + .iter() + .chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))), + ); + let br = ty::BoundRegion { + var: ty::BoundVar::from_usize(bound_vars.len() - 1), + kind: ty::BoundRegionKind::BrEnv, + }; let env_region = ty::ReLateBound(ty::INNERMOST, br); let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); @@ -2504,21 +2526,21 @@ impl<'tcx> ty::Instance<'tcx> { let pin_substs = tcx.intern_substs(&[env_ty.into()]); let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs); - sig.map_bound(|sig| { - let state_did = tcx.require_lang_item(LangItem::GeneratorState, None); - let state_adt_ref = tcx.adt_def(state_did); - let state_substs = - tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]); - let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); - + let sig = sig.skip_binder(); + let state_did = tcx.require_lang_item(LangItem::GeneratorState, None); + let state_adt_ref = tcx.adt_def(state_did); + let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]); + let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); + ty::Binder::bind_with_vars( tcx.mk_fn_sig( [env_ty, sig.resume_ty].iter(), &ret_ty, false, hir::Unsafety::Normal, rustc_target::spec::abi::Abi::Rust, - ) - }) + ), + bound_vars, + ) } _ => bug!("unexpected type {:?} in Instance::fn_sig", ty), } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a09573fac02..6574c938260 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -543,10 +543,33 @@ impl<'tcx> Predicate<'tcx> { // substitution code expects equal binding levels in the values // from the substitution and the value being substituted into, and // this trick achieves that). - let substs = trait_ref.skip_binder().substs; - let pred = self.kind().skip_binder(); - let new = pred.subst(tcx, substs); - tcx.reuse_or_mk_predicate(self, ty::Binder::bind(new, tcx)) + + // Working through the second example: + // trait_ref: for<'x> T: Foo1<'^0.0>; substs: [T, '^0.0] + // predicate: for<'b> Self: Bar1<'a, '^0.0>; substs: [Self, 'a, '^0.0] + // We want to end up with: + // for<'x, 'b> T: Bar1<'^0.0, '^0.1> + // To do this: + // 1) We must shift all bound vars in predicate by the length + // of trait ref's bound vars. So, we would end up with predicate like + // Self: Bar1<'a, '^0.1> + // 2) We can then apply the trait substs to this, ending up with + // T: Bar1<'^0.0, '^0.1> + // 3) Finally, to create the final bound vars, we concatenate the bound + // vars of the trait ref with those of the predicate: + // ['x, 'b] + let bound_pred = self.kind(); + let pred_bound_vars = bound_pred.bound_vars(); + let trait_bound_vars = trait_ref.bound_vars(); + // 1) Self: Bar1<'a, '^0.0> -> Self: Bar1<'a, '^0.1> + let shifted_pred = + tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder()); + // 2) Self: Bar1<'a, '^0.1> -> T: Bar1<'^0.0, '^0.1> + let new = shifted_pred.subst(tcx, trait_ref.skip_binder().substs); + // 3) ['x] + ['b] -> ['x, 'b] + let bound_vars = + tcx.mk_bound_variable_kinds(trait_bound_vars.iter().chain(pred_bound_vars)); + tcx.reuse_or_mk_predicate(self, ty::Binder::bind_with_vars(new, bound_vars)) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index acb5c474164..b8f39fce21d 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1636,7 +1636,7 @@ impl PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { data.name != kw::Empty && data.name != kw::UnderscoreLifetime } - ty::ReLateBound(_, ty::BoundRegion { kind: br }) + ty::ReLateBound(_, ty::BoundRegion { kind: br, .. }) | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { if let ty::BrNamed(_, name) = br { @@ -1715,7 +1715,7 @@ impl FmtPrinter<'_, '_, F> { return Ok(self); } } - ty::ReLateBound(_, ty::BoundRegion { kind: br }) + ty::ReLateBound(_, ty::BoundRegion { kind: br, .. }) | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { if let ty::BrNamed(_, name) = br { @@ -1821,7 +1821,8 @@ impl FmtPrinter<'_, 'tcx, F> { ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name) } }; - self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { kind })) + self.tcx + .mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind })) }); start_or_continue(&mut self, "", "> ")?; @@ -1865,7 +1866,7 @@ impl FmtPrinter<'_, 'tcx, F> { struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet); impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> { fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { - if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name) }) = *r { + if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r { self.0.insert(name); } r.super_visit_with(self) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 1884df0c67b..e352d0bc756 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -6,6 +6,7 @@ use self::TyKind::*; use crate::infer::canonical::Canonical; use crate::ty::fold::BoundVarsCollector; +use crate::ty::fold::ValidateBoundVars; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::InferTy::{self, *}; use crate::ty::{ @@ -63,22 +64,10 @@ pub enum BoundRegionKind { #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)] #[derive(HashStable)] pub struct BoundRegion { + pub var: BoundVar, pub kind: BoundRegionKind, } -impl BoundRegion { - /// When canonicalizing, we replace unbound inference variables and free - /// regions with anonymous late bound regions. This method asserts that - /// we have an anonymous late bound region, which hence may refer to - /// a canonical variable. - pub fn assert_bound_var(&self) -> BoundVar { - match self.kind { - BoundRegionKind::BrAnon(var) => BoundVar::from_u32(var), - _ => bug!("bound region is not anonymous"), - } - } -} - impl BoundRegionKind { pub fn is_named(&self) -> bool { match *self { @@ -987,13 +976,17 @@ where value.visit_with(&mut collector); Binder(value, collector.into_vars(tcx)) } + + pub fn bind_with_vars(value: T, vars: &'tcx List) -> Binder<'tcx, T> { + if cfg!(debug_assertions) { + let mut validator = ValidateBoundVars::new(vars); + value.visit_with(&mut validator); + } + Binder(value, vars) + } } impl<'tcx, T> Binder<'tcx, T> { - pub fn bind_with_vars(value: T, vars: &'tcx List) -> Binder<'tcx, T> { - Binder(value, vars) - } - /// Skips the binder and returns the "bound" value. This is a /// risky thing to do because it's easy to get confused about /// De Bruijn indices and the like. It is usually better to @@ -1022,18 +1015,31 @@ impl<'tcx, T> Binder<'tcx, T> { Binder(&self.0, self.1) } - pub fn map_bound_ref(&self, f: F) -> Binder<'tcx, U> + pub fn map_bound_ref_unchecked(&self, f: F) -> Binder<'tcx, U> + where + F: FnOnce(&T) -> U, + { + let value = f(&self.0); + Binder(value, self.1) + } + + pub fn map_bound_ref>(&self, f: F) -> Binder<'tcx, U> where F: FnOnce(&T) -> U, { self.as_ref().map_bound(f) } - pub fn map_bound(self, f: F) -> Binder<'tcx, U> + pub fn map_bound>(self, f: F) -> Binder<'tcx, U> where F: FnOnce(T) -> U, { - Binder(f(self.0), self.1) + let value = f(self.0); + if cfg!(debug_assertions) { + let mut validator = ValidateBoundVars::new(self.1); + value.visit_with(&mut validator); + } + Binder(value, self.1) } /// Wraps a `value` in a binder, using the same bound variables as the @@ -1045,7 +1051,14 @@ impl<'tcx, T> Binder<'tcx, T> { /// don't actually track bound vars. However, semantically, it is different /// because bound vars aren't allowed to change here, whereas they are /// in `bind`. This may be (debug) asserted in the future. - pub fn rebind(&self, value: U) -> Binder<'tcx, U> { + pub fn rebind(&self, value: U) -> Binder<'tcx, U> + where + U: TypeFoldable<'tcx>, + { + if cfg!(debug_assertions) { + let mut validator = ValidateBoundVars::new(self.bound_vars()); + value.visit_with(&mut validator); + } Binder(value, self.1) } @@ -1066,20 +1079,6 @@ impl<'tcx, T> Binder<'tcx, T> { if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) } } - /// Given two things that have the same binder level, - /// and an operation that wraps on their contents, executes the operation - /// and then wraps its result. - /// - /// `f` should consider bound regions at depth 1 to be free, and - /// anything it produces with bound regions at depth 1 will be - /// bound in the resulting return value. - pub fn fuse(self, u: Binder<'tcx, U>, f: F) -> Binder<'tcx, R> - where - F: FnOnce(T, U) -> R, - { - Binder(f(self.0, u.0), self.1) - } - /// Splits the contents into two things that share the same binder /// level as the original, returning two distinct binders. /// @@ -1204,7 +1203,7 @@ pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>; impl<'tcx> PolyFnSig<'tcx> { #[inline] pub fn inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]> { - self.map_bound_ref(|fn_sig| fn_sig.inputs()) + self.map_bound_ref_unchecked(|fn_sig| fn_sig.inputs()) } #[inline] pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 93fbc1f53b2..b211ac2a79f 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -499,18 +499,18 @@ impl<'tcx> TyCtxt<'tcx> { self, closure_def_id: DefId, closure_substs: SubstsRef<'tcx>, - ) -> Option>> { + env_region: ty::RegionKind, + ) -> Option> { let closure_ty = self.mk_closure(closure_def_id, closure_substs); - let br = ty::BoundRegion { kind: ty::BrEnv }; - let env_region = ty::ReLateBound(ty::INNERMOST, br); let closure_kind_ty = closure_substs.as_closure().kind_ty(); let closure_kind = closure_kind_ty.to_opt_closure_kind()?; + debug_assert!(!closure_ty.has_escaping_bound_vars()); let env_ty = match closure_kind { ty::ClosureKind::Fn => self.mk_imm_ref(self.mk_region(env_region), closure_ty), ty::ClosureKind::FnMut => self.mk_mut_ref(self.mk_region(env_region), closure_ty), ty::ClosureKind::FnOnce => closure_ty, }; - Some(ty::Binder::bind(env_ty, self)) + Some(env_ty) } /// Returns `true` if the node pointed to by `def_id` is a `static` item. diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs index 4f61b8d0910..6ea0ba0a8e1 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs @@ -502,7 +502,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // lifetimes without names with the value `'0`. match ty.kind() { ty::Ref( - ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br }) + ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br, .. }) | ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }), _, _, @@ -523,7 +523,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let region = match ty.kind() { ty::Ref(region, _, _) => { match region { - ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br }) + ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br, .. }) | ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => { printer.region_highlight_mode.highlighting_bound_region(*br, counter) } diff --git a/compiler/rustc_mir/src/borrow_check/universal_regions.rs b/compiler/rustc_mir/src/borrow_check/universal_regions.rs index f295693781e..c2ac1e289ce 100644 --- a/compiler/rustc_mir/src/borrow_check/universal_regions.rs +++ b/compiler/rustc_mir/src/borrow_check/universal_regions.rs @@ -596,24 +596,38 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { assert_eq!(self.mir_def.did.to_def_id(), def_id); let closure_sig = substs.as_closure().sig(); let inputs_and_output = closure_sig.inputs_and_output(); - let closure_ty = tcx.closure_env_ty(def_id, substs).unwrap(); - ty::Binder::fuse(closure_ty, inputs_and_output, |closure_ty, inputs_and_output| { - // The "inputs" of the closure in the - // signature appear as a tuple. The MIR side - // flattens this tuple. - let (&output, tuplized_inputs) = inputs_and_output.split_last().unwrap(); - assert_eq!(tuplized_inputs.len(), 1, "multiple closure inputs"); - let inputs = match tuplized_inputs[0].kind() { - ty::Tuple(inputs) => inputs, - _ => bug!("closure inputs not a tuple: {:?}", tuplized_inputs[0]), - }; + let bound_vars = tcx.mk_bound_variable_kinds( + inputs_and_output + .bound_vars() + .iter() + .chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))), + ); + let br = ty::BoundRegion { + var: ty::BoundVar::from_usize(bound_vars.len() - 1), + kind: ty::BrEnv, + }; + let env_region = ty::ReLateBound(ty::INNERMOST, br); + let closure_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap(); + // The "inputs" of the closure in the + // signature appear as a tuple. The MIR side + // flattens this tuple. + let (&output, tuplized_inputs) = + inputs_and_output.skip_binder().split_last().unwrap(); + assert_eq!(tuplized_inputs.len(), 1, "multiple closure inputs"); + let inputs = match tuplized_inputs[0].kind() { + ty::Tuple(inputs) => inputs, + _ => bug!("closure inputs not a tuple: {:?}", tuplized_inputs[0]), + }; + + ty::Binder::bind_with_vars( tcx.mk_type_list( iter::once(closure_ty) .chain(inputs.iter().map(|k| k.expect_ty())) .chain(iter::once(output)), - ) - }) + ), + bound_vars, + ) } DefiningTy::Generator(def_id, substs, movability) => { diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 9f1de3349a5..c90f94c6d63 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -252,8 +252,13 @@ fn liberated_closure_env_ty( _ => bug!("closure expr does not have closure type: {:?}", closure_ty), }; - let closure_env_ty = tcx.closure_env_ty(closure_def_id, closure_substs).unwrap(); - tcx.erase_late_bound_regions(closure_env_ty) + let bound_vars = + tcx.mk_bound_variable_kinds(std::iter::once(ty::BoundVariableKind::Region(ty::BrEnv))); + let br = + ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind: ty::BrEnv }; + let env_region = ty::ReLateBound(ty::INNERMOST, br); + let closure_env_ty = tcx.closure_env_ty(closure_def_id, closure_substs, env_region).unwrap(); + tcx.erase_late_bound_regions(ty::Binder::bind_with_vars(closure_env_ty, bound_vars)) } #[derive(Debug, PartialEq, Eq)] diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 1377bb781d0..25acbd478bf 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -34,6 +34,7 @@ use tracing::debug; mod diagnostics; crate mod lifetimes; +crate mod supertraits; type Res = def::Res; diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 8e0309225de..79d81ef047e 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -30,7 +30,7 @@ use std::cell::Cell; use std::fmt; use std::mem::take; -use tracing::debug; +use tracing::{debug, span, Level}; // This counts the no of times a lifetime is used #[derive(Clone, Copy, Debug)] @@ -44,7 +44,7 @@ trait RegionExt { fn late(index: u32, hir_map: &Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region); - fn late_anon(named_late_bound_vars: u32, anon_index: &Cell) -> Region; + fn late_anon(named_late_bound_vars: u32, index: &Cell) -> Region; fn id(&self) -> Option; @@ -150,6 +150,8 @@ struct NamedRegionMap { // be late-bound if (a) it does NOT appear in a where-clause and // (b) it DOES appear in the arguments. late_bound: HirIdSet, + + late_bound_vars: HirIdMap>, } crate struct LifetimeContext<'a, 'tcx> { @@ -164,13 +166,15 @@ crate struct LifetimeContext<'a, 'tcx> { /// correct when representing these constraints, we should only introduce one /// scope. However, we want to support both locations for the quantifier and /// during lifetime resolution we want precise information (so we can't - /// desugar in an earlier phase). + /// desugar in an earlier phase). Moreso, an error here doesn't cause a bail + /// from type checking, so we need to be extra careful that we don't lose + /// any bound var information. /// /// So, if we encounter a quantifier at the outer scope, we set /// `trait_ref_hack` to `true` (and introduce a scope), and then if we encounter /// a quantifier at the inner scope, we error. If `trait_ref_hack` is `false`, /// then we introduce the scope at the inner quantifier. - trait_ref_hack: bool, + trait_ref_hack: Option<(Vec, u32)>, /// Used to disallow the use of in-band lifetimes in `fn` or `Fn` syntax. is_in_fn_syntax: bool, @@ -228,8 +232,19 @@ enum Scope<'a> { /// of the resulting opaque type. opaque_type_parent: bool, + /// We need to keep track of the number of named late bound vars, since + /// we may have elided lifetimes that have an index starting *after* + /// these. named_late_bound_vars: u32, + from_poly_trait_ref: bool, + + /// The late bound vars for a given item are stored by `HirId` to be + /// queried later. However, if we enter an elision scope, we have to + /// later append the elided bound vars to the list and need to know what + /// to append to. + hir_id: hir::HirId, + s: ScopeRef<'a>, }, @@ -257,6 +272,51 @@ enum Scope<'a> { s: ScopeRef<'a>, }, + /// This is a particularly interesting consequence of how we handle poly + /// trait refs. See `trait_ref_hack` for additional info. This bit is + /// important w.r.t. querying late-bound vars. + /// + /// To completely understand why this is necessary, first it's important to + /// realize that `T: for<'a> U + for<'a, 'b> V` is actually two separate + /// trait refs: `T: for<'a> U` and `T: for<'b> V` and as such, the late + /// bound vars on each needs to be tracked separately. Also, in this case, + /// are *three* relevant `HirId`s: one for the entire bound and one + /// for each separate one. + /// + /// Next, imagine three different poly trait refs: + /// 1) `for<'a, 'b> T: U<'a, 'b>` + /// 2) `T: for<'a, 'b> U<'a, 'b>` + /// 3) `for<'a> T: for<'b> U<'a, 'b>` + /// + /// First, note that the third example is semantically invalid and an error, + /// but we *must* handle it as valid, since type checking isn't bailed out + /// of. Other than that, if ask for bound vars for each, we expect + /// `['a, 'b]`. If we *didn't* allow binders before `T`, then we would + /// always introduce a binder scope at the inner trait ref. This is great, + /// becauase later on during type-checking, we will ask "what are the late + /// bound vars on this trait ref". However, because we allow bound vars on + /// the bound itself, we have to have some way of keeping track of the fact + /// that we actually want to store the late bound vars as being associated + /// with the trait ref; this is that. + /// + /// One alternative way to handle this would be to just introduce a new + /// `Binder` scope, but that's semantically a bit different, since bound + /// vars from both `for<...>`s *do* share the same binder level. + TraitRefHackInner { + hir_id: hir::HirId, + named_late_bound_vars: u32, + s: ScopeRef<'a>, + }, + + /// When we have nested trait refs, we concanetate late bound vars for inner + /// trait refs from outer ones. But we also need to include any HRTB + /// lifetimes encountered when identifying the trait that an associated type + /// is declared on. + Supertrait { + lifetimes: Vec, + s: ScopeRef<'a>, + }, + Root, } @@ -272,6 +332,8 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { track_lifetime_uses, opaque_type_parent, named_late_bound_vars, + from_poly_trait_ref, + hir_id, s: _, } => f .debug_struct("Binder") @@ -280,6 +342,8 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { .field("track_lifetime_uses", track_lifetime_uses) .field("opaque_type_parent", opaque_type_parent) .field("named_late_bound_vars", named_late_bound_vars) + .field("from_poly_trait_ref", from_poly_trait_ref) + .field("hir_id", hir_id) .field("s", &"..") .finish(), Scope::Body { id, s: _ } => { @@ -293,6 +357,17 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { .field("lifetime", lifetime) .field("s", &"..") .finish(), + Scope::TraitRefHackInner { hir_id, named_late_bound_vars, s: _ } => f + .debug_struct("TraitRefHackInner") + .field("hir_id", hir_id) + .field("named_late_bound_vars", named_late_bound_vars) + .field("s", &"..") + .finish(), + Scope::Supertrait { lifetimes, s: _ } => f + .debug_struct("Supertrait") + .field("lifetimes", lifetimes) + .field("s", &"..") + .finish(), Scope::Root => f.debug_struct("Root").finish(), } } @@ -342,6 +417,7 @@ pub fn provide(providers: &mut ty::query::Providers) { _ => None, } }, + late_bound_vars_map: |tcx, id| resolve_lifetimes_for(tcx, id).late_bound_vars.get(&id), ..*providers }; @@ -399,13 +475,16 @@ fn do_resolve( trait_definition_only: bool, ) -> ResolveLifetimes { let item = tcx.hir().expect_item(tcx.hir().local_def_id_to_hir_id(local_def_id)); - let mut named_region_map = - NamedRegionMap { defs: Default::default(), late_bound: Default::default() }; + let mut named_region_map = NamedRegionMap { + defs: Default::default(), + late_bound: Default::default(), + late_bound_vars: Default::default(), + }; let mut visitor = LifetimeContext { tcx, map: &mut named_region_map, scope: ROOT_SCOPE, - trait_ref_hack: false, + trait_ref_hack: None, is_in_fn_syntax: false, is_in_const_generic: false, trait_definition_only, @@ -426,6 +505,10 @@ fn do_resolve( let map = rl.late_bound.entry(hir_id.owner).or_default(); map.insert(hir_id.local_id); } + for (hir_id, v) in named_region_map.late_bound_vars { + let map = rl.late_bound_vars.entry(hir_id.owner).or_default(); + map.insert(hir_id.local_id, v); + } debug!(?rl.defs); rl @@ -511,6 +594,19 @@ fn sub_items_have_self_param(node: &hir::ItemKind<'_>) -> bool { matches!(*node, hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..)) } +fn late_region_as_bound_region<'tcx>(tcx: TyCtxt<'tcx>, region: &Region) -> ty::BoundVariableKind { + match region { + Region::LateBound(_, _, def_id, _) => { + let name = tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local())); + ty::BoundVariableKind::Region(ty::BrNamed(*def_id, name)) + } + Region::LateBoundAnon(_, _, anon_idx) => { + ty::BoundVariableKind::Region(ty::BrAnon(*anon_idx)) + } + _ => bug!("{:?} is not a late region", region), + } +} + impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { type Map = Map<'tcx>; @@ -538,11 +634,59 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.labels_in_fn = saved; } + fn visit_fn( + &mut self, + fk: intravisit::FnKind<'tcx>, + fd: &'tcx hir::FnDecl<'tcx>, + b: hir::BodyId, + s: rustc_span::Span, + hir_id: hir::HirId, + ) { + let name = match fk { + intravisit::FnKind::ItemFn(id, _, _, _) => id.as_str(), + intravisit::FnKind::Method(id, _, _) => id.as_str(), + intravisit::FnKind::Closure => Symbol::intern("closure").as_str(), + }; + let name: &str = &name; + let span = span!(Level::DEBUG, "visit_fn", name); + let _enter = span.enter(); + match fk { + // Any `Binders` are handled elsewhere + intravisit::FnKind::ItemFn(..) | intravisit::FnKind::Method(..) => { + intravisit::walk_fn(self, fk, fd, b, s, hir_id) + } + intravisit::FnKind::Closure => { + self.map.late_bound_vars.insert(hir_id, vec![]); + let scope = Scope::Binder { + hir_id, + lifetimes: FxHashMap::default(), + next_early_index: self.next_early_index(), + s: self.scope, + track_lifetime_uses: true, + opaque_type_parent: false, + named_late_bound_vars: 0, + from_poly_trait_ref: false, + }; + self.with(scope, move |_old_scope, this| { + intravisit::walk_fn(this, fk, fd, b, s, hir_id) + }); + } + } + } + fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { + match &item.kind { + hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => { + if let Some(of_trait) = of_trait { + self.map.late_bound_vars.insert(of_trait.hir_ref_id, Vec::default()); + } + } + _ => {} + } match item.kind { hir::ItemKind::Fn(ref sig, ref generics, _) => { self.missing_named_lifetime_spots.push(generics.into()); - self.visit_early_late(None, &sig.decl, generics, |this| { + self.visit_early_late(None, item.hir_id(), &sig.decl, generics, |this| { intravisit::walk_item(this, item); }); self.missing_named_lifetime_spots.pop(); @@ -590,6 +734,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.map.late_bound.insert(hir::HirId { owner, local_id }); }); } + for (&owner, late_bound_vars) in + resolved_lifetimes.late_bound_vars.iter() + { + late_bound_vars.iter().for_each(|(&local_id, late_bound_vars)| { + self.map.late_bound_vars.insert( + hir::HirId { owner, local_id }, + late_bound_vars.clone(), + ); + }); + } break; } hir::Node::Crate(_) => bug!("No Item about an OpaqueTy"), @@ -629,12 +783,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } }) .collect(); + self.map.late_bound_vars.insert(item.hir_id(), vec![]); let scope = Scope::Binder { + hir_id: item.hir_id(), lifetimes, next_early_index: index + non_lifetime_count, opaque_type_parent: true, track_lifetime_uses, named_late_bound_vars: 0, + from_poly_trait_ref: false, s: ROOT_SCOPE, }; self.with(scope, |old_scope, this| { @@ -649,7 +806,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) { match item.kind { hir::ForeignItemKind::Fn(ref decl, _, ref generics) => { - self.visit_early_late(None, decl, generics, |this| { + self.visit_early_late(None, item.hir_id(), decl, generics, |this| { intravisit::walk_foreign_item(this, item); }) } @@ -681,23 +838,32 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }; self.missing_named_lifetime_spots .push(MissingLifetimeSpot::HigherRanked { span, span_type }); + let mut named_late_bound_vars = 0; + let (lifetimes, binders): (FxHashMap, Vec<_>) = c + .generic_params + .iter() + .filter_map(|param| match param.kind { + GenericParamKind::Lifetime { .. } => { + let late_bound_idx = named_late_bound_vars; + named_late_bound_vars += 1; + let pair = Region::late(late_bound_idx, &self.tcx.hir(), param); + let r = pair.1.clone(); + let r = late_region_as_bound_region(self.tcx, &r); + Some((pair, r)) + } + _ => None, + }) + .unzip(); + self.map.late_bound_vars.insert(ty.hir_id, binders); let scope = Scope::Binder { - lifetimes: c - .generic_params - .iter() - .enumerate() - .filter_map(|(idx, param)| match param.kind { - GenericParamKind::Lifetime { .. } => { - Some(Region::late(idx as u32, &self.tcx.hir(), param)) - } - _ => None, - }) - .collect(), + hir_id: ty.hir_id, + lifetimes, s: self.scope, next_early_index, track_lifetime_uses: true, opaque_type_parent: false, - named_late_bound_vars: c.generic_params.len() as u32, + named_late_bound_vars, + from_poly_trait_ref: false, }; self.with(scope, |old_scope, this| { // a bare fn has no bounds, so everything @@ -874,18 +1040,21 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } let next_early_index = index + non_lifetime_count; + self.map.late_bound_vars.insert(ty.hir_id, vec![]); if let Some(elision_region) = elision { let scope = Scope::Elision { elide: Elide::Exact(elision_region), s: self.scope }; self.with(scope, |_old_scope, this| { let scope = Scope::Binder { + hir_id: ty.hir_id, lifetimes, next_early_index, s: this.scope, track_lifetime_uses: true, opaque_type_parent: false, named_late_bound_vars: 0, + from_poly_trait_ref: false, }; this.with(scope, |_old_scope, this| { this.visit_generics(generics); @@ -896,12 +1065,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }); } else { let scope = Scope::Binder { + hir_id: ty.hir_id, lifetimes, next_early_index, s: self.scope, track_lifetime_uses: true, opaque_type_parent: false, named_late_bound_vars: 0, + from_poly_trait_ref: false, }; self.with(scope, |_old_scope, this| { this.visit_generics(generics); @@ -923,6 +1094,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let tcx = self.tcx; self.visit_early_late( Some(tcx.hir().get_parent_item(trait_item.hir_id())), + trait_item.hir_id(), &sig.decl, &trait_item.generics, |this| intravisit::walk_trait_item(this, trait_item), @@ -948,13 +1120,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } }) .collect(); + self.map.late_bound_vars.insert(trait_item.hir_id(), vec![]); let scope = Scope::Binder { + hir_id: trait_item.hir_id(), lifetimes, next_early_index: index + non_lifetime_count, s: self.scope, track_lifetime_uses: true, opaque_type_parent: true, named_late_bound_vars: 0, + from_poly_trait_ref: false, }; self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &generics.params); @@ -986,6 +1161,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let tcx = self.tcx; self.visit_early_late( Some(tcx.hir().get_parent_item(impl_item.hir_id())), + impl_item.hir_id(), &sig.decl, &impl_item.generics, |this| intravisit::walk_impl_item(this, impl_item), @@ -998,7 +1174,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let mut index = self.next_early_index(); let mut non_lifetime_count = 0; debug!("visit_ty: index = {}", index); - let lifetimes = generics + let lifetimes: FxHashMap = generics .params .iter() .filter_map(|param| match param.kind { @@ -1011,13 +1187,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } }) .collect(); + self.map.late_bound_vars.insert(ty.hir_id, vec![]); let scope = Scope::Binder { + hir_id: ty.hir_id, lifetimes, next_early_index: index + non_lifetime_count, s: self.scope, track_lifetime_uses: true, opaque_type_parent: true, named_late_bound_vars: 0, + from_poly_trait_ref: false, }; self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &generics.params); @@ -1100,32 +1279,40 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { ref bound_generic_params, .. }) => { - let lifetimes: FxHashMap<_, _> = bound_generic_params + let mut named_late_bound_vars = 0; + let (lifetimes, binders): (FxHashMap<_, _>, Vec<_>) = bound_generic_params .iter() - .enumerate() - .filter_map(|(idx, param)| match param.kind { + .filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => { - Some(Region::late(idx as u32, &self.tcx.hir(), param)) + let late_bound_idx = named_late_bound_vars; + named_late_bound_vars += 1; + let pair = Region::late(late_bound_idx, &self.tcx.hir(), param); + let r = pair.1.clone(); + let r = late_region_as_bound_region(self.tcx, &r); + Some((pair, r)) } _ => None, }) - .collect(); + .unzip(); + self.map.late_bound_vars.insert(bounded_ty.hir_id, binders.clone()); if !lifetimes.is_empty() { let next_early_index = self.next_early_index(); let scope = Scope::Binder { + hir_id: bounded_ty.hir_id, lifetimes, s: self.scope, next_early_index, track_lifetime_uses: true, opaque_type_parent: false, - named_late_bound_vars: bound_generic_params.len() as u32, + named_late_bound_vars, + from_poly_trait_ref: true, }; let result = self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &bound_generic_params); this.visit_ty(&bounded_ty); - this.trait_ref_hack = true; + this.trait_ref_hack = Some((binders, named_late_bound_vars)); walk_list!(this, visit_param_bound, bounds); - this.trait_ref_hack = false; + this.trait_ref_hack = None; }); result } else { @@ -1155,14 +1342,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_param_bound(&mut self, bound: &'tcx hir::GenericBound<'tcx>) { match bound { - hir::GenericBound::LangItemTrait { .. } if !self.trait_ref_hack => { + hir::GenericBound::LangItemTrait(_, _, hir_id, _) if self.trait_ref_hack.is_none() => { + self.map.late_bound_vars.insert(*hir_id, vec![]); let scope = Scope::Binder { + hir_id: *hir_id, lifetimes: FxHashMap::default(), s: self.scope, next_early_index: self.next_early_index(), track_lifetime_uses: true, opaque_type_parent: false, named_late_bound_vars: 0, + from_poly_trait_ref: false, }; self.with(scope, |_, this| { intravisit::walk_param_bound(this, bound); @@ -1181,40 +1371,144 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let should_pop_missing_lt = self.is_trait_ref_fn_scope(trait_ref); - let trait_ref_hack = take(&mut self.trait_ref_hack); - if !trait_ref_hack - || trait_ref - .bound_generic_params - .iter() - .any(|param| matches!(param.kind, GenericParamKind::Lifetime { .. })) - { - if trait_ref_hack { - struct_span_err!( - self.tcx.sess, - trait_ref.span, - E0316, - "nested quantification of lifetimes" - ) - .emit(); - } - let next_early_index = self.next_early_index(); - let scope = Scope::Binder { - lifetimes: trait_ref + let trait_ref_hack = self.trait_ref_hack.take(); + let next_early_index = self.next_early_index(); + // See note on `trait_ref_hack`. If `for<..>` has been defined in both + // the outer and inner part of the trait ref, emit an error. + let has_lifetimes = trait_ref.bound_generic_params.iter().any(|param| match param.kind { + GenericParamKind::Lifetime { .. } => true, + _ => false, + }); + if trait_ref_hack.is_some() && has_lifetimes { + struct_span_err!( + self.tcx.sess, + trait_ref.span, + E0316, + "nested quantification of lifetimes" + ) + .emit(); + } + + let (binders, named_late_bound_vars, lifetimes) = + if let Some((mut binders, mut named_late_bound_vars)) = trait_ref_hack.clone() { + let initial_binders = named_late_bound_vars; + binders.extend(trait_ref.bound_generic_params.iter().filter_map(|param| { + match param.kind { + GenericParamKind::Lifetime { .. } => { + let late_bound_idx = named_late_bound_vars; + named_late_bound_vars += 1; + let region = Region::late(late_bound_idx, &self.tcx.hir(), param).1; + Some(late_region_as_bound_region(self.tcx, ®ion)) + } + GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, + } + })); + + let mut named_late_bound_vars = initial_binders; + let lifetimes: FxHashMap = trait_ref .bound_generic_params .iter() - .enumerate() - .filter_map(|(idx, param)| match param.kind { + .filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => { - Some(Region::late(idx as u32, &self.tcx.hir(), param)) + let late_bound_idx = named_late_bound_vars; + named_late_bound_vars += 1; + Some(Region::late(late_bound_idx, &self.tcx.hir(), param)) } _ => None, }) - .collect(), + .collect(); + + (binders, named_late_bound_vars, lifetimes) + } else { + let mut supertrait_lifetimes = vec![]; + let mut scope = self.scope; + let mut binders = loop { + match scope { + Scope::Body { .. } | Scope::Root => { + break vec![]; + } + + Scope::Elision { s, .. } | Scope::ObjectLifetimeDefault { s, .. } => { + scope = s; + } + + Scope::TraitRefHackInner { hir_id, .. } => { + // Nested poly trait refs have the binders concatenated + // If we reach `TraitRefHackInner`, then there is only one more `Binder` above us, + // over all the bounds. We don't want this, since all the lifetimes we care about + // are here anyways. + let mut full_binders = + self.map.late_bound_vars.entry(*hir_id).or_default().clone(); + full_binders.extend(supertrait_lifetimes.into_iter()); + break full_binders; + } + + Scope::Supertrait { s, lifetimes } => { + supertrait_lifetimes = lifetimes.clone(); + scope = s; + } + + Scope::Binder { hir_id, from_poly_trait_ref, .. } => { + if !from_poly_trait_ref { + // We should only see super trait lifetimes if there is a `Binder` above + assert!(supertrait_lifetimes.is_empty()); + break vec![]; + } + // Nested poly trait refs have the binders concatenated + let mut full_binders = + self.map.late_bound_vars.entry(*hir_id).or_default().clone(); + full_binders.extend(supertrait_lifetimes.into_iter()); + break full_binders; + } + } + }; + let mut named_late_bound_vars = binders.len() as u32; + let local_binders: Vec<_> = trait_ref + .bound_generic_params + .iter() + .filter_map(|param| match param.kind { + GenericParamKind::Lifetime { .. } => { + let late_bound_idx = named_late_bound_vars; + named_late_bound_vars += 1; + let region = Region::late(late_bound_idx, &self.tcx.hir(), param).1; + Some(late_region_as_bound_region(self.tcx, ®ion)) + } + GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, + }) + .collect(); + + let mut named_late_bound_vars = binders.len() as u32; + let lifetimes: FxHashMap = trait_ref + .bound_generic_params + .iter() + .filter_map(|param| match param.kind { + GenericParamKind::Lifetime { .. } => { + let late_bound_idx = named_late_bound_vars; + named_late_bound_vars += 1; + Some(Region::late(late_bound_idx, &self.tcx.hir(), param)) + } + _ => None, + }) + .collect(); + + binders.extend(local_binders.into_iter()); + + (binders, named_late_bound_vars, lifetimes) + }; + + debug!(?binders); + self.map.late_bound_vars.insert(trait_ref.trait_ref.hir_ref_id, binders); + + if trait_ref_hack.is_none() || has_lifetimes { + let scope = Scope::Binder { + hir_id: trait_ref.trait_ref.hir_ref_id, + lifetimes, s: self.scope, next_early_index, track_lifetime_uses: true, opaque_type_parent: false, - named_late_bound_vars: trait_ref.bound_generic_params.len() as u32, + named_late_bound_vars: named_late_bound_vars as u32, + from_poly_trait_ref: true, }; self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params); @@ -1222,7 +1516,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { this.visit_trait_ref(&trait_ref.trait_ref); }); } else { - self.visit_trait_ref(&trait_ref.trait_ref); + let scope = Scope::TraitRefHackInner { + hir_id: trait_ref.trait_ref.hir_ref_id, + named_late_bound_vars: named_late_bound_vars as u32, + s: self.scope, + }; + self.with(scope, |_old_scope, this| { + this.visit_trait_ref(&trait_ref.trait_ref); + }); } self.trait_ref_hack = trait_ref_hack; if should_pop_missing_lt { @@ -1374,7 +1675,9 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) { match *scope { Scope::Body { s, .. } | Scope::Elision { s, .. } - | Scope::ObjectLifetimeDefault { s, .. } => { + | Scope::ObjectLifetimeDefault { s, .. } + | Scope::TraitRefHackInner { s, .. } + | Scope::Supertrait { s, .. } => { scope = s; } @@ -1563,11 +1866,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let labels_in_fn = take(&mut self.labels_in_fn); let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults); let missing_named_lifetime_spots = take(&mut self.missing_named_lifetime_spots); + let trait_ref_hack = take(&mut self.trait_ref_hack); let mut this = LifetimeContext { tcx: *tcx, map, scope: &wrap_scope, - trait_ref_hack: self.trait_ref_hack, + trait_ref_hack, is_in_fn_syntax: self.is_in_fn_syntax, is_in_const_generic: self.is_in_const_generic, trait_definition_only: self.trait_definition_only, @@ -1587,6 +1891,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { self.labels_in_fn = this.labels_in_fn; self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults; self.missing_named_lifetime_spots = this.missing_named_lifetime_spots; + self.trait_ref_hack = this.trait_ref_hack; } /// helper method to determine the span to remove when suggesting the @@ -1881,6 +2186,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { fn visit_early_late( &mut self, parent_id: Option, + hir_id: hir::HirId, decl: &'tcx hir::FnDecl<'tcx>, generics: &'tcx hir::Generics<'tcx>, walk: F, @@ -1890,16 +2196,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { insert_late_bound_lifetimes(self.map, decl, generics); // Find the start of nested early scopes, e.g., in methods. - let mut index = 0; + let mut next_early_index = 0; if let Some(parent_id) = parent_id { let parent = self.tcx.hir().expect_item(parent_id); if sub_items_have_self_param(&parent.kind) { - index += 1; // Self comes before lifetimes + next_early_index += 1; // Self comes before lifetimes } match parent.kind { hir::ItemKind::Trait(_, _, ref generics, ..) | hir::ItemKind::Impl(hir::Impl { ref generics, .. }) => { - index += generics.params.len() as u32; + next_early_index += generics.params.len() as u32; } _ => {} } @@ -1907,17 +2213,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let mut non_lifetime_count = 0; let mut named_late_bound_vars = 0; - let lifetimes = generics + let lifetimes: FxHashMap = generics .params .iter() - .enumerate() - .filter_map(|(idx, param)| match param.kind { + .filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => { if self.map.late_bound.contains(¶m.hir_id) { + let late_bound_idx = named_late_bound_vars; named_late_bound_vars += 1; - Some(Region::late(idx as u32, &self.tcx.hir(), param)) + Some(Region::late(late_bound_idx, &self.tcx.hir(), param)) } else { - Some(Region::early(&self.tcx.hir(), &mut index, param)) + Some(Region::early(&self.tcx.hir(), &mut next_early_index, param)) } } GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { @@ -1926,15 +2232,37 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } }) .collect(); - let next_early_index = index + non_lifetime_count; + let next_early_index = next_early_index + non_lifetime_count; + let mut named_late_bound_vars = 0; + let binders: Vec<_> = generics + .params + .iter() + .filter_map(|param| match param.kind { + GenericParamKind::Lifetime { .. } => { + if self.map.late_bound.contains(¶m.hir_id) { + let late_bound_idx = named_late_bound_vars; + named_late_bound_vars += 1; + let r = Region::late(late_bound_idx, &self.tcx.hir(), param).1; + let r = late_region_as_bound_region(self.tcx, &r); + Some(r) + } else { + None + } + } + GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, + }) + .collect(); + self.map.late_bound_vars.insert(hir_id, binders); let scope = Scope::Binder { + hir_id, lifetimes, next_early_index, s: self.scope, opaque_type_parent: true, track_lifetime_uses: false, - named_late_bound_vars, + named_late_bound_vars: named_late_bound_vars as u32, + from_poly_trait_ref: false, }; self.with(scope, move |old_scope, this| { this.check_lifetime_params(old_scope, &generics.params); @@ -1957,7 +2285,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Binder { s, .. } | Scope::Body { s, .. } | Scope::Elision { s, .. } - | Scope::ObjectLifetimeDefault { s, .. } => scope = s, + | Scope::ObjectLifetimeDefault { s, .. } + | Scope::TraitRefHackInner { s, .. } + | Scope::Supertrait { s, .. } => scope = s, } } } @@ -1989,6 +2319,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // given name or we run out of scopes. // search. let mut late_depth = 0; + let mut in_poly_trait_ref = false; let mut scope = self.scope; let mut outermost_body = None; let result = loop { @@ -2006,7 +2337,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { break None; } - Scope::Binder { ref lifetimes, s, .. } => { + Scope::Binder { ref lifetimes, from_poly_trait_ref, s, .. } => { match lifetime_ref.name { LifetimeName::Param(param_name) => { if let Some(&def) = lifetimes.get(¶m_name.normalize_to_macros_2_0()) @@ -2017,11 +2348,35 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { _ => bug!("expected LifetimeName::Param"), } - late_depth += 1; + match (from_poly_trait_ref, in_poly_trait_ref) { + // This is the first binder we see that is a poly trait ref; add one to the + // late depth and mark that we're potentially in nested trait refs. + (true, false) => { + in_poly_trait_ref = true; + late_depth += 1; + } + // We've already seen a binder that is a poly trait ref and this one is too, + // that means that they are nested and we are concatenating the bound vars; + // don't increase the late depth. + (true, true) => {} + // We've exited nested poly trait refs; add one to the late depth and mark + // that we are no longer in nested trait refs + (false, true) => { + in_poly_trait_ref = false; + late_depth += 1; + } + // Any other kind of nested binders: just increase late depth. + (false, false) => { + late_depth += 1; + } + } scope = s; } - Scope::Elision { s, .. } | Scope::ObjectLifetimeDefault { s, .. } => { + Scope::Elision { s, .. } + | Scope::ObjectLifetimeDefault { s, .. } + | Scope::TraitRefHackInner { s, .. } + | Scope::Supertrait { s, .. } => { scope = s; } } @@ -2117,6 +2472,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { _ => None, }) .collect(); + // We short-circuit here if all are elided in order to pluralize + // possible errors if elide_lifetimes { self.resolve_elided_lifetimes(&lifetimes); } else { @@ -2171,7 +2528,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Binder { s, .. } | Scope::Elision { s, .. } - | Scope::ObjectLifetimeDefault { s, .. } => { + | Scope::ObjectLifetimeDefault { s, .. } + | Scope::TraitRefHackInner { s, .. } + | Scope::Supertrait { s, .. } => { scope = s; } } @@ -2271,15 +2630,50 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_))); // Resolve lifetimes found in the type `XX` from `Item = XX` bindings. - for b in generic_args.bindings { + for binding in generic_args.bindings { let scope = Scope::ObjectLifetimeDefault { lifetime: if has_lifetime_parameter { None } else { Some(Region::Static) }, s: self.scope, }; - self.with(scope, |_, this| this.visit_assoc_type_binding(b)); + if let Some(type_def_id) = type_def_id { + let lifetimes = + LifetimeContext::supertrait_bounds(self.tcx, type_def_id, binding.ident); + if let Some(lifetimes) = lifetimes { + self.with(scope, |_, this| { + let scope = Scope::Supertrait { lifetimes, s: this.scope }; + this.with(scope, |_, this| this.visit_assoc_type_binding(binding)); + }); + } else { + self.with(scope, |_, this| this.visit_assoc_type_binding(binding)); + } + } else { + self.with(scope, |_, this| this.visit_assoc_type_binding(binding)); + } } } + fn trait_defines_associated_type_named( + tcx: TyCtxt<'tcx>, + trait_def_id: DefId, + assoc_name: Ident, + ) -> bool { + tcx.associated_items(trait_def_id) + .find_by_name_and_kind(tcx, assoc_name, ty::AssocKind::Type, trait_def_id) + .is_some() + } + + fn supertrait_bounds( + tcx: TyCtxt<'tcx>, + def_id: DefId, + assoc_name: Ident, + ) -> Option> { + let all_candidates = super::supertraits::supertraits(tcx, def_id); + let mut matching_candidates = all_candidates + .filter(|r| LifetimeContext::trait_defines_associated_type_named(tcx, r.0, assoc_name)); + + matching_candidates.next().map(|c| c.1.into_iter().collect()) + } + #[tracing::instrument(level = "debug", skip(self))] fn visit_fn_like_elision( &mut self, @@ -2287,11 +2681,29 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { output: Option<&'tcx hir::Ty<'tcx>>, ) { debug!("visit_fn_like_elision: enter"); - let named_late_bound_vars = match *self.scope { - Scope::Binder { named_late_bound_vars, .. } => named_late_bound_vars, - Scope::Body { .. } => 0, - _ => bug!("{:?}", self.scope), + let mut scope = &*self.scope; + let (hir_id, named_late_bound_vars) = loop { + match scope { + Scope::Binder { hir_id, named_late_bound_vars, .. } + | Scope::TraitRefHackInner { hir_id, named_late_bound_vars, .. } => { + break (*hir_id, *named_late_bound_vars); + } + Scope::Body { id, .. } => break (id.hir_id, 0), + Scope::ObjectLifetimeDefault { ref s, .. } + | Scope::Elision { ref s, .. } + | Scope::Supertrait { ref s, .. } => { + scope = *s; + } + Scope::Root => bug!("In fn_like_elision without appropriate scope above"), + } }; + let mut gather = GatherAnonLifetimes { anon_count: 0 }; + for input in inputs { + gather.visit_ty(input); + } + self.map.late_bound_vars.entry(hir_id).or_default().extend( + (0..gather.anon_count).map(|var| ty::BoundVariableKind::Region(ty::BrAnon(var))), + ); let arg_scope = Scope::Elision { elide: Elide::FreshLateAnon(named_late_bound_vars, Cell::new(0)), s: self.scope, @@ -2563,6 +2975,41 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } } + + struct GatherAnonLifetimes { + anon_count: u32, + } + impl<'v> Visitor<'v> for GatherAnonLifetimes { + type Map = intravisit::ErasedMap<'v>; + + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::None + } + + fn visit_ty(&mut self, ty: &hir::Ty<'_>) { + if let hir::TyKind::BareFn(_) = ty.kind { + return; + } + intravisit::walk_ty(self, ty); + } + + fn visit_generic_args( + &mut self, + path_span: Span, + generic_args: &'v hir::GenericArgs<'v>, + ) { + if generic_args.parenthesized { + return; + } + intravisit::walk_generic_args(self, path_span, generic_args) + } + + fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) { + if lifetime_ref.is_elided() { + self.anon_count += 1; + } + } + } } fn resolve_elided_lifetimes(&mut self, lifetime_refs: &[&'tcx hir::Lifetime]) { @@ -2574,6 +3021,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let span = lifetime_refs[0].span; let mut late_depth = 0; + let mut in_poly_trait_ref = false; let mut scope = self.scope; let mut lifetime_names = FxHashSet::default(); let mut lifetime_spans = vec![]; @@ -2584,7 +3032,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Root => break None, - Scope::Binder { s, ref lifetimes, .. } => { + Scope::Binder { s, ref lifetimes, from_poly_trait_ref, .. } => { // collect named lifetimes for suggestions for name in lifetimes.keys() { if let hir::ParamName::Plain(name) = name { @@ -2592,7 +3040,21 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { lifetime_spans.push(name.span); } } - late_depth += 1; + // See comments in `resolve_lifetime_ref` + match (from_poly_trait_ref, in_poly_trait_ref) { + (true, false) => { + in_poly_trait_ref = true; + late_depth += 1; + } + (true, true) => {} + (false, true) => { + in_poly_trait_ref = false; + late_depth += 1; + } + (false, false) => { + late_depth += 1; + } + } scope = s; } @@ -2602,6 +3064,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { for lifetime_ref in lifetime_refs { let lifetime = Region::late_anon(named_late_bound_vars, counter) .shifted(late_depth); + self.insert_lifetime(lifetime_ref, lifetime); } return; @@ -2638,7 +3101,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { return; } - Scope::ObjectLifetimeDefault { s, .. } => { + Scope::ObjectLifetimeDefault { s, .. } + | Scope::TraitRefHackInner { s, .. } + | Scope::Supertrait { s, .. } => { scope = s; } } @@ -2744,11 +3209,25 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { fn resolve_object_lifetime_default(&mut self, lifetime_ref: &'tcx hir::Lifetime) { debug!("resolve_object_lifetime_default(lifetime_ref={:?})", lifetime_ref); let mut late_depth = 0; + let mut in_poly_trait_ref = false; let mut scope = self.scope; let lifetime = loop { match *scope { - Scope::Binder { s, .. } => { - late_depth += 1; + Scope::Binder { s, from_poly_trait_ref, .. } => { + match (from_poly_trait_ref, in_poly_trait_ref) { + (true, false) => { + in_poly_trait_ref = true; + late_depth += 1; + } + (true, true) => {} + (false, true) => { + in_poly_trait_ref = false; + late_depth += 1; + } + (false, false) => { + late_depth += 1; + } + } scope = s; } @@ -2757,6 +3236,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Body { .. } | Scope::ObjectLifetimeDefault { lifetime: None, .. } => return, Scope::ObjectLifetimeDefault { lifetime: Some(l), .. } => break l, + + Scope::TraitRefHackInner { s, .. } | Scope::Supertrait { s, .. } => { + scope = s; + } } }; self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth)); @@ -2880,7 +3363,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { match *old_scope { Scope::Body { s, .. } | Scope::Elision { s, .. } - | Scope::ObjectLifetimeDefault { s, .. } => { + | Scope::ObjectLifetimeDefault { s, .. } + | Scope::TraitRefHackInner { s, .. } + | Scope::Supertrait { s, .. } => { old_scope = s; } @@ -2926,7 +3411,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // A lifetime only used in a fn argument could as well // be replaced with `'_`, as that would generate a // fresh name, too. - Scope::Elision { elide: Elide::FreshLateAnon(_, _), .. } => break true, + Scope::Elision { elide: Elide::FreshLateAnon(..), .. } => break true, // In the return type or other such place, `'_` is not // going to make a fresh name, so we cannot @@ -2936,7 +3421,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { elide: Elide::Exact(_) | Elide::Error(_) | Elide::Forbid, .. } => break false, - Scope::ObjectLifetimeDefault { s, .. } => scope = s, + Scope::ObjectLifetimeDefault { s, .. } + | Scope::TraitRefHackInner { s, .. } + | Scope::Supertrait { s, .. } => scope = s, } } } diff --git a/compiler/rustc_resolve/src/late/supertraits.rs b/compiler/rustc_resolve/src/late/supertraits.rs new file mode 100644 index 00000000000..2130c33bd77 --- /dev/null +++ b/compiler/rustc_resolve/src/late/supertraits.rs @@ -0,0 +1,60 @@ +use smallvec::{smallvec, SmallVec}; + +use rustc_data_structures::fx::FxHashSet; +use rustc_hir::def_id::DefId; +use rustc_middle::ty::{self, TyCtxt}; + +pub struct Elaborator<'tcx> { + tcx: TyCtxt<'tcx>, + stack: SmallVec<[(DefId, SmallVec<[ty::BoundVariableKind; 8]>); 8]>, + visited: FxHashSet, +} + +#[allow(dead_code)] +pub fn supertraits<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Elaborator<'tcx> { + Elaborator { tcx, stack: smallvec![(def_id, smallvec![])], visited: Default::default() } +} + +impl<'tcx> Elaborator<'tcx> { + fn elaborate(&mut self, def_id: DefId, bound_vars: &SmallVec<[ty::BoundVariableKind; 8]>) { + let tcx = self.tcx; + + let predicates = tcx.super_predicates_of(def_id); + let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| { + let bound_predicate = pred.kind(); + match bound_predicate.skip_binder() { + ty::PredicateKind::Trait(data, _) => { + // The order here needs to match what we would get from `subst_supertrait` + let pred_bound_vars = bound_predicate.bound_vars(); + let mut all_bound_vars = bound_vars.clone(); + all_bound_vars.extend(pred_bound_vars.iter()); + let super_def_id = data.trait_ref.def_id; + Some((super_def_id, all_bound_vars)) + } + _ => None, + } + }); + + let visited = &mut self.visited; + let obligations = obligations.filter(|o| visited.insert(o.0)); + self.stack.extend(obligations); + } +} + +impl<'tcx> Iterator for Elaborator<'tcx> { + type Item = (DefId, SmallVec<[ty::BoundVariableKind; 8]>); + + fn size_hint(&self) -> (usize, Option) { + (self.stack.len(), None) + } + + fn next(&mut self) -> Option { + match self.stack.pop() { + Some((def_id, bound_vars)) => { + self.elaborate(def_id, &bound_vars); + Some((def_id, bound_vars)) + } + None => None, + } + } +} diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 0bb5dd117a0..37a834043f6 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -318,7 +318,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { // Late-bound lifetimes use indices starting at 1, // see `BinderLevel` for more details. - ty::ReLateBound(debruijn, ty::BoundRegion { kind: ty::BrAnon(i) }) => { + ty::ReLateBound(debruijn, ty::BoundRegion { kind: ty::BrAnon(i), .. }) => { let binder = &self.binders[self.binders.len() - 1 - debruijn.index()]; let depth = binder.lifetime_depths.start + i; diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 5c0cb2fb835..8c97e606c56 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -735,7 +735,10 @@ fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> { .into(), ty::GenericParamDefKind::Lifetime => { - let br = ty::BoundRegion { kind: ty::BrAnon(substs.len() as u32) }; + let br = ty::BoundRegion { + var: ty::BoundVar::from_usize(substs.len()), + kind: ty::BrAnon(substs.len() as u32), + }; tcx.mk_region(ty::RegionKind::ReLateBound(ty::INNERMOST, br)).into() } diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index f9de41ee893..39890fd5b05 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -434,17 +434,11 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t ReEarlyBound(_) => { panic!("Should have already been substituted."); } - ReLateBound(db, br) => match br.kind { - ty::BoundRegionKind::BrAnon(var) => { - chalk_ir::LifetimeData::BoundVar(chalk_ir::BoundVar::new( - chalk_ir::DebruijnIndex::new(db.as_u32()), - var as usize, - )) - .intern(interner) - } - ty::BoundRegionKind::BrNamed(_def_id, _name) => unimplemented!(), - ty::BrEnv => unimplemented!(), - }, + ReLateBound(db, br) => chalk_ir::LifetimeData::BoundVar(chalk_ir::BoundVar::new( + chalk_ir::DebruijnIndex::new(db.as_u32()), + br.var.as_usize(), + )) + .intern(interner), ReFree(_) => unimplemented!(), ReStatic => chalk_ir::LifetimeData::Static.intern(interner), ReVar(_) => unimplemented!(), @@ -467,7 +461,10 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime ty::RegionKind::ReLateBound( ty::DebruijnIndex::from_u32(var.debruijn.depth()), - ty::BoundRegion { kind: ty::BrAnon(var.index as u32) }, + ty::BoundRegion { + var: ty::BoundVar::from_usize(var.index), + kind: ty::BrAnon(var.index as u32), + }, ), chalk_ir::LifetimeData::InferenceVar(_var) => unimplemented!(), chalk_ir::LifetimeData::Placeholder(p) => { @@ -900,7 +897,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { }, }, - ty::BrEnv => unimplemented!(), + ty::BoundRegionKind::BrEnv => unimplemented!(), }, ty::ReEarlyBound(_re) => { @@ -948,7 +945,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> { ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind { ty::BrNamed(def_id, _name) => match self.named_parameters.get(&def_id) { Some(idx) => { - let new_br = ty::BoundRegion { kind: ty::BrAnon(*idx) }; + let new_br = ty::BoundRegion { var: br.var, kind: ty::BrAnon(*idx) }; return self.tcx.mk_region(RegionKind::ReLateBound(*index, new_br)); } None => panic!("Missing `BrNamed`."), @@ -1031,12 +1028,16 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { // This covers any region variables in a goal, right? ty::ReEarlyBound(_re) => match self.named_regions.get(&_re.def_id) { Some(idx) => { - let br = ty::BoundRegion { kind: ty::BrAnon(*idx) }; + let br = ty::BoundRegion { + var: ty::BoundVar::from_u32(*idx), + kind: ty::BrAnon(*idx), + }; self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br)) } None => { let idx = self.named_regions.len() as u32; - let br = ty::BoundRegion { kind: ty::BrAnon(idx) }; + let br = + ty::BoundRegion { var: ty::BoundVar::from_u32(idx), kind: ty::BrAnon(idx) }; self.named_regions.insert(_re.def_id, idx); self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br)) } diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 9625211109d..845375f3e32 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -166,7 +166,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { parent_substs: &[subst::GenericArg<'tcx>], has_self: bool, self_ty: Option>, - arg_count: GenericArgCountResult, + arg_count: &GenericArgCountResult, ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>, ) -> SubstsRef<'tcx> { // Collect the segments of the path; we need to substitute arguments diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 711466e774d..8d55bc8f2f3 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -210,14 +210,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let r = match tcx.named_region(lifetime.hir_id) { Some(rl::Region::Static) => tcx.lifetimes.re_static, - Some(rl::Region::LateBound(debruijn, _, id, _)) => { - let name = lifetime_name(id.expect_local()); - let br = ty::BoundRegion { kind: ty::BrNamed(id, name) }; + Some(rl::Region::LateBound(debruijn, index, def_id, _)) => { + let name = lifetime_name(def_id.expect_local()); + let br = ty::BoundRegion { + var: ty::BoundVar::from_u32(index), + kind: ty::BrNamed(def_id, name), + }; tcx.mk_region(ty::ReLateBound(debruijn, br)) } - Some(rl::Region::LateBoundAnon(debruijn, _index, anon_index)) => { - let br = ty::BoundRegion { kind: ty::BrAnon(anon_index) }; + Some(rl::Region::LateBoundAnon(debruijn, index, anon_index)) => { + let br = ty::BoundRegion { + var: ty::BoundVar::from_u32(index), + kind: ty::BrAnon(anon_index), + }; tcx.mk_region(ty::ReLateBound(debruijn, br)) } @@ -266,7 +272,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { def_id: DefId, item_segment: &hir::PathSegment<'_>, ) -> SubstsRef<'tcx> { - let (substs, assoc_bindings, _) = self.create_substs_for_ast_path( + let (substs, _) = self.create_substs_for_ast_path( span, def_id, &[], @@ -275,6 +281,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment.infer_args, None, ); + let assoc_bindings = self.create_assoc_bindings_for_generic_args(item_segment.args()); if let Some(b) = assoc_bindings.first() { Self::prohibit_assoc_ty_binding(self.tcx(), b.span); @@ -314,6 +321,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// `[Vec, u8]` and `generic_args` are the arguments for the associated /// type itself: `['a]`. The returned `SubstsRef` concatenates these two /// lists: `[Vec, u8, 'a]`. + #[tracing::instrument(level = "debug", skip(self, span))] fn create_substs_for_ast_path<'a>( &self, span: Span, @@ -323,15 +331,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { generic_args: &'a hir::GenericArgs<'_>, infer_args: bool, self_ty: Option>, - ) -> (SubstsRef<'tcx>, Vec>, GenericArgCountResult) { + ) -> (SubstsRef<'tcx>, GenericArgCountResult) { // If the type is parameterized by this region, then replace this // region with the current anon region binding (in other words, // whatever & would get replaced with). - debug!( - "create_substs_for_ast_path(def_id={:?}, self_ty={:?}, \ - generic_args={:?})", - def_id, self_ty, generic_args - ); let tcx = self.tcx(); let generics = tcx.generics_of(def_id); @@ -367,7 +370,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // here and so associated type bindings will be handled regardless of whether there are any // non-`Self` generic parameters. if generics.params.len() == 0 { - return (tcx.intern_substs(&[]), vec![], arg_count); + return (tcx.intern_substs(&[]), arg_count); } let is_object = self_ty.map_or(false, |ty| ty == self.tcx().types.trait_object_dummy_self); @@ -540,7 +543,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { parent_substs, self_ty.is_some(), self_ty, - arg_count.clone(), + &arg_count, &mut substs_ctx, ); @@ -551,6 +554,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { generic_args.args.is_empty(), ); + debug!( + "create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}", + generics, self_ty, substs + ); + + (substs, arg_count) + } + + fn create_assoc_bindings_for_generic_args<'a>( + &self, + generic_args: &'a hir::GenericArgs<'_>, + ) -> Vec> { // Convert associated-type bindings or constraints into a separate vector. // Example: Given this: // @@ -581,12 +596,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }) .collect(); - debug!( - "create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}", - generics, self_ty, substs - ); - - (substs, assoc_bindings, arg_count) + assoc_bindings } crate fn create_substs_for_associated_item( @@ -636,55 +646,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) } - /// The given trait-ref must actually be a trait. - pub(super) fn instantiate_poly_trait_ref_inner( - &self, - trait_ref: &hir::TraitRef<'_>, - span: Span, - constness: Constness, - self_ty: Ty<'tcx>, - bounds: &mut Bounds<'tcx>, - speculative: bool, - ) -> GenericArgCountResult { - let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()); - - debug!("instantiate_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id); - - self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1); - - let (substs, assoc_bindings, arg_count) = self.create_substs_for_ast_trait_ref( - trait_ref.path.span, - trait_def_id, - self_ty, - trait_ref.path.segments.last().unwrap(), - ); - let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs), self.tcx()); - - bounds.trait_bounds.push((poly_trait_ref, span, constness)); - - let mut dup_bindings = FxHashMap::default(); - for binding in &assoc_bindings { - // Specify type to assert that error was already reported in `Err` case. - let _: Result<_, ErrorReported> = self.add_predicates_for_ast_type_binding( - trait_ref.hir_ref_id, - poly_trait_ref, - binding, - bounds, - speculative, - &mut dup_bindings, - binding.span, - ); - // Okay to ignore `Err` because of `ErrorReported` (see above). - } - - debug!( - "instantiate_poly_trait_ref({:?}, bounds={:?}) -> {:?}", - trait_ref, bounds, poly_trait_ref - ); - - arg_count - } - /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct /// a full trait reference. The resulting trait reference is returned. This may also generate /// auxiliary bounds, which are added to `bounds`. @@ -704,21 +665,55 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly, /// however. + #[tracing::instrument(level = "debug", skip(self, span, constness, bounds, speculative))] pub fn instantiate_poly_trait_ref( &self, - poly_trait_ref: &hir::PolyTraitRef<'_>, + trait_ref: &hir::TraitRef<'_>, + span: Span, constness: Constness, self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, + speculative: bool, ) -> GenericArgCountResult { - self.instantiate_poly_trait_ref_inner( - &poly_trait_ref.trait_ref, - poly_trait_ref.span, - constness, + let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()); + + self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1); + + let tcx = self.tcx(); + let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id); + debug!(?bound_vars); + + let (substs, arg_count) = self.create_substs_for_ast_trait_ref( + trait_ref.path.span, + trait_def_id, self_ty, - bounds, - false, - ) + trait_ref.path.segments.last().unwrap(), + ); + let assoc_bindings = self + .create_assoc_bindings_for_generic_args(trait_ref.path.segments.last().unwrap().args()); + + let poly_trait_ref = + ty::Binder::bind_with_vars(ty::TraitRef::new(trait_def_id, substs), bound_vars); + + debug!(?poly_trait_ref, ?assoc_bindings); + bounds.trait_bounds.push((poly_trait_ref, span, constness)); + + let mut dup_bindings = FxHashMap::default(); + for binding in &assoc_bindings { + // Specify type to assert that error was already reported in `Err` case. + let _: Result<_, ErrorReported> = self.add_predicates_for_ast_type_binding( + trait_ref.hir_ref_id, + poly_trait_ref, + binding, + bounds, + speculative, + &mut dup_bindings, + binding.span, + ); + // Okay to ignore `Err` because of `ErrorReported` (see above). + } + + arg_count } pub fn instantiate_lang_item_trait_ref( @@ -732,7 +727,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) { let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span)); - let (substs, assoc_bindings, _) = self.create_substs_for_ast_path( + let (substs, _) = self.create_substs_for_ast_path( span, trait_def_id, &[], @@ -741,7 +736,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { false, Some(self_ty), ); - let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs), self.tcx()); + let assoc_bindings = self.create_assoc_bindings_for_generic_args(args); + let tcx = self.tcx(); + let bound_vars = tcx.late_bound_vars(hir_id); + let poly_trait_ref = + ty::Binder::bind_with_vars(ty::TraitRef::new(trait_def_id, substs), bound_vars); bounds.trait_bounds.push((poly_trait_ref, span, Constness::NotConst)); let mut dup_bindings = FxHashMap::default(); @@ -765,23 +764,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty: Ty<'tcx>, trait_segment: &hir::PathSegment<'_>, ) -> ty::TraitRef<'tcx> { - let (substs, assoc_bindings, _) = + let (substs, _) = self.create_substs_for_ast_trait_ref(span, trait_def_id, self_ty, trait_segment); + let assoc_bindings = self.create_assoc_bindings_for_generic_args(trait_segment.args()); if let Some(b) = assoc_bindings.first() { Self::prohibit_assoc_ty_binding(self.tcx(), b.span); } ty::TraitRef::new(trait_def_id, substs) } + #[tracing::instrument(level = "debug", skip(self, span))] fn create_substs_for_ast_trait_ref<'a>( &self, span: Span, trait_def_id: DefId, self_ty: Ty<'tcx>, trait_segment: &'a hir::PathSegment<'a>, - ) -> (SubstsRef<'tcx>, Vec>, GenericArgCountResult) { - debug!("create_substs_for_ast_trait_ref(trait_segment={:?})", trait_segment); - + ) -> (SubstsRef<'tcx>, GenericArgCountResult) { self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment); self.create_substs_for_ast_path( @@ -803,7 +802,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } // Returns `true` if a bounds list includes `?Sized`. - pub fn is_unsized(&self, ast_bounds: &[&hir::GenericBound<'_>], span: Span) -> bool { + pub fn is_unsized(&self, ast_bounds: &[hir::GenericBound<'_>], span: Span) -> bool { let tcx = self.tcx(); // Try to find an unbound in bounds. @@ -858,28 +857,44 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// **A note on binders:** there is an implied binder around /// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref` /// for more details. + #[tracing::instrument(level = "debug", skip(self, bounds))] fn add_bounds( &self, param_ty: Ty<'tcx>, - ast_bounds: &[&hir::GenericBound<'_>], + ast_bounds: &[hir::GenericBound<'_>], bounds: &mut Bounds<'tcx>, + bound_vars: &'tcx ty::List, ) { let constness = self.default_constness_for_trait_bounds(); for ast_bound in ast_bounds { match *ast_bound { hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => { - self.instantiate_poly_trait_ref(b, constness, param_ty, bounds); + self.instantiate_poly_trait_ref( + &b.trait_ref, + b.span, + constness, + param_ty, + bounds, + false, + ); } hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::MaybeConst) => { - self.instantiate_poly_trait_ref(b, Constness::NotConst, param_ty, bounds); + self.instantiate_poly_trait_ref( + &b.trait_ref, + b.span, + Constness::NotConst, + param_ty, + bounds, + false, + ); } hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {} hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => self .instantiate_lang_item_trait_ref( - *lang_item, *span, *hir_id, args, param_ty, bounds, + lang_item, span, hir_id, args, param_ty, bounds, ), hir::GenericBound::Outlives(ref l) => bounds.region_bounds.push(( - ty::Binder::bind(self.ast_region_to_region(l, None), self.tcx()), + ty::Binder::bind_with_vars(self.ast_region_to_region(l, None), bound_vars), l.span, )), } @@ -909,7 +924,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { sized_by_default: SizedByDefault, span: Span, ) -> Bounds<'tcx> { - let ast_bounds: Vec<_> = ast_bounds.iter().collect(); self.compute_bounds_inner(param_ty, &ast_bounds, sized_by_default, span) } @@ -929,7 +943,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Some(trait_ref) = ast_bound.trait_ref() { if let Some(trait_did) = trait_ref.trait_def_id() { if self.tcx().trait_may_define_assoc_type(trait_did, assoc_name) { - result.push(ast_bound); + result.push(ast_bound.clone()); } } } @@ -941,13 +955,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { fn compute_bounds_inner( &self, param_ty: Ty<'tcx>, - ast_bounds: &[&hir::GenericBound<'_>], + ast_bounds: &[hir::GenericBound<'_>], sized_by_default: SizedByDefault, span: Span, ) -> Bounds<'tcx> { let mut bounds = Bounds::default(); - self.add_bounds(param_ty, ast_bounds, &mut bounds); + self.add_bounds(param_ty, ast_bounds, &mut bounds, ty::List::empty()); bounds.implicitly_sized = if let SizedByDefault::Yes = sized_by_default { if !self.is_unsized(ast_bounds, span) { Some(span) } else { None } @@ -964,6 +978,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// **A note on binders:** given something like `T: for<'a> Iterator`, the /// `trait_ref` here will be `for<'a> T: Iterator`. The `binding` data however is from *inside* /// the binder (e.g., `&'a u32`) and hence may reference bound regions. + #[tracing::instrument( + level = "debug", + skip(self, bounds, speculative, dup_bindings, path_span) + )] fn add_predicates_for_ast_type_binding( &self, hir_ref_id: hir::HirId, @@ -990,7 +1008,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // // We want to produce `>::T == foo`. - debug!(?hir_ref_id, ?trait_ref, ?binding, ?bounds, "add_predicates_for_ast_type_binding",); let tcx = self.tcx(); let candidate = @@ -1140,10 +1157,8 @@ 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_projection(assoc_ty.def_id, projection_ty.skip_binder().substs); - let ast_bounds: Vec<_> = ast_bounds.iter().collect(); - self.add_bounds(param_ty, &ast_bounds, bounds); + let param_ty = tcx.mk_ty(ty::Projection(projection_ty.skip_binder())); + self.add_bounds(param_ty, ast_bounds, bounds, candidate.bound_vars()); } } Ok(()) @@ -1177,10 +1192,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }), .. } = self.instantiate_poly_trait_ref( - trait_bound, + &trait_bound.trait_ref, + trait_bound.span, Constness::NotConst, dummy_self, &mut bounds, + false, ) { potential_assoc_types.extend(cur_potential_assoc_types); } @@ -2169,12 +2186,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } - /// Parses the programmer's textual representation of a type into our - /// internal notion of a type. pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> { self.ast_ty_to_ty_inner(ast_ty, false) } + /// Parses the programmer's textual representation of a type into our + /// internal notion of a type. + /// /// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait /// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors. #[tracing::instrument(level = "debug", skip(self))] @@ -2200,6 +2218,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { require_c_abi_if_c_variadic(tcx, &bf.decl, bf.abi, ast_ty.span); tcx.mk_fn_ptr(self.ty_of_fn( + ast_ty.hir_id, bf.unsafety, bf.abi, &bf.decl, @@ -2242,7 +2261,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => { let def_id = tcx.require_lang_item(lang_item, Some(span)); - let (substs, _, _) = self.create_substs_for_ast_path( + let (substs, _) = self.create_substs_for_ast_path( span, def_id, &[], @@ -2279,7 +2298,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { result_ty } - pub fn impl_trait_ty_to_ty( + fn impl_trait_ty_to_ty( &self, def_id: DefId, lifetimes: &[hir::GenericArg<'_>], @@ -2340,6 +2359,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { pub fn ty_of_fn( &self, + hir_id: hir::HirId, unsafety: hir::Unsafety, abi: abi::Abi, decl: &hir::FnDecl<'_>, @@ -2350,6 +2370,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!("ty_of_fn"); let tcx = self.tcx(); + let bound_vars = tcx.late_bound_vars(hir_id); + debug!(?bound_vars); // We proactively collect all the inferred type params to emit a single error per fn def. let mut visitor = PlaceholderHirTyCollector::default(); @@ -2369,10 +2391,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!("ty_of_fn: output_ty={:?}", output_ty); - let bare_fn_ty = ty::Binder::bind( - tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi), - tcx, - ); + let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi); + let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars); if !self.allow_ty_infer() { // We always collect the spans for placeholder types when evaluating `fn`s, but we diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs index 2f30621b019..22d3dc6bdc0 100644 --- a/compiler/rustc_typeck/src/check/closure.rs +++ b/compiler/rustc_typeck/src/check/closure.rs @@ -69,7 +69,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expr_def_id = self.tcx.hir().local_def_id(expr.hir_id); let ClosureSignatures { bound_sig, liberated_sig } = - self.sig_of_closure(expr_def_id.to_def_id(), decl, body, expected_sig); + self.sig_of_closure(expr.hir_id, expr_def_id.to_def_id(), decl, body, expected_sig); debug!("check_closure: ty_of_closure returns {:?}", liberated_sig); @@ -288,15 +288,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn sig_of_closure( &self, + hir_id: hir::HirId, expr_def_id: DefId, decl: &hir::FnDecl<'_>, body: &hir::Body<'_>, expected_sig: Option>, ) -> ClosureSignatures<'tcx> { if let Some(e) = expected_sig { - self.sig_of_closure_with_expectation(expr_def_id, decl, body, e) + self.sig_of_closure_with_expectation(hir_id, expr_def_id, decl, body, e) } else { - self.sig_of_closure_no_expectation(expr_def_id, decl, body) + self.sig_of_closure_no_expectation(hir_id, expr_def_id, decl, body) } } @@ -304,13 +305,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// types that the user gave into a signature. fn sig_of_closure_no_expectation( &self, + hir_id: hir::HirId, expr_def_id: DefId, decl: &hir::FnDecl<'_>, body: &hir::Body<'_>, ) -> ClosureSignatures<'tcx> { debug!("sig_of_closure_no_expectation()"); - let bound_sig = self.supplied_sig_of_closure(expr_def_id, decl, body); + let bound_sig = self.supplied_sig_of_closure(hir_id, expr_def_id, decl, body); self.closure_sigs(expr_def_id, body, bound_sig) } @@ -364,6 +366,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// regions with depth 1, which are bound then by the closure. fn sig_of_closure_with_expectation( &self, + hir_id: hir::HirId, expr_def_id: DefId, decl: &hir::FnDecl<'_>, body: &hir::Body<'_>, @@ -375,7 +378,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // expectation if things don't see to match up with what we // expect. if expected_sig.sig.c_variadic() != decl.c_variadic { - return self.sig_of_closure_no_expectation(expr_def_id, decl, body); + return self.sig_of_closure_no_expectation(hir_id, expr_def_id, decl, body); } else if expected_sig.sig.skip_binder().inputs_and_output.len() != decl.inputs.len() + 1 { return self.sig_of_closure_with_mismatched_number_of_arguments( expr_def_id, @@ -411,9 +414,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Along the way, it also writes out entries for types that the user // wrote into our typeck results, which are then later used by the privacy // check. - match self.check_supplied_sig_against_expectation(expr_def_id, decl, body, &closure_sigs) { + match self.check_supplied_sig_against_expectation( + hir_id, + expr_def_id, + decl, + body, + &closure_sigs, + ) { Ok(infer_ok) => self.register_infer_ok_obligations(infer_ok), - Err(_) => return self.sig_of_closure_no_expectation(expr_def_id, decl, body), + Err(_) => return self.sig_of_closure_no_expectation(hir_id, expr_def_id, decl, body), } closure_sigs @@ -460,6 +469,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// strategy. fn check_supplied_sig_against_expectation( &self, + hir_id: hir::HirId, expr_def_id: DefId, decl: &hir::FnDecl<'_>, body: &hir::Body<'_>, @@ -469,7 +479,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // (See comment on `sig_of_closure_with_expectation` for the // meaning of these letters.) - let supplied_sig = self.supplied_sig_of_closure(expr_def_id, decl, body); + let supplied_sig = self.supplied_sig_of_closure(hir_id, expr_def_id, decl, body); debug!("check_supplied_sig_against_expectation: supplied_sig={:?}", supplied_sig); @@ -534,6 +544,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Also, record this closure signature for later. fn supplied_sig_of_closure( &self, + hir_id: hir::HirId, expr_def_id: DefId, decl: &hir::FnDecl<'_>, body: &hir::Body<'_>, @@ -545,6 +556,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { decl, body.generator_kind, ); + let bound_vars = self.tcx.late_bound_vars(hir_id); + // First, convert the types that the user supplied (if any). let supplied_arguments = decl.inputs.iter().map(|a| astconv.ast_ty_to_ty(a)); let supplied_return = match decl.output { @@ -571,7 +584,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, }; - let result = ty::Binder::bind( + let result = ty::Binder::bind_with_vars( self.tcx.mk_fn_sig( supplied_arguments, supplied_return, @@ -579,7 +592,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::Unsafety::Normal, Abi::RustCall, ), - self.tcx, + bound_vars, ); debug!("supplied_sig_of_closure: result={:?}", result); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index a7a412f06be..9ace4550421 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1462,7 +1462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &[][..], has_self, self_ty, - arg_count, + &arg_count, &mut CreateCtorSubstsContext { fcx: self, span, diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index 969359a3c21..e40aa914858 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -186,7 +186,10 @@ pub fn resolve_interior<'a, 'tcx>( // which means that none of the regions inside relate to any other, even if // typeck had previously found constraints that would cause them to be related. let folded = fcx.tcx.fold_regions(erased, &mut false, |_, current_depth| { - let br = ty::BoundRegion { kind: ty::BrAnon(counter) }; + let br = ty::BoundRegion { + var: ty::BoundVar::from_u32(counter), + kind: ty::BrAnon(counter), + }; let r = fcx.tcx.mk_region(ty::ReLateBound(current_depth, br)); counter += 1; r @@ -202,11 +205,15 @@ pub fn resolve_interior<'a, 'tcx>( // Extract type components to build the witness type. let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty)); - let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list, fcx.tcx)); + let bound_vars = fcx.tcx.mk_bound_variable_kinds( + (0..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i))), + ); + let witness = + fcx.tcx.mk_generator_witness(ty::Binder::bind_with_vars(type_list, bound_vars.clone())); // Store the generator types and spans into the typeck results for this generator. visitor.fcx.inh.typeck_results.borrow_mut().generator_interior_types = - ty::Binder::bind(type_causes, fcx.tcx); + ty::Binder::bind_with_vars(type_causes, bound_vars); debug!( "types in generator after region replacement {:?}, span = {:?}", diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index 3b399b86718..303a77507cf 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -101,12 +101,21 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { let intrinsic_name = tcx.item_name(it.def_id.to_def_id()); let name_str = intrinsic_name.as_str(); + let bound_vars = tcx.mk_bound_variable_kinds( + [ty::BoundVariableKind::Region(ty::BrAnon(0)), ty::BoundVariableKind::Region(ty::BrEnv)] + .iter() + .copied(), + ); let mk_va_list_ty = |mutbl| { tcx.lang_items().va_list().map(|did| { - let region = tcx - .mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { kind: ty::BrAnon(0) })); - let env_region = - tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { kind: ty::BrEnv })); + let region = tcx.mk_region(ty::ReLateBound( + ty::INNERMOST, + ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) }, + )); + let env_region = tcx.mk_region(ty::ReLateBound( + ty::INNERMOST, + ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv }, + )); let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]); (tcx.mk_ref(env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty) }) @@ -305,7 +314,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap()); let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id; - let br = ty::BoundRegion { kind: ty::BrAnon(0) }; + let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) }; ( 1, vec![ @@ -366,7 +375,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { (n_tps, inputs, output, unsafety) }; let sig = tcx.mk_fn_sig(inputs.into_iter(), output, false, unsafety, Abi::RustIntrinsic); - let sig = ty::Binder::bind(sig, tcx); + let sig = ty::Binder::bind_with_vars(sig, bound_vars); equate_intrinsic_type(tcx, it, n_tps, sig) } diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index 900bd2885fd..f546a0d8963 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -381,7 +381,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { parent_substs, false, None, - arg_count_correct, + &arg_count_correct, &mut MethodSubstsCtxt { cfcx: self, pick, seg }, ) } diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index ad9bb703779..0760d59875c 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -497,6 +497,7 @@ fn typeck_with_fallback<'tcx>( let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id); >::ty_of_fn( &fcx, + id, header.unsafety, header.abi, decl, diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index ed4c0f8b828..afe52c97733 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1712,6 +1712,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { } None => >::ty_of_fn( &icx, + hir_id, sig.header.unsafety, sig.header.abi, &sig.decl, @@ -1729,6 +1730,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { .. }) => >::ty_of_fn( &icx, + hir_id, header.unsafety, header.abi, decl, @@ -2082,6 +2084,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP match predicate { hir::WherePredicate::BoundPredicate(bound_pred) => { let ty = icx.to_ty(&bound_pred.bounded_ty); + let bound_vars = icx.tcx.late_bound_vars(bound_pred.bounded_ty.hir_id); // Keep the type around in a dummy predicate, in case of no bounds. // That way, `where Ty:` is not a complete noop (see #53696) and `Ty` @@ -2097,12 +2100,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP } else { let span = bound_pred.bounded_ty.span; let re_root_empty = tcx.lifetimes.re_root_empty; - let predicate = ty::Binder::bind( + let predicate = ty::Binder::bind_with_vars( ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate( ty, re_root_empty, )), - tcx, + bound_vars, ); predicates.insert((predicate.to_predicate(tcx), span)); } @@ -2120,10 +2123,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP let mut bounds = Bounds::default(); let _ = >::instantiate_poly_trait_ref( &icx, - &poly_trait_ref, + &poly_trait_ref.trait_ref, + poly_trait_ref.span, constness, ty, &mut bounds, + false, ); predicates.extend(bounds.predicates(tcx, ty)); } @@ -2146,11 +2151,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP let region = >::ast_region_to_region(&icx, lifetime, None); predicates.insert(( - ty::Binder::bind( + ty::Binder::bind_with_vars( ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate( ty, region, )), - tcx, + bound_vars, ) .to_predicate(tcx), lifetime.span, @@ -2373,7 +2378,14 @@ fn predicates_from_bound<'tcx>( }; let mut bounds = Bounds::default(); - let _ = astconv.instantiate_poly_trait_ref(tr, constness, param_ty, &mut bounds); + let _ = astconv.instantiate_poly_trait_ref( + &tr.trait_ref, + tr.span, + constness, + param_ty, + &mut bounds, + false, + ); bounds.predicates(astconv.tcx(), param_ty) } hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => { @@ -2409,8 +2421,10 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( } else { hir::Unsafety::Unsafe }; + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); let fty = >::ty_of_fn( &ItemCtxt::new(tcx, def_id), + hir_id, unsafety, abi, decl, diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index cb442344fa2..4244d37232f 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -430,7 +430,7 @@ pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> { let env_node_id = tcx.hir().get_parent_item(hir_ty.hir_id); let env_def_id = tcx.hir().local_def_id(env_node_id); let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.to_def_id()); - item_cx.to_ty(hir_ty) + AstConv::ast_ty_to_ty(&item_cx, hir_ty) } pub fn hir_trait_to_predicates<'tcx>( @@ -445,7 +445,7 @@ pub fn hir_trait_to_predicates<'tcx>( let env_def_id = tcx.hir().local_def_id(env_hir_id); let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.to_def_id()); let mut bounds = Bounds::default(); - let _ = >::instantiate_poly_trait_ref_inner( + let _ = >::instantiate_poly_trait_ref( &item_cx, hir_trait, DUMMY_SP, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 58869296d09..217e899001e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -411,7 +411,7 @@ impl Clean> for ty::RegionKind { fn clean(&self, _cx: &mut DocContext<'_>) -> Option { match *self { ty::ReStatic => Some(Lifetime::statik()), - ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name) }) => { + ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) => { Some(Lifetime(name)) } ty::ReEarlyBound(ref data) => Some(Lifetime(data.name)), diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 32bac53e8f5..60cbe9f376f 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -97,7 +97,7 @@ fn external_generic_args( .iter() .filter_map(|kind| match kind.unpack() { GenericArgKind::Lifetime(lt) => match lt { - ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrAnon(_) }) => { + ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrAnon(_), .. }) => { Some(GenericArg::Lifetime(Lifetime::elided())) } _ => lt.clean(cx).map(GenericArg::Lifetime), diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs index ed67b2dcb04..c8530c70f78 100644 --- a/src/test/incremental/hashes/function_interfaces.rs +++ b/src/test/incremental/hashes/function_interfaces.rs @@ -118,7 +118,7 @@ pub fn type_parameter() {} pub fn lifetime_parameter() {} #[cfg(not(cfail1))] -#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, generics_of")] +#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, generics_of,fn_sig")] #[rustc_clean(cfg = "cfail3")] pub fn lifetime_parameter<'a>() {} @@ -150,7 +150,7 @@ pub fn lifetime_bound<'a, T>() {} #[cfg(not(cfail1))] #[rustc_clean( cfg = "cfail2", - except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of" + except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of,fn_sig" )] #[rustc_clean(cfg = "cfail3")] pub fn lifetime_bound<'a, T: 'a>() {} @@ -183,7 +183,7 @@ pub fn second_lifetime_bound<'a, 'b, T: 'a>() {} #[cfg(not(cfail1))] #[rustc_clean( cfg = "cfail2", - except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of" + except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of,fn_sig" )] #[rustc_clean(cfg = "cfail3")] pub fn second_lifetime_bound<'a, 'b, T: 'a + 'b>() {} diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs index ae8f2ace217..ee7b258cec4 100644 --- a/src/test/incremental/hashes/inherent_impls.rs +++ b/src/test/incremental/hashes/inherent_impls.rs @@ -312,7 +312,7 @@ impl Foo { // if we lower generics before the body, then the `HirId` for // things in the body will be affected. So if you start to see // `typeck` appear dirty, that might be the cause. -nmatsakis - #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")] + #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig")] #[rustc_clean(cfg="cfail3")] pub fn add_lifetime_parameter_to_method<'a>(&self) { } } @@ -360,7 +360,7 @@ impl Foo { impl Foo { #[rustc_clean( cfg="cfail2", - except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of" + except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of,fn_sig" )] #[rustc_clean(cfg="cfail3")] pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b: 'a>(&self) { } @@ -388,7 +388,7 @@ impl Foo { // body will be affected. So if you start to see `typeck` // appear dirty, that might be the cause. -nmatsakis #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,\ - type_of")] + type_of,fn_sig")] #[rustc_clean(cfg="cfail3")] pub fn add_lifetime_bound_to_type_param_of_method<'a, T: 'a>(&self) { } } diff --git a/src/test/ui/associated-type-bounds/hrtb.rs b/src/test/ui/associated-type-bounds/hrtb.rs new file mode 100644 index 00000000000..7ab3836493b --- /dev/null +++ b/src/test/ui/associated-type-bounds/hrtb.rs @@ -0,0 +1,65 @@ +// check-pass + +#![feature(associated_type_bounds)] + +trait A<'a> {} +trait B<'b> {} +fn foo() +where + for<'a> T: A<'a> + 'a, +{ +} +trait C<'c>: for<'a> A<'a> + for<'b> B<'b> { + type As; +} +struct D +where + T: for<'c> C<'c, As: A<'c>>, +{ + t: std::marker::PhantomData, +} + +trait E<'e> { + type As; +} +trait F<'f>: for<'a> A<'a> + for<'e> E<'e> {} +struct G +where + for<'f> T: F<'f, As: E<'f>> + 'f, +{ + t: std::marker::PhantomData, +} + +trait I<'a, 'b, 'c> { + type As; +} +trait H<'d, 'e>: for<'f> I<'d, 'f, 'e> + 'd {} +fn foo2() +where + T: for<'g> H<'g, 'g, As: for<'h> H<'h, 'g> + 'g>, +{ +} + +fn foo3() +where + T: for<'i> H<'i, 'i, As: for<'j> H<'j, 'i, As: for<'k> I<'i, 'k, 'j> + 'j> + 'i>, +{ +} +fn foo4() +where + T: for<'l, 'i> H<'l, 'i, As: for<'j> H<'j, 'i, As: for<'k> I<'l, 'k, 'j> + 'j> + 'i>, +{ +} + +struct X<'x, 'y> { + x: std::marker::PhantomData<&'x ()>, + y: std::marker::PhantomData<&'y ()>, +} + +fn foo5() +where + T: for<'l, 'i> H<'l, 'i, As: for<'j> H<'j, 'i, As: for<'k> H<'j, 'k, As = X<'j, 'k>> + 'j> + 'i> +{ +} + +fn main() {} diff --git a/src/test/ui/hrtb/complex.rs b/src/test/ui/hrtb/complex.rs index 0bcda8c01cd..8cdfe247e02 100644 --- a/src/test/ui/hrtb/complex.rs +++ b/src/test/ui/hrtb/complex.rs @@ -9,12 +9,20 @@ trait C<'c>: for<'a> A<'a> + for<'b> B<'b> { struct D where T: for<'c> C<'c, As=&'c ()> { t: std::marker::PhantomData, } -trait E<'e> { +trait E<'e, 'g> { type As; } -trait F<'f>: for<'a> A<'a> + for<'e> E<'e> {} +trait F<'f>: for<'a> A<'a> + for<'e> E<'e, 'f> {} struct G where T: for<'f> F<'f, As=&'f ()> { t: std::marker::PhantomData, } +trait H<'a, 'b> { + type As; +} +trait I<'a>: for<'b> H<'a, 'b> {} + +struct J where T: for<'i> I<'i, As=&'i ()> { + t: std::marker::PhantomData, +} fn main() {} diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr index 4e122d930fc..ff16bf0e078 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -6,7 +6,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); | = note: defining type: test::{closure#0} with closure substs [ i16, - for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) i32)), + for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('t0) }) i32)), (), ] diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr index 44d1d2327fc..22398f08572 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr @@ -6,7 +6,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); | = note: defining type: test::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32)), + for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) i32)), (), ] diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr index fa9f994c4fa..11420efaa06 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr @@ -10,7 +10,7 @@ LL | | }, | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)), + for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>)), (), ] = note: late-bound region is '_#4r diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr index 0555f79bcb0..98c3c28fb43 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -11,7 +11,7 @@ LL | | }); | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>)), + for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) u32>)), (), ] = note: late-bound region is '_#3r diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 0932f941548..30ef343b261 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -10,7 +10,7 @@ LL | | }) | = note: defining type: case1::{closure#0} with closure substs [ i32, - for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>)), + for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>)), (), ] @@ -49,7 +49,7 @@ LL | | }) | = note: defining type: case2::{closure#0} with closure substs [ i32, - for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>)), + for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>)), (), ] = note: number of external vids: 2 diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index bf6e2a922ed..29993b129c7 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -12,7 +12,7 @@ LL | | }); | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) u32>)), + for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('t2) }) u32>)), (), ] = note: late-bound region is '_#2r diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index a3d993848cb..cb505d8b1ec 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -12,7 +12,7 @@ LL | | }); | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>)), + for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('t0) }) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) u32>)), (), ] = note: late-bound region is '_#3r diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr index 60dca1baa40..2ec9d4d8db1 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr @@ -11,7 +11,7 @@ LL | | }); | = note: defining type: test::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)), + for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>)), (), ] = note: late-bound region is '_#3r diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr index cbb10eb187e..21e4232c788 100644 --- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr @@ -10,7 +10,7 @@ LL | | }, | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)), + for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>)), (), ] = note: late-bound region is '_#3r diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index f9f1d8bb6ff..8b9b0435420 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -11,7 +11,7 @@ LL | | }); | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)), + for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>)), (), ] = note: late-bound region is '_#2r diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index 1587c28e1be..060ce690f03 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -11,7 +11,7 @@ LL | | }); | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>)), + for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) u32>)), (), ] = note: late-bound region is '_#3r diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr index 44f743310b4..5fc1d5c4361 100644 --- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr +++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr @@ -6,7 +6,7 @@ LL | expect_sig(|a, b| b); // ought to return `a` | = note: defining type: test::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32)) -> &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) i32, + for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) i32)) -> &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) i32, (), ] diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr index dbf76cd1329..baf223b786b 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr @@ -6,7 +6,7 @@ LL | twice(cell, value, |a, b| invoke(a, b)); | = note: defining type: generic::::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((std::option::Option>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) T)), + for<'r, 's> extern "rust-call" fn((std::option::Option>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) T)), (), ] = note: number of external vids: 2 @@ -31,7 +31,7 @@ LL | twice(cell, value, |a, b| invoke(a, b)); | = note: defining type: generic_fail::::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((std::option::Option>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) T)), + for<'r, 's> extern "rust-call" fn((std::option::Option>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) T)), (), ] = note: late-bound region is '_#2r From 8ad7e5685ee38af0d1c62808c4eaf8301f3a0db8 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Thu, 11 Mar 2021 21:08:49 -0500 Subject: [PATCH 251/370] Fix new problem from rebase and a little cleanup --- compiler/rustc_middle/src/ty/fold.rs | 15 ++++++++------- compiler/rustc_typeck/src/check/coercion.rs | 2 +- .../rustc_typeck/src/check/fn_ctxt/suggestions.rs | 7 +++++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 368236b146f..819399141b9 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -820,7 +820,8 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { match r { ty::ReLateBound(index, _br) if *index == self.binder_index => { - bug!("{:?} {:?}", index, _br) + // If you hit this, you should be using `Binder::bind_with_vars` or `Binder::rebind` + bug!("Trying to collect bound vars with a bound region: {:?} {:?}", index, _br) } _ => (), @@ -870,19 +871,19 @@ impl<'tcx> TypeVisitor<'tcx> for ValidateBoundVars<'tcx> { match *t.kind() { ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => { if self.bound_vars.len() <= bound_ty.var.as_usize() { - panic!("Not enough bound vars: {:?} not found in {:?}", t, self.bound_vars); + bug!("Not enough bound vars: {:?} not found in {:?}", t, self.bound_vars); } let list_var = self.bound_vars[bound_ty.var.as_usize()]; match list_var { ty::BoundVariableKind::Ty(kind) => { if kind != bound_ty.kind { - panic!( + bug!( "Mismatched type kinds: {:?} doesn't var in list {:?}", bound_ty.kind, list_var ); } } - _ => panic!( + _ => bug!( "Mismatched bound variable kinds! Expected type, found {:?}", list_var ), @@ -899,19 +900,19 @@ impl<'tcx> TypeVisitor<'tcx> for ValidateBoundVars<'tcx> { match r { ty::ReLateBound(index, br) if *index == self.binder_index => { if self.bound_vars.len() <= br.var.as_usize() { - panic!("Not enough bound vars: {:?} not found in {:?}", *br, self.bound_vars); + bug!("Not enough bound vars: {:?} not found in {:?}", *br, self.bound_vars); } let list_var = self.bound_vars[br.var.as_usize()]; match list_var { ty::BoundVariableKind::Region(kind) => { if kind != br.kind { - panic!( + bug!( "Mismatched region kinds: {:?} doesn't match var ({:?}) in list ({:?})", br.kind, list_var, self.bound_vars ); } } - _ => panic!( + _ => bug!( "Mismatched bound variable kinds! Expected region, found {:?}", list_var ), diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 94aee87364a..68a923a55eb 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1487,7 +1487,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { if let (Some((expr, _)), Some((fn_decl, _, _))) = (expression, fcx.get_node_fn_decl(parent_item)) { - fcx.suggest_missing_return_expr(&mut err, expr, fn_decl, expected, found); + fcx.suggest_missing_return_expr(&mut err, expr, fn_decl, expected, found, parent_id); } if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.get(), fn_output) { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index b940e90fadb..6112a5fdc91 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -55,7 +55,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) { pointing_at_return_type = self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest); - self.suggest_missing_return_expr(err, expr, &fn_decl, expected, found); + let fn_id = self.tcx.hir().get_return_block(blk_id).unwrap(); + self.suggest_missing_return_expr(err, expr, &fn_decl, expected, found, fn_id); } pointing_at_return_type } @@ -479,6 +480,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_decl: &hir::FnDecl<'_>, expected: Ty<'tcx>, found: Ty<'tcx>, + id: hir::HirId, ) { if !expected.is_unit() { return; @@ -486,7 +488,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let found = self.resolve_vars_with_obligations(found); if let hir::FnRetTy::Return(ty) = fn_decl.output { let ty = >::ast_ty_to_ty(self, ty); - let ty = self.tcx.erase_late_bound_regions(Binder::bind(ty, self.tcx)); + let bound_vars = self.tcx.late_bound_vars(id); + let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars)); let ty = self.normalize_associated_types_in(expr.span, ty); if self.can_coerce(found, ty) { err.multipart_suggestion( From 4ff65ec7823d4ec16c4b88e53b5a76f71b27e324 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Thu, 11 Mar 2021 21:49:41 -0500 Subject: [PATCH 252/370] Fmt and test revert --- compiler/rustc_middle/src/ty/fold.rs | 14 ++++---- src/test/ui/symbol-names/impl1.legacy.stderr | 36 ++++++++++---------- src/test/ui/symbol-names/impl1.rs | 3 +- src/test/ui/symbol-names/impl1.v0.stderr | 24 ++++++------- 4 files changed, 39 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 819399141b9..70f3ac30040 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -879,14 +879,14 @@ impl<'tcx> TypeVisitor<'tcx> for ValidateBoundVars<'tcx> { if kind != bound_ty.kind { bug!( "Mismatched type kinds: {:?} doesn't var in list {:?}", - bound_ty.kind, list_var + bound_ty.kind, + list_var ); } } - _ => bug!( - "Mismatched bound variable kinds! Expected type, found {:?}", - list_var - ), + _ => { + bug!("Mismatched bound variable kinds! Expected type, found {:?}", list_var) + } } } @@ -908,7 +908,9 @@ impl<'tcx> TypeVisitor<'tcx> for ValidateBoundVars<'tcx> { if kind != br.kind { bug!( "Mismatched region kinds: {:?} doesn't match var ({:?}) in list ({:?})", - br.kind, list_var, self.bound_vars + br.kind, + list_var, + self.bound_vars ); } } diff --git a/src/test/ui/symbol-names/impl1.legacy.stderr b/src/test/ui/symbol-names/impl1.legacy.stderr index c9c2664e6de..bd32a39a65c 100644 --- a/src/test/ui/symbol-names/impl1.legacy.stderr +++ b/src/test/ui/symbol-names/impl1.legacy.stderr @@ -1,71 +1,71 @@ -error: symbol-name(_ZN5impl13foo3Foo3bar17h2e76f87b171019e0E) - --> $DIR/impl1.rs:16:9 +error: symbol-name(_ZN5impl13foo3Foo3bar17) + --> $DIR/impl1.rs:15:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(impl1::foo::Foo::bar::h2e76f87b171019e0) - --> $DIR/impl1.rs:16:9 +error: demangling(impl1::foo::Foo::bar::) + --> $DIR/impl1.rs:15:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(impl1::foo::Foo::bar) - --> $DIR/impl1.rs:16:9 + --> $DIR/impl1.rs:15:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(foo::Foo::bar) - --> $DIR/impl1.rs:23:9 + --> $DIR/impl1.rs:22:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17hb388a171ee84bca1E) - --> $DIR/impl1.rs:34:9 +error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17) + --> $DIR/impl1.rs:33:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(impl1::bar::::baz::hb388a171ee84bca1) - --> $DIR/impl1.rs:34:9 +error: demangling(impl1::bar::::baz::) + --> $DIR/impl1.rs:33:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(impl1::bar::::baz) - --> $DIR/impl1.rs:34:9 + --> $DIR/impl1.rs:33:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(bar::::baz) - --> $DIR/impl1.rs:41:9 + --> $DIR/impl1.rs:40:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17SYMBOL_HASH) - --> $DIR/impl1.rs:64:13 +error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17) + --> $DIR/impl1.rs:63:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method::SYMBOL_HASH) - --> $DIR/impl1.rs:64:13 +error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method::) + --> $DIR/impl1.rs:63:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method) - --> $DIR/impl1.rs:64:13 + --> $DIR/impl1.rs:63:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:71:13 + --> $DIR/impl1.rs:70:13 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index 0a865a602f6..771695330d8 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -3,8 +3,7 @@ // revisions: legacy v0 //[legacy]compile-flags: -Z symbol-mangling-version=legacy //[v0]compile-flags: -Z symbol-mangling-version=v0 -//[legacy]normalize-stderr-test: "method17h[\d\w]+" -> "method17SYMBOL_HASH" -//[legacy]normalize-stderr-test: "method::h[\d\w]+" -> "method::SYMBOL_HASH" +//[legacy]normalize-stderr-test: "h[\w]{16}E?\)" -> ")" #![feature(auto_traits, rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/symbol-names/impl1.v0.stderr b/src/test/ui/symbol-names/impl1.v0.stderr index a68a74c8552..3a6610935d6 100644 --- a/src/test/ui/symbol-names/impl1.v0.stderr +++ b/src/test/ui/symbol-names/impl1.v0.stderr @@ -1,71 +1,71 @@ error: symbol-name(_RNvMNtCs21hi0yVfW1J_5impl13fooNtB2_3Foo3bar) - --> $DIR/impl1.rs:16:9 + --> $DIR/impl1.rs:15:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(::bar) - --> $DIR/impl1.rs:16:9 + --> $DIR/impl1.rs:15:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(::bar) - --> $DIR/impl1.rs:16:9 + --> $DIR/impl1.rs:15:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(foo::Foo::bar) - --> $DIR/impl1.rs:23:9 + --> $DIR/impl1.rs:22:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ error: symbol-name(_RNvMNtCs21hi0yVfW1J_5impl13barNtNtB4_3foo3Foo3baz) - --> $DIR/impl1.rs:34:9 + --> $DIR/impl1.rs:33:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(::baz) - --> $DIR/impl1.rs:34:9 + --> $DIR/impl1.rs:33:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(::baz) - --> $DIR/impl1.rs:34:9 + --> $DIR/impl1.rs:33:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(bar::::baz) - --> $DIR/impl1.rs:41:9 + --> $DIR/impl1.rs:40:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ error: symbol-name(_RNvXNCNvCs21hi0yVfW1J_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hvEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) - --> $DIR/impl1.rs:64:13 + --> $DIR/impl1.rs:63:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(<[&dyn impl1[17891616a171812d]::Foo extern "C" fn(&'a u8, ...)> + impl1[17891616a171812d]::AutoTrait; 3: usize] as impl1[17891616a171812d]::main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:64:13 + --> $DIR/impl1.rs:63:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8, ...)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:64:13 + --> $DIR/impl1.rs:63:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:71:13 + --> $DIR/impl1.rs:70:13 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ From 0c98dc66fdc1bd5a2ff56bc72c67b03c2d376cd0 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Thu, 25 Mar 2021 12:15:45 -0400 Subject: [PATCH 253/370] Fix tests and AstConv -> dyn AstConv --- compiler/rustc_typeck/src/lib.rs | 2 +- .../no_introducing_in_band_in_locals.rs | 2 +- .../no_introducing_in_band_in_locals.stderr | 18 +++++++++++++++++- .../method-call-lifetime-args-unresolved.rs | 2 -- ...method-call-lifetime-args-unresolved.stderr | 17 +---------------- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index 4244d37232f..190744fe6f1 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -430,7 +430,7 @@ pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> { let env_node_id = tcx.hir().get_parent_item(hir_ty.hir_id); let env_def_id = tcx.hir().local_def_id(env_node_id); let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.to_def_id()); - AstConv::ast_ty_to_ty(&item_cx, hir_ty) + >::ast_ty_to_ty(&item_cx, hir_ty) } pub fn hir_trait_to_predicates<'tcx>( diff --git a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.rs b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.rs index 3b407871e37..c1c40afdbab 100644 --- a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.rs +++ b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.rs @@ -7,7 +7,7 @@ fn foo(x: &u32) { fn foo2(x: &u32) {} fn bar() { - let y: fn(&'test u32) = foo2; + let y: fn(&'test u32) = foo2; //~ ERROR use of undeclared lifetime } fn main() {} diff --git a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr index 7ecb6ff0c9d..a43b49041ec 100644 --- a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr +++ b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr @@ -6,6 +6,22 @@ LL | fn foo(x: &u32) { LL | let y: &'test u32 = x; | ^^^^^ undeclared lifetime -error: aborting due to previous error +error[E0261]: use of undeclared lifetime name `'test` + --> $DIR/no_introducing_in_band_in_locals.rs:10:16 + | +LL | let y: fn(&'test u32) = foo2; + | ^^^^^ undeclared lifetime + | + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider introducing lifetime `'test` here + | +LL | fn bar<'test>() { + | ^^^^^^^ +help: consider making the type lifetime-generic with a new `'test` lifetime + | +LL | let y: for<'test> fn(&'test u32) = foo2; + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0261`. diff --git a/src/test/ui/methods/method-call-lifetime-args-unresolved.rs b/src/test/ui/methods/method-call-lifetime-args-unresolved.rs index d7760985ec6..d16ba3df47b 100644 --- a/src/test/ui/methods/method-call-lifetime-args-unresolved.rs +++ b/src/test/ui/methods/method-call-lifetime-args-unresolved.rs @@ -1,5 +1,3 @@ fn main() { 0.clone::<'a>(); //~ ERROR use of undeclared lifetime name `'a` - //~^ WARNING cannot specify lifetime arguments - //~| WARNING this was previously accepted } diff --git a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr index 5a958bc4b9c..93c0384fcc2 100644 --- a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr +++ b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr @@ -1,18 +1,3 @@ -warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/method-call-lifetime-args-unresolved.rs:2:15 - | -LL | 0.clone::<'a>(); - | ^^ - | - ::: $SRC_DIR/core/src/clone.rs:LL:COL - | -LL | fn clone(&self) -> Self; - | - the late bound lifetime parameter is introduced here - | - = note: `#[warn(late_bound_lifetime_arguments)]` on by default - = 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 #42868 - error[E0261]: use of undeclared lifetime name `'a` --> $DIR/method-call-lifetime-args-unresolved.rs:2:15 | @@ -23,6 +8,6 @@ LL | 0.clone::<'a>(); | = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error For more information about this error, try `rustc --explain E0261`. From 7108918db6f59fca6656849c3e360045354e8a42 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Fri, 26 Mar 2021 17:40:15 -0400 Subject: [PATCH 254/370] Cleanups and comments --- compiler/rustc_middle/src/ty/util.rs | 1 - compiler/rustc_mir/src/monomorphize/mod.rs | 4 +- compiler/rustc_resolve/src/late.rs | 1 - compiler/rustc_resolve/src/late/lifetimes.rs | 411 +++++++++--------- .../rustc_resolve/src/late/supertraits.rs | 60 --- .../src/traits/auto_trait.rs | 1 - compiler/rustc_typeck/src/astconv/mod.rs | 5 +- 7 files changed, 216 insertions(+), 267 deletions(-) delete mode 100644 compiler/rustc_resolve/src/late/supertraits.rs diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index b211ac2a79f..7d09ca5152f 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -504,7 +504,6 @@ impl<'tcx> TyCtxt<'tcx> { let closure_ty = self.mk_closure(closure_def_id, closure_substs); let closure_kind_ty = closure_substs.as_closure().kind_ty(); let closure_kind = closure_kind_ty.to_opt_closure_kind()?; - debug_assert!(!closure_ty.has_escaping_bound_vars()); let env_ty = match closure_kind { ty::ClosureKind::Fn => self.mk_imm_ref(self.mk_region(env_region), closure_ty), ty::ClosureKind::FnMut => self.mk_mut_ref(self.mk_region(env_region), closure_ty), diff --git a/compiler/rustc_mir/src/monomorphize/mod.rs b/compiler/rustc_mir/src/monomorphize/mod.rs index fd3f3b3a080..9ca4b6687f1 100644 --- a/compiler/rustc_mir/src/monomorphize/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/mod.rs @@ -1,6 +1,6 @@ use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_hir::lang_items::LangItem; @@ -15,8 +15,6 @@ fn custom_coerce_unsize_info<'tcx>( ) -> CustomCoerceUnsized { let def_id = tcx.require_lang_item(LangItem::CoerceUnsized, None); - debug_assert!(!source_ty.has_escaping_bound_vars()); - debug_assert!(!target_ty.has_escaping_bound_vars()); let trait_ref = ty::Binder::dummy(ty::TraitRef { def_id, substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]), diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 25acbd478bf..1377bb781d0 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -34,7 +34,6 @@ use tracing::debug; mod diagnostics; crate mod lifetimes; -crate mod supertraits; type Res = def::Res; diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 79d81ef047e..b89ad867f46 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -151,6 +151,12 @@ struct NamedRegionMap { // (b) it DOES appear in the arguments. late_bound: HirIdSet, + // Maps relevant hir items to the bound vars on them. These include: + // - function defs + // - function pointers + // - closures + // - trait refs + // - bound types (like `T` in `for<'a> T<'a>: Foo`) late_bound_vars: HirIdMap>, } @@ -171,10 +177,16 @@ crate struct LifetimeContext<'a, 'tcx> { /// any bound var information. /// /// So, if we encounter a quantifier at the outer scope, we set - /// `trait_ref_hack` to `true` (and introduce a scope), and then if we encounter - /// a quantifier at the inner scope, we error. If `trait_ref_hack` is `false`, - /// then we introduce the scope at the inner quantifier. - trait_ref_hack: Option<(Vec, u32)>, + /// `trait_ref_hack` to the hir id of the bounded type (and introduce a scope). + /// Then, if we encounter a quantifier at the inner scope, then we know to + /// emit an error. Importantly though, we do have to track the lifetimes + /// defined on the outer scope (i.e. the bounded ty), since we continue + /// to type check after emitting an error; we therefore assume that the bound + /// vars on the inner trait refs come from both quantifiers. + /// + /// If we encounter a quantifier in the inner scope `trait_ref_hack` being + /// `None`, then we just introduce the scope at the inner quantifier as normal. + trait_ref_hack: Option, /// Used to disallow the use of in-band lifetimes in `fn` or `Fn` syntax. is_in_fn_syntax: bool, @@ -232,11 +244,9 @@ enum Scope<'a> { /// of the resulting opaque type. opaque_type_parent: bool, - /// We need to keep track of the number of named late bound vars, since - /// we may have elided lifetimes that have an index starting *after* - /// these. - named_late_bound_vars: u32, - + /// True only if this `Binder` scope is from the quantifiers on a + /// `PolyTraitRef`. This is necessary for `assocated_type_bounds`, which + /// requires binders of nested trait refs to be merged. from_poly_trait_ref: bool, /// The late bound vars for a given item are stored by `HirId` to be @@ -304,7 +314,6 @@ enum Scope<'a> { /// vars from both `for<...>`s *do* share the same binder level. TraitRefHackInner { hir_id: hir::HirId, - named_late_bound_vars: u32, s: ScopeRef<'a>, }, @@ -331,7 +340,6 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { next_early_index, track_lifetime_uses, opaque_type_parent, - named_late_bound_vars, from_poly_trait_ref, hir_id, s: _, @@ -341,7 +349,6 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { .field("next_early_index", next_early_index) .field("track_lifetime_uses", track_lifetime_uses) .field("opaque_type_parent", opaque_type_parent) - .field("named_late_bound_vars", named_late_bound_vars) .field("from_poly_trait_ref", from_poly_trait_ref) .field("hir_id", hir_id) .field("s", &"..") @@ -357,10 +364,9 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { .field("lifetime", lifetime) .field("s", &"..") .finish(), - Scope::TraitRefHackInner { hir_id, named_late_bound_vars, s: _ } => f + Scope::TraitRefHackInner { hir_id, s: _ } => f .debug_struct("TraitRefHackInner") .field("hir_id", hir_id) - .field("named_late_bound_vars", named_late_bound_vars) .field("s", &"..") .finish(), Scope::Supertrait { lifetimes, s: _ } => f @@ -664,7 +670,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: self.scope, track_lifetime_uses: true, opaque_type_parent: false, - named_late_bound_vars: 0, from_poly_trait_ref: false, }; self.with(scope, move |_old_scope, this| { @@ -790,7 +795,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index: index + non_lifetime_count, opaque_type_parent: true, track_lifetime_uses, - named_late_bound_vars: 0, from_poly_trait_ref: false, s: ROOT_SCOPE, }; @@ -838,21 +842,19 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }; self.missing_named_lifetime_spots .push(MissingLifetimeSpot::HigherRanked { span, span_type }); - let mut named_late_bound_vars = 0; let (lifetimes, binders): (FxHashMap, Vec<_>) = c .generic_params .iter() .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - let late_bound_idx = named_late_bound_vars; - named_late_bound_vars += 1; - let pair = Region::late(late_bound_idx, &self.tcx.hir(), param); - let r = pair.1.clone(); - let r = late_region_as_bound_region(self.tcx, &r); - Some((pair, r)) - } + GenericParamKind::Lifetime { .. } => Some(param), _ => None, }) + .enumerate() + .map(|(late_bound_idx, param)| { + let pair = Region::late(late_bound_idx as u32, &self.tcx.hir(), param); + let r = late_region_as_bound_region(self.tcx, &pair.1); + (pair, r) + }) .unzip(); self.map.late_bound_vars.insert(ty.hir_id, binders); let scope = Scope::Binder { @@ -862,7 +864,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index, track_lifetime_uses: true, opaque_type_parent: false, - named_late_bound_vars, from_poly_trait_ref: false, }; self.with(scope, |old_scope, this| { @@ -1053,7 +1054,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: this.scope, track_lifetime_uses: true, opaque_type_parent: false, - named_late_bound_vars: 0, from_poly_trait_ref: false, }; this.with(scope, |_old_scope, this| { @@ -1071,7 +1071,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: self.scope, track_lifetime_uses: true, opaque_type_parent: false, - named_late_bound_vars: 0, from_poly_trait_ref: false, }; self.with(scope, |_old_scope, this| { @@ -1128,7 +1127,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: self.scope, track_lifetime_uses: true, opaque_type_parent: true, - named_late_bound_vars: 0, from_poly_trait_ref: false, }; self.with(scope, |old_scope, this| { @@ -1195,7 +1193,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: self.scope, track_lifetime_uses: true, opaque_type_parent: true, - named_late_bound_vars: 0, from_poly_trait_ref: false, }; self.with(scope, |old_scope, this| { @@ -1279,21 +1276,21 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { ref bound_generic_params, .. }) => { - let mut named_late_bound_vars = 0; - let (lifetimes, binders): (FxHashMap<_, _>, Vec<_>) = bound_generic_params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - let late_bound_idx = named_late_bound_vars; - named_late_bound_vars += 1; - let pair = Region::late(late_bound_idx, &self.tcx.hir(), param); - let r = pair.1.clone(); - let r = late_region_as_bound_region(self.tcx, &r); - Some((pair, r)) - } - _ => None, - }) - .unzip(); + let (lifetimes, binders): (FxHashMap, Vec<_>) = + bound_generic_params + .iter() + .filter_map(|param| match param.kind { + GenericParamKind::Lifetime { .. } => Some(param), + _ => None, + }) + .enumerate() + .map(|(late_bound_idx, param)| { + let pair = + Region::late(late_bound_idx as u32, &self.tcx.hir(), param); + let r = late_region_as_bound_region(self.tcx, &pair.1); + (pair, r) + }) + .unzip(); self.map.late_bound_vars.insert(bounded_ty.hir_id, binders.clone()); if !lifetimes.is_empty() { let next_early_index = self.next_early_index(); @@ -1304,13 +1301,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index, track_lifetime_uses: true, opaque_type_parent: false, - named_late_bound_vars, from_poly_trait_ref: true, }; let result = self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &bound_generic_params); this.visit_ty(&bounded_ty); - this.trait_ref_hack = Some((binders, named_late_bound_vars)); + this.trait_ref_hack = Some(bounded_ty.hir_id); walk_list!(this, visit_param_bound, bounds); this.trait_ref_hack = None; }); @@ -1351,7 +1347,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index: self.next_early_index(), track_lifetime_uses: true, opaque_type_parent: false, - named_late_bound_vars: 0, from_poly_trait_ref: false, }; self.with(scope, |_, this| { @@ -1389,112 +1384,97 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { .emit(); } - let (binders, named_late_bound_vars, lifetimes) = - if let Some((mut binders, mut named_late_bound_vars)) = trait_ref_hack.clone() { - let initial_binders = named_late_bound_vars; - binders.extend(trait_ref.bound_generic_params.iter().filter_map(|param| { - match param.kind { - GenericParamKind::Lifetime { .. } => { - let late_bound_idx = named_late_bound_vars; - named_late_bound_vars += 1; - let region = Region::late(late_bound_idx, &self.tcx.hir(), param).1; - Some(late_region_as_bound_region(self.tcx, ®ion)) - } - GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, + let (binders, lifetimes) = if let Some(hir_id) = trait_ref_hack { + let mut binders = self.map.late_bound_vars.entry(hir_id).or_default().clone(); + let initial_bound_vars = binders.len() as u32; + let mut lifetimes: FxHashMap = FxHashMap::default(); + let binders_iter = trait_ref + .bound_generic_params + .iter() + .filter_map(|param| match param.kind { + GenericParamKind::Lifetime { .. } => Some(param), + _ => None, + }) + .enumerate() + .map(|(late_bound_idx, param)| { + let pair = Region::late( + initial_bound_vars + late_bound_idx as u32, + &self.tcx.hir(), + param, + ); + let r = late_region_as_bound_region(self.tcx, &pair.1); + lifetimes.insert(pair.0, pair.1); + r + }); + binders.extend(binders_iter); + + (binders, lifetimes) + } else { + let mut supertrait_lifetimes = vec![]; + let mut scope = self.scope; + let mut outer_binders = loop { + match scope { + Scope::Body { .. } | Scope::Root => { + break vec![]; } - })); - let mut named_late_bound_vars = initial_binders; - let lifetimes: FxHashMap = trait_ref - .bound_generic_params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - let late_bound_idx = named_late_bound_vars; - named_late_bound_vars += 1; - Some(Region::late(late_bound_idx, &self.tcx.hir(), param)) - } - _ => None, - }) - .collect(); + Scope::Elision { s, .. } | Scope::ObjectLifetimeDefault { s, .. } => { + scope = s; + } - (binders, named_late_bound_vars, lifetimes) - } else { - let mut supertrait_lifetimes = vec![]; - let mut scope = self.scope; - let mut binders = loop { - match scope { - Scope::Body { .. } | Scope::Root => { + Scope::TraitRefHackInner { hir_id, .. } => { + // Nested poly trait refs have the binders concatenated + // If we reach `TraitRefHackInner`, then there is only one more `Binder` above us, + // over all the bounds. We don't want this, since all the lifetimes we care about + // are here anyways. + let mut full_binders = + self.map.late_bound_vars.entry(*hir_id).or_default().clone(); + full_binders.extend(supertrait_lifetimes.into_iter()); + break full_binders; + } + + Scope::Supertrait { s, lifetimes } => { + supertrait_lifetimes = lifetimes.clone(); + scope = s; + } + + Scope::Binder { hir_id, from_poly_trait_ref, .. } => { + if !from_poly_trait_ref { + // We should only see super trait lifetimes if there is a `Binder` above + assert!(supertrait_lifetimes.is_empty()); break vec![]; } - - Scope::Elision { s, .. } | Scope::ObjectLifetimeDefault { s, .. } => { - scope = s; - } - - Scope::TraitRefHackInner { hir_id, .. } => { - // Nested poly trait refs have the binders concatenated - // If we reach `TraitRefHackInner`, then there is only one more `Binder` above us, - // over all the bounds. We don't want this, since all the lifetimes we care about - // are here anyways. - let mut full_binders = - self.map.late_bound_vars.entry(*hir_id).or_default().clone(); - full_binders.extend(supertrait_lifetimes.into_iter()); - break full_binders; - } - - Scope::Supertrait { s, lifetimes } => { - supertrait_lifetimes = lifetimes.clone(); - scope = s; - } - - Scope::Binder { hir_id, from_poly_trait_ref, .. } => { - if !from_poly_trait_ref { - // We should only see super trait lifetimes if there is a `Binder` above - assert!(supertrait_lifetimes.is_empty()); - break vec![]; - } - // Nested poly trait refs have the binders concatenated - let mut full_binders = - self.map.late_bound_vars.entry(*hir_id).or_default().clone(); - full_binders.extend(supertrait_lifetimes.into_iter()); - break full_binders; - } + // Nested poly trait refs have the binders concatenated + let mut full_binders = + self.map.late_bound_vars.entry(*hir_id).or_default().clone(); + full_binders.extend(supertrait_lifetimes.into_iter()); + break full_binders; } - }; - let mut named_late_bound_vars = binders.len() as u32; - let local_binders: Vec<_> = trait_ref - .bound_generic_params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - let late_bound_idx = named_late_bound_vars; - named_late_bound_vars += 1; - let region = Region::late(late_bound_idx, &self.tcx.hir(), param).1; - Some(late_region_as_bound_region(self.tcx, ®ion)) - } - GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, - }) - .collect(); - - let mut named_late_bound_vars = binders.len() as u32; - let lifetimes: FxHashMap = trait_ref - .bound_generic_params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - let late_bound_idx = named_late_bound_vars; - named_late_bound_vars += 1; - Some(Region::late(late_bound_idx, &self.tcx.hir(), param)) - } - _ => None, - }) - .collect(); - - binders.extend(local_binders.into_iter()); - - (binders, named_late_bound_vars, lifetimes) + } }; + let (lifetimes, local_binders): (FxHashMap, Vec<_>) = trait_ref + .bound_generic_params + .iter() + .filter_map(|param| match param.kind { + GenericParamKind::Lifetime { .. } => Some(param), + _ => None, + }) + .enumerate() + .map(|(late_bound_idx, param)| { + let pair = Region::late( + outer_binders.len() as u32 + late_bound_idx as u32, + &self.tcx.hir(), + param, + ); + let r = late_region_as_bound_region(self.tcx, &pair.1); + (pair, r) + }) + .unzip(); + + outer_binders.extend(local_binders.into_iter()); + + (outer_binders, lifetimes) + }; debug!(?binders); self.map.late_bound_vars.insert(trait_ref.trait_ref.hir_ref_id, binders); @@ -1507,7 +1487,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index, track_lifetime_uses: true, opaque_type_parent: false, - named_late_bound_vars: named_late_bound_vars as u32, from_poly_trait_ref: true, }; self.with(scope, |old_scope, this| { @@ -1516,11 +1495,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { this.visit_trait_ref(&trait_ref.trait_ref); }); } else { - let scope = Scope::TraitRefHackInner { - hir_id: trait_ref.trait_ref.hir_ref_id, - named_late_bound_vars: named_late_bound_vars as u32, - s: self.scope, - }; + let scope = + Scope::TraitRefHackInner { hir_id: trait_ref.trait_ref.hir_ref_id, s: self.scope }; self.with(scope, |_old_scope, this| { this.visit_trait_ref(&trait_ref.trait_ref); }); @@ -2234,23 +2210,22 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .collect(); let next_early_index = next_early_index + non_lifetime_count; - let mut named_late_bound_vars = 0; let binders: Vec<_> = generics .params .iter() .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - if self.map.late_bound.contains(¶m.hir_id) { - let late_bound_idx = named_late_bound_vars; - named_late_bound_vars += 1; - let r = Region::late(late_bound_idx, &self.tcx.hir(), param).1; - let r = late_region_as_bound_region(self.tcx, &r); - Some(r) - } else { - None - } + GenericParamKind::Lifetime { .. } + if self.map.late_bound.contains(¶m.hir_id) => + { + Some(param) } - GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, + _ => None, + }) + .enumerate() + .map(|(late_bound_idx, param)| { + let pair = Region::late(late_bound_idx as u32, &self.tcx.hir(), param); + let r = late_region_as_bound_region(self.tcx, &pair.1); + r }) .collect(); self.map.late_bound_vars.insert(hir_id, binders); @@ -2261,7 +2236,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { s: self.scope, opaque_type_parent: true, track_lifetime_uses: false, - named_late_bound_vars: named_late_bound_vars as u32, from_poly_trait_ref: false, }; self.with(scope, move |old_scope, this| { @@ -2629,49 +2603,85 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let has_lifetime_parameter = generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_))); - // Resolve lifetimes found in the type `XX` from `Item = XX` bindings. + // Resolve lifetimes found in the bindings, so either in the type `XX` in `Item = XX` or + // in the trait ref `YY<...>` in `Item: YY<...>`. for binding in generic_args.bindings { let scope = Scope::ObjectLifetimeDefault { lifetime: if has_lifetime_parameter { None } else { Some(Region::Static) }, s: self.scope, }; if let Some(type_def_id) = type_def_id { - let lifetimes = - LifetimeContext::supertrait_bounds(self.tcx, type_def_id, binding.ident); - if let Some(lifetimes) = lifetimes { - self.with(scope, |_, this| { - let scope = Scope::Supertrait { lifetimes, s: this.scope }; - this.with(scope, |_, this| this.visit_assoc_type_binding(binding)); - }); - } else { - self.with(scope, |_, this| this.visit_assoc_type_binding(binding)); - } + let lifetimes = LifetimeContext::supertrait_hrtb_lifetimes( + self.tcx, + type_def_id, + binding.ident, + ); + self.with(scope, |_, this| { + let scope = + Scope::Supertrait { lifetimes: lifetimes.unwrap_or(vec![]), s: this.scope }; + this.with(scope, |_, this| this.visit_assoc_type_binding(binding)); + }); } else { self.with(scope, |_, this| this.visit_assoc_type_binding(binding)); } } } - fn trait_defines_associated_type_named( - tcx: TyCtxt<'tcx>, - trait_def_id: DefId, - assoc_name: Ident, - ) -> bool { - tcx.associated_items(trait_def_id) - .find_by_name_and_kind(tcx, assoc_name, ty::AssocKind::Type, trait_def_id) - .is_some() - } - - fn supertrait_bounds( + /// Returns all the late-bound vars that come into scope from supertrait HRTBs, based on the + /// associated type name and starting trait. + /// For example, imagine we have + /// ```rust + /// trait Foo<'a, 'b> { + /// type As; + /// } + /// trait Bar<'b>: for<'a> Foo<'a, 'b> {} + /// trait Bar: for<'b> Bar<'b> {} + /// ``` + /// In this case, if we wanted to the supertrait HRTB lifetimes for `As` on + /// the starting trait `Bar`, we would return `Some(['b, 'a])`. + fn supertrait_hrtb_lifetimes( tcx: TyCtxt<'tcx>, def_id: DefId, assoc_name: Ident, ) -> Option> { - let all_candidates = super::supertraits::supertraits(tcx, def_id); - let mut matching_candidates = all_candidates - .filter(|r| LifetimeContext::trait_defines_associated_type_named(tcx, r.0, assoc_name)); + let trait_defines_associated_type_named = |trait_def_id: DefId| { + tcx.associated_items(trait_def_id) + .find_by_name_and_kind(tcx, assoc_name, ty::AssocKind::Type, trait_def_id) + .is_some() + }; - matching_candidates.next().map(|c| c.1.into_iter().collect()) + use smallvec::{smallvec, SmallVec}; + let mut stack: SmallVec<[(DefId, SmallVec<[ty::BoundVariableKind; 8]>); 8]> = + smallvec![(def_id, smallvec![])]; + let mut visited: FxHashSet = FxHashSet::default(); + loop { + let (def_id, bound_vars) = match stack.pop() { + Some(next) => next, + None => break None, + }; + if trait_defines_associated_type_named(def_id) { + break Some(bound_vars.into_iter().collect()); + } + let predicates = + tcx.super_predicates_that_define_assoc_type((def_id, Some(assoc_name))); + let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| { + let bound_predicate = pred.kind(); + match bound_predicate.skip_binder() { + ty::PredicateKind::Trait(data, _) => { + // The order here needs to match what we would get from `subst_supertrait` + let pred_bound_vars = bound_predicate.bound_vars(); + let mut all_bound_vars = bound_vars.clone(); + all_bound_vars.extend(pred_bound_vars.iter()); + let super_def_id = data.trait_ref.def_id; + Some((super_def_id, all_bound_vars)) + } + _ => None, + } + }); + + let obligations = obligations.filter(|o| visited.insert(o.0)); + stack.extend(obligations); + } } #[tracing::instrument(level = "debug", skip(self))] @@ -2682,13 +2692,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { ) { debug!("visit_fn_like_elision: enter"); let mut scope = &*self.scope; - let (hir_id, named_late_bound_vars) = loop { + let hir_id = loop { match scope { - Scope::Binder { hir_id, named_late_bound_vars, .. } - | Scope::TraitRefHackInner { hir_id, named_late_bound_vars, .. } => { - break (*hir_id, *named_late_bound_vars); + Scope::Binder { hir_id, .. } | Scope::TraitRefHackInner { hir_id, .. } => { + break *hir_id; } - Scope::Body { id, .. } => break (id.hir_id, 0), + Scope::Body { id, .. } => break id.hir_id, Scope::ObjectLifetimeDefault { ref s, .. } | Scope::Elision { ref s, .. } | Scope::Supertrait { ref s, .. } => { @@ -2697,11 +2706,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Root => bug!("In fn_like_elision without appropriate scope above"), } }; + // While not strictly necessary, we gather anon lifetimes *before* actually + // visiting the argument types. let mut gather = GatherAnonLifetimes { anon_count: 0 }; for input in inputs { gather.visit_ty(input); } - self.map.late_bound_vars.entry(hir_id).or_default().extend( + let late_bound_vars = self.map.late_bound_vars.entry(hir_id).or_default(); + let named_late_bound_vars = late_bound_vars.len() as u32; + late_bound_vars.extend( (0..gather.anon_count).map(|var| ty::BoundVariableKind::Region(ty::BrAnon(var))), ); let arg_scope = Scope::Elision { @@ -2987,6 +3000,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } fn visit_ty(&mut self, ty: &hir::Ty<'_>) { + // If we enter a `BareFn`, then we enter a *new* binding scope if let hir::TyKind::BareFn(_) = ty.kind { return; } @@ -2998,6 +3012,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { path_span: Span, generic_args: &'v hir::GenericArgs<'v>, ) { + // parenthesized args enter a new elison scope if generic_args.parenthesized { return; } diff --git a/compiler/rustc_resolve/src/late/supertraits.rs b/compiler/rustc_resolve/src/late/supertraits.rs deleted file mode 100644 index 2130c33bd77..00000000000 --- a/compiler/rustc_resolve/src/late/supertraits.rs +++ /dev/null @@ -1,60 +0,0 @@ -use smallvec::{smallvec, SmallVec}; - -use rustc_data_structures::fx::FxHashSet; -use rustc_hir::def_id::DefId; -use rustc_middle::ty::{self, TyCtxt}; - -pub struct Elaborator<'tcx> { - tcx: TyCtxt<'tcx>, - stack: SmallVec<[(DefId, SmallVec<[ty::BoundVariableKind; 8]>); 8]>, - visited: FxHashSet, -} - -#[allow(dead_code)] -pub fn supertraits<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Elaborator<'tcx> { - Elaborator { tcx, stack: smallvec![(def_id, smallvec![])], visited: Default::default() } -} - -impl<'tcx> Elaborator<'tcx> { - fn elaborate(&mut self, def_id: DefId, bound_vars: &SmallVec<[ty::BoundVariableKind; 8]>) { - let tcx = self.tcx; - - let predicates = tcx.super_predicates_of(def_id); - let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| { - let bound_predicate = pred.kind(); - match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(data, _) => { - // The order here needs to match what we would get from `subst_supertrait` - let pred_bound_vars = bound_predicate.bound_vars(); - let mut all_bound_vars = bound_vars.clone(); - all_bound_vars.extend(pred_bound_vars.iter()); - let super_def_id = data.trait_ref.def_id; - Some((super_def_id, all_bound_vars)) - } - _ => None, - } - }); - - let visited = &mut self.visited; - let obligations = obligations.filter(|o| visited.insert(o.0)); - self.stack.extend(obligations); - } -} - -impl<'tcx> Iterator for Elaborator<'tcx> { - type Item = (DefId, SmallVec<[ty::BoundVariableKind; 8]>); - - fn size_hint(&self) -> (usize, Option) { - (self.stack.len(), None) - } - - fn next(&mut self) -> Option { - match self.stack.pop() { - Some((def_id, bound_vars)) => { - self.elaborate(def_id, &bound_vars); - Some((def_id, bound_vars)) - } - None => None, - } - } -} diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index cb66dc7e5d9..f54eb0914a5 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -82,7 +82,6 @@ impl<'tcx> AutoTraitFinder<'tcx> { ) -> AutoTraitResult { let tcx = self.tcx; - debug_assert!(!ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef { def_id: trait_did, substs: tcx.mk_substs_trait(ty, &[]) }; let trait_pred = ty::Binder::dummy(trait_ref); diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 8d55bc8f2f3..b6de491911a 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2186,13 +2186,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } + /// Parses the programmer's textual representation of a type into our + /// internal notion of a type. pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> { self.ast_ty_to_ty_inner(ast_ty, false) } - /// Parses the programmer's textual representation of a type into our - /// internal notion of a type. - /// /// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait /// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors. #[tracing::instrument(level = "debug", skip(self))] From f3dde45d2a963c32994a78f3ea0119a2da973c14 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 31 Mar 2021 17:12:03 +0200 Subject: [PATCH 255/370] Enable debugging the dep-graph without debug-assertions. It may also be useful in these cases, and some CI configurations test without debug assertions. --- .../rustc_query_system/src/dep_graph/serialized.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 1e34b14d906..6f3d1fb7199 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -157,11 +157,11 @@ impl EncoderState { } } - #[instrument(skip(self, _record_graph))] + #[instrument(skip(self, record_graph))] fn encode_node( &mut self, node: &NodeInfo, - _record_graph: &Option>>, + record_graph: &Option>>, ) -> DepNodeIndex { let index = DepNodeIndex::new(self.total_node_count); self.total_node_count += 1; @@ -169,8 +169,7 @@ impl EncoderState { let edge_count = node.edges.len(); self.total_edge_count += edge_count; - #[cfg(debug_assertions)] - if let Some(record_graph) = &_record_graph { + if let Some(record_graph) = &record_graph { // Do not ICE when a query is called from within `with_query`. if let Some(record_graph) = &mut record_graph.try_lock() { record_graph.push(index, node.node, &node.edges); @@ -222,11 +221,8 @@ impl> GraphEncoder { record_graph: bool, record_stats: bool, ) -> Self { - let record_graph = if cfg!(debug_assertions) && record_graph { - Some(Lock::new(DepGraphQuery::new(prev_node_count))) - } else { - None - }; + let record_graph = + if record_graph { Some(Lock::new(DepGraphQuery::new(prev_node_count))) } else { None }; let status = Lock::new(EncoderState::new(encoder, record_stats)); GraphEncoder { status, record_graph } } From 38b31691a7c6124ae4e48809ee9e083c1ca1f635 Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Wed, 31 Mar 2021 15:30:07 +0000 Subject: [PATCH 256/370] Fix compiletest to use correct bitwidth stderr files. --- src/tools/compiletest/src/runtest.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 1a49b1e7b17..7e6c21b824d 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -3140,8 +3140,14 @@ impl<'test> TestCx<'test> { output_kind: TestOutput, explicit_format: bool, ) -> usize { + let stderr_bits = format!("{}.stderr", get_pointer_width(&self.config.target)); let (stderr_kind, stdout_kind) = match output_kind { - TestOutput::Compile => (UI_STDERR, UI_STDOUT), + TestOutput::Compile => ( + { + if self.props.stderr_per_bitwidth { &stderr_bits } else { UI_STDERR } + }, + UI_STDOUT, + ), TestOutput::Run => (UI_RUN_STDERR, UI_RUN_STDOUT), }; @@ -3181,15 +3187,12 @@ impl<'test> TestCx<'test> { match output_kind { TestOutput::Compile => { if !self.props.dont_check_compiler_stdout { - errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout); + errors += + self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout); } if !self.props.dont_check_compiler_stderr { - let kind = if self.props.stderr_per_bitwidth { - format!("{}.stderr", get_pointer_width(&self.config.target)) - } else { - String::from("stderr") - }; - errors += self.compare_output(&kind, &normalized_stderr, &expected_stderr); + errors += + self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr); } } TestOutput::Run => { From d4f3f91c48dd244357a439a234a44d5f0e99f014 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 31 Mar 2021 11:13:51 -0400 Subject: [PATCH 257/370] Enforce that Toolchain files are static and Crate files are dynamic This also changes custom themes from Toolchain to Crate files. --- src/librustdoc/html/render/write_shared.rs | 63 +++++++++++--------- src/test/run-make/emit-shared-files/Makefile | 6 +- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index af346bb8225..b19b29d2fa0 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -44,11 +44,11 @@ enum SharedResource<'a> { /// This file will never change, no matter what toolchain is used to build it. /// /// It does not have a resource suffix. - Unversioned { name: &'a str }, + Unversioned { name: &'static str }, /// This file may change depending on the toolchain. /// /// It has a resource suffix. - ToolchainSpecific { basename: &'a str }, + ToolchainSpecific { basename: &'static str }, /// This file may change for any crate within a build. /// /// This differs from normal crate-specific files because it has a resource suffix. @@ -157,11 +157,16 @@ pub(super) fn write_shared( &options.emit, ) }; - let write_toolchain = |p: &_, c: &_| { + // Toolchain resources should never be dynamic. + let write_toolchain = |p: &'static _, c: &'static _| { cx.write_shared(SharedResource::ToolchainSpecific { basename: p }, c, &options.emit) }; - let write_crate = - |p, c: &_| cx.write_shared(SharedResource::CrateSpecific { basename: p }, c, &options.emit); + + // Crate resources should always be dynamic. + let write_crate = |p: &_, make_content: &dyn Fn() -> Result, Error>| { + let content = make_content()?; + cx.write_shared(SharedResource::CrateSpecific { basename: p }, content, &options.emit) + }; // Add all the static files. These may already exist, but we just // overwrite them anyway to make sure that they're fresh and up-to-date. @@ -185,10 +190,8 @@ pub(super) fn write_shared( "ayu" => write_minify("ayu.css", static_files::themes::AYU)?, _ => { // Handle added third-party themes - let content = try_err!(fs::read(&entry.path), &entry.path); - // This is not exactly right: if compiled a second time with the same toolchain but different CLI args, the file could be different. - // But docs.rs doesn't use this, so hopefully the issue doesn't come up. - write_toolchain(&format!("{}.{}", theme, extension), content.as_slice())?; + let filename = format!("{}.{}", theme, extension); + write_crate(&filename, &|| Ok(try_err!(fs::read(&entry.path), &entry.path)))?; } }; @@ -367,19 +370,22 @@ pub(super) fn write_shared( } let dst = cx.dst.join(&format!("source-files{}.js", cx.shared.resource_suffix)); - let (mut all_sources, _krates) = - try_err!(collect(&dst, &krate.name.as_str(), "sourcesIndex"), &dst); - all_sources.push(format!( - "sourcesIndex[\"{}\"] = {};", - &krate.name, - hierarchy.to_json_string() - )); - all_sources.sort(); - let v = format!( - "var N = null;var sourcesIndex = {{}};\n{}\ncreateSourceSidebar();\n", - all_sources.join("\n") - ); - write_crate("source-files.js", &v)?; + let make_sources = || { + let (mut all_sources, _krates) = + try_err!(collect(&dst, &krate.name.as_str(), "sourcesIndex"), &dst); + all_sources.push(format!( + "sourcesIndex[\"{}\"] = {};", + &krate.name, + hierarchy.to_json_string() + )); + all_sources.sort(); + Ok(format!( + "var N = null;var sourcesIndex = {{}};\n{}\ncreateSourceSidebar();\n", + all_sources.join("\n") + ) + .into_bytes()) + }; + write_crate("source-files.js", &make_sources)?; } // Update the search index and crate list. @@ -392,16 +398,17 @@ pub(super) fn write_shared( // Sort the indexes by crate so the file will be generated identically even // with rustdoc running in parallel. all_indexes.sort(); - { + write_crate("search-index.js", &|| { let mut v = String::from("var searchIndex = JSON.parse('{\\\n"); v.push_str(&all_indexes.join(",\\\n")); v.push_str("\\\n}');\ninitSearch(searchIndex);"); - write_crate("search-index.js", &v)?; - } + Ok(v.into_bytes()) + })?; - let crate_list = - format!("window.ALL_CRATES = [{}];", krates.iter().map(|k| format!("\"{}\"", k)).join(",")); - write_crate("crates.js", &crate_list)?; + write_crate("crates.js", &|| { + let krates = krates.iter().map(|k| format!("\"{}\"", k)).join(","); + Ok(format!("window.ALL_CRATES = [{}];", krates).into_bytes()) + })?; if options.enable_index_page { if let Some(index_page) = options.index_page.clone() { diff --git a/src/test/run-make/emit-shared-files/Makefile b/src/test/run-make/emit-shared-files/Makefile index 06358f6eb2c..952c3aaf560 100644 --- a/src/test/run-make/emit-shared-files/Makefile +++ b/src/test/run-make/emit-shared-files/Makefile @@ -7,17 +7,20 @@ ALL_SHARED = $(TMPDIR)/all-shared all: crate-only toolchain-only all-shared crate-only: - $(RUSTDOC) -Z unstable-options --emit=crate-specific --output $(CRATE_ONLY) --resource-suffix=-xxx x.rs + $(RUSTDOC) -Z unstable-options --emit=crate-specific --output $(CRATE_ONLY) --resource-suffix=-xxx --theme y.css x.rs [ -e $(CRATE_ONLY)/search-index-xxx.js ] [ -e $(CRATE_ONLY)/settings.html ] [ -e $(CRATE_ONLY)/x/all.html ] [ -e $(CRATE_ONLY)/x/index.html ] + # FIXME: this probably shouldn't have a suffix + [ -e $(CRATE_ONLY)/y-xxx.css ] ! [ -e $(CRATE_ONLY)/storage-xxx.js ] ! [ -e $(CRATE_ONLY)/SourceSerifPro-It.ttf.woff ] toolchain-only: $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources --output $(TOOLCHAIN_ONLY) --resource-suffix=-xxx x.rs [ -e $(TOOLCHAIN_ONLY)/storage-xxx.js ] + ! [ -e $(TOOLCHAIN_ONLY)/y-xxx.css ] ! [ -e $(TOOLCHAIN_ONLY)/SourceSerifPro-It.ttf.woff ] ! [ -e $(TOOLCHAIN_ONLY)/search-index-xxx.js ] ! [ -e $(TOOLCHAIN_ONLY)/x/index.html ] @@ -26,6 +29,7 @@ all-shared: $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources,unversioned-shared-resources --output $(ALL_SHARED) --resource-suffix=-xxx x.rs [ -e $(ALL_SHARED)/storage-xxx.js ] [ -e $(ALL_SHARED)/SourceSerifPro-It.ttf.woff ] + ! [ -e $(ALL_SHARED)/y-xxx.css ] ! [ -e $(ALL_SHARED)/search-index-xxx.js ] ! [ -e $(ALL_SHARED)/settings.html ] ! [ -e $(ALL_SHARED)/x ] From 1086d9b7b58fea8f15b1f10bc2e527b6fcb0e382 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 31 Mar 2021 11:35:57 -0400 Subject: [PATCH 258/370] Rename CrateSpecific -> InvocationSpecific --- src/librustdoc/config.rs | 6 +++--- src/librustdoc/html/render/write_shared.rs | 14 ++++++------- src/librustdoc/lib.rs | 2 +- src/test/run-make/emit-shared-files/Makefile | 22 ++++++++++---------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index a7a2db62100..246e0ebbb2b 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -274,7 +274,7 @@ crate struct RenderOptions { crate enum EmitType { Unversioned, Toolchain, - CrateSpecific, + InvocationSpecific, } impl FromStr for EmitType { @@ -285,7 +285,7 @@ impl FromStr for EmitType { match s { "unversioned-shared-resources" => Ok(Unversioned), "toolchain-shared-resources" => Ok(Toolchain), - "crate-specific" => Ok(CrateSpecific), + "invocation-specific" => Ok(InvocationSpecific), _ => Err(()), } } @@ -293,7 +293,7 @@ impl FromStr for EmitType { impl RenderOptions { crate fn should_emit_crate(&self) -> bool { - self.emit.is_empty() || self.emit.contains(&EmitType::CrateSpecific) + self.emit.is_empty() || self.emit.contains(&EmitType::InvocationSpecific) } } diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index b19b29d2fa0..34994097812 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -49,10 +49,10 @@ enum SharedResource<'a> { /// /// It has a resource suffix. ToolchainSpecific { basename: &'static str }, - /// This file may change for any crate within a build. + /// This file may change for any crate within a build, or based on the CLI arguments. /// - /// This differs from normal crate-specific files because it has a resource suffix. - CrateSpecific { basename: &'a str }, + /// This differs from normal invocation-specific files because it has a resource suffix. + InvocationSpecific { basename: &'a str }, } impl SharedResource<'_> { @@ -61,7 +61,7 @@ impl SharedResource<'_> { match self { Unversioned { name } | ToolchainSpecific { basename: name } - | CrateSpecific { basename: name } => Path::new(name).extension(), + | InvocationSpecific { basename: name } => Path::new(name).extension(), } } @@ -69,7 +69,7 @@ impl SharedResource<'_> { match self { SharedResource::Unversioned { name } => cx.dst.join(name), SharedResource::ToolchainSpecific { basename } => cx.suffix_path(basename), - SharedResource::CrateSpecific { basename } => cx.suffix_path(basename), + SharedResource::InvocationSpecific { basename } => cx.suffix_path(basename), } } @@ -80,7 +80,7 @@ impl SharedResource<'_> { let kind = match self { SharedResource::Unversioned { .. } => EmitType::Unversioned, SharedResource::ToolchainSpecific { .. } => EmitType::Toolchain, - SharedResource::CrateSpecific { .. } => EmitType::CrateSpecific, + SharedResource::InvocationSpecific { .. } => EmitType::InvocationSpecific, }; emit.contains(&kind) } @@ -165,7 +165,7 @@ pub(super) fn write_shared( // Crate resources should always be dynamic. let write_crate = |p: &_, make_content: &dyn Fn() -> Result, Error>| { let content = make_content()?; - cx.write_shared(SharedResource::CrateSpecific { basename: p }, content, &options.emit) + cx.write_shared(SharedResource::InvocationSpecific { basename: p }, content, &options.emit) }; // Add all the static files. These may already exist, but we just diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index ebdd56611db..54a6fc625a6 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -532,7 +532,7 @@ fn opts() -> Vec { "", "emit", "Comma separated list of types of output for rustdoc to emit", - "[unversioned-shared-resources,toolchain-shared-resources,crate-specific]", + "[unversioned-shared-resources,toolchain-shared-resources,invocation-specific]", ) }), ] diff --git a/src/test/run-make/emit-shared-files/Makefile b/src/test/run-make/emit-shared-files/Makefile index 952c3aaf560..66a36dae9d3 100644 --- a/src/test/run-make/emit-shared-files/Makefile +++ b/src/test/run-make/emit-shared-files/Makefile @@ -1,21 +1,21 @@ -include ../../run-make-fulldeps/tools.mk -CRATE_ONLY = $(TMPDIR)/crate-only +INVOCATION_ONLY = $(TMPDIR)/invocation-only TOOLCHAIN_ONLY = $(TMPDIR)/toolchain-only ALL_SHARED = $(TMPDIR)/all-shared -all: crate-only toolchain-only all-shared +all: invocation-only toolchain-only all-shared -crate-only: - $(RUSTDOC) -Z unstable-options --emit=crate-specific --output $(CRATE_ONLY) --resource-suffix=-xxx --theme y.css x.rs - [ -e $(CRATE_ONLY)/search-index-xxx.js ] - [ -e $(CRATE_ONLY)/settings.html ] - [ -e $(CRATE_ONLY)/x/all.html ] - [ -e $(CRATE_ONLY)/x/index.html ] +invocation-only: + $(RUSTDOC) -Z unstable-options --emit=invocation-specific --output $(INVOCATION_ONLY) --resource-suffix=-xxx --theme y.css x.rs + [ -e $(INVOCATION_ONLY)/search-index-xxx.js ] + [ -e $(INVOCATION_ONLY)/settings.html ] + [ -e $(INVOCATION_ONLY)/x/all.html ] + [ -e $(INVOCATION_ONLY)/x/index.html ] # FIXME: this probably shouldn't have a suffix - [ -e $(CRATE_ONLY)/y-xxx.css ] - ! [ -e $(CRATE_ONLY)/storage-xxx.js ] - ! [ -e $(CRATE_ONLY)/SourceSerifPro-It.ttf.woff ] + [ -e $(INVOCATION_ONLY)/y-xxx.css ] + ! [ -e $(INVOCATION_ONLY)/storage-xxx.js ] + ! [ -e $(INVOCATION_ONLY)/SourceSerifPro-It.ttf.woff ] toolchain-only: $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources --output $(TOOLCHAIN_ONLY) --resource-suffix=-xxx x.rs From 82c6709d6fe46f6b7f2e7dc14e42eac1b5543080 Mon Sep 17 00:00:00 2001 From: JohnTitor Date: Thu, 1 Apr 2021 01:59:50 +0900 Subject: [PATCH 259/370] Clarify `--print target-list` is a rustc's option --- compiler/rustc_session/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 6540d461047..3692219cb6d 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -953,7 +953,7 @@ pub fn build_target_config(opts: &Options, target_override: Option) -> T opts.error_format, &format!( "Error loading target specification: {}. \ - Use `--print target-list` for a list of built-in targets", + Run `rustc --print target-list` for a list of built-in targets", e ), ) From 9acf558db426ac2875838d1bc5e499d57b1c3f99 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 31 Mar 2021 10:24:41 -0700 Subject: [PATCH 260/370] Update LLVM with another wasm simd fix Just a small bug fix for opcode numberings, not too major. --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index c3a26cbf6e7..0abbcc04d83 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit c3a26cbf6e73f2c5f8d03cee1f151d90a266ef3c +Subproject commit 0abbcc04d8375661a0637896b9ae5dc37a99dc70 From 29eb6860a8104f01ad4bac2b5560d9d66af14a99 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 31 Mar 2021 10:27:01 -0400 Subject: [PATCH 261/370] Give a better error when --theme is not a CSS file Before: ``` error: invalid argument: "bacon.toml" ``` After: ``` error: invalid argument: "bacon.toml" | = help: arguments to --theme must be CSS files ``` --- src/librustdoc/config.rs | 4 +++- src/test/rustdoc-ui/invalid-theme-name.rs | 3 +++ src/test/rustdoc-ui/invalid-theme-name.stderr | 4 ++++ src/tools/compiletest/src/runtest.rs | 3 +-- 4 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 src/test/rustdoc-ui/invalid-theme-name.rs create mode 100644 src/test/rustdoc-ui/invalid-theme-name.stderr diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index ecb6378f31f..471ac8f6cad 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -439,7 +439,9 @@ impl Options { return Err(1); } if theme_file.extension() != Some(OsStr::new("css")) { - diag.struct_err(&format!("invalid argument: \"{}\"", theme_s)).emit(); + diag.struct_err(&format!("invalid argument: \"{}\"", theme_s)) + .help("arguments to --theme must have a .css extension") + .emit(); return Err(1); } let (success, ret) = theme::test_theme_against(&theme_file, &paths, &diag); diff --git a/src/test/rustdoc-ui/invalid-theme-name.rs b/src/test/rustdoc-ui/invalid-theme-name.rs new file mode 100644 index 00000000000..c22ebf02718 --- /dev/null +++ b/src/test/rustdoc-ui/invalid-theme-name.rs @@ -0,0 +1,3 @@ +// compile-flags:--theme {{src-base}}/invalid-theme-name.rs +// error-pattern: invalid argument +// error-pattern: must have a .css extension diff --git a/src/test/rustdoc-ui/invalid-theme-name.stderr b/src/test/rustdoc-ui/invalid-theme-name.stderr new file mode 100644 index 00000000000..80204442dbe --- /dev/null +++ b/src/test/rustdoc-ui/invalid-theme-name.stderr @@ -0,0 +1,4 @@ +error: invalid argument: "$DIR/invalid-theme-name.rs" + | + = help: arguments to --theme must have a .css extension + diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 7aa3d4ab09e..91d4e3a26a9 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1909,8 +1909,7 @@ impl<'test> TestCx<'test> { } else { Command::new(&self.config.rustdoc_path.clone().expect("no rustdoc built yet")) }; - // FIXME Why is -L here? - rustc.arg(input_file); //.arg("-L").arg(&self.config.build_base); + rustc.arg(input_file); // Use a single thread for efficiency and a deterministic error message order rustc.arg("-Zthreads=1"); From 6530b3243a773a7e6d0bcf4f617fb74b18d8d1ea Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 31 Mar 2021 12:43:21 -0700 Subject: [PATCH 262/370] rustdoc: use Array.prototype.filter instead of open-coding it --- src/librustdoc/html/static/main.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index da2952bbebd..52c3ff68d91 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1338,17 +1338,11 @@ function hideThemeButtonState() { var valGenerics = extractGenerics(val); var paths = valLower.split("::"); - var j; - for (j = 0, len = paths.length; j < len; ++j) { - if (paths[j] === "") { - paths.splice(j, 1); - j -= 1; - } - } + paths = paths.filter(function(segment) { return segment !== ""; }); val = paths[paths.length - 1]; var contains = paths.slice(0, paths.length > 1 ? paths.length - 1 : 1); - var lev; + var lev, j; for (j = 0; j < nSearchWords; ++j) { ty = searchIndex[j]; if (!ty || (filterCrates !== undefined && ty.crate !== filterCrates)) { From 828179d687e0e6d75a1816c45bc866445d057e04 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 31 Mar 2021 22:13:47 +0200 Subject: [PATCH 263/370] Add a button to copy the "use statement" --- src/librustdoc/html/markdown.rs | 1 + src/librustdoc/html/render/print_item.rs | 1 + src/librustdoc/html/static/main.js | 25 +++++++++++++++++++++ src/librustdoc/html/static/noscript.css | 5 +++++ src/librustdoc/html/static/rustdoc.css | 25 ++++++++++++++------- src/librustdoc/html/static/themes/ayu.css | 5 +++-- src/librustdoc/html/static/themes/dark.css | 5 +++-- src/librustdoc/html/static/themes/light.css | 5 +++-- 8 files changed, 58 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index b39f9f87892..eecdf6fe0ce 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1354,6 +1354,7 @@ fn init_id_map() -> FxHashMap { map.insert("default-settings".to_owned(), 1); map.insert("rustdoc-vars".to_owned(), 1); map.insert("sidebar-vars".to_owned(), 1); + map.insert("copy-path".to_owned(), 1); // This is the list of IDs used by rustdoc sections. map.insert("fields".to_owned(), 1); map.insert("variants".to_owned(), 1); diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index cc93e55fc67..25314f87eb5 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -73,6 +73,7 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) } } write!(buf, "{}", item.type_(), item.name.as_ref().unwrap()); + write!(buf, ""); buf.write_str(""); // in-band buf.write_str(""); diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index da2952bbebd..f2e62ee7b6b 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -3061,3 +3061,28 @@ function hideThemeButtonState() { window.onhashchange = onHashChange; setupSearchLoader(); }()); + +function copy_path(but) { + var parent = but.parentElement; + var path = []; + + onEach(parent.childNodes, function(child) { + if (child.tagName === 'A') { + path.push(child.textContent); + } + }); + + var el = document.createElement('textarea'); + el.value = 'use ' + path.join('::') + ';'; + el.setAttribute('readonly', ''); + // To not make it appear on the screen. + el.style.position = 'absolute'; + el.style.left = '-9999px'; + + document.body.appendChild(el); + el.select(); + document.execCommand('copy'); + document.body.removeChild(el); + + but.textContent = '✓'; +} diff --git a/src/librustdoc/html/static/noscript.css b/src/librustdoc/html/static/noscript.css index c9fed989ec0..4d3332877c0 100644 --- a/src/librustdoc/html/static/noscript.css +++ b/src/librustdoc/html/static/noscript.css @@ -33,3 +33,8 @@ rules. /* Since there is no toggle (the "[-]") when JS is disabled, no need for this margin either. */ margin-left: 0 !important; } + +#copy-path { + /* It requires JS to work so no need to display it in this case. */ + display: none; +} diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 6c90fd7c9ee..6b2edf60f15 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1316,14 +1316,7 @@ h4 > .notable-traits { outline: none; } -.help-button { - right: 30px; - font-family: "Fira Sans", Arial, sans-serif; - text-align: center; - font-size: 17px; -} - -#theme-picker, #settings-menu, .help-button { +#theme-picker, #settings-menu, .help-button, #copy-path { padding: 4px; width: 27px; height: 29px; @@ -1332,6 +1325,22 @@ h4 > .notable-traits { cursor: pointer; } +.help-button { + right: 30px; + font-family: "Fira Sans", Arial, sans-serif; + text-align: center; + font-size: 17px; + padding-top: 2px; +} + +#copy-path { + height: 30px; + font-size: 18px; + margin-left: 10px; + padding: 0 6px; + width: 28px; +} + #theme-choices { display: none; position: absolute; diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index 7374aee71f8..b24f4035ca8 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -498,7 +498,7 @@ kbd { box-shadow-color: #c6cbd1; } -#theme-picker, #settings-menu, .help-button { +#theme-picker, #settings-menu, .help-button, #copy-path { border-color: #5c6773; background-color: #0f1419; color: #fff; @@ -510,7 +510,8 @@ kbd { #theme-picker:hover, #theme-picker:focus, #settings-menu:hover, #settings-menu:focus, -.help-button:hover, .help-button:focus { +.help-button:hover, .help-button:focus, +#copy-path:hover, #copy-path:focus { border-color: #e0e0e0; } diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index cf2d28bb43f..e863ed03f51 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -388,7 +388,7 @@ kbd { box-shadow-color: #c6cbd1; } -#theme-picker, #settings-menu, .help-button { +#theme-picker, #settings-menu, .help-button, #copy-path { border-color: #e0e0e0; background: #f0f0f0; color: #000; @@ -396,7 +396,8 @@ kbd { #theme-picker:hover, #theme-picker:focus, #settings-menu:hover, #settings-menu:focus, -.help-button:hover, .help-button:focus { +.help-button:hover, .help-button:focus, +#copy-path:hover, #copy-path:focus { border-color: #ffb900; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 7bf6793809c..9335dd96d29 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -380,14 +380,15 @@ kbd { box-shadow-color: #c6cbd1; } -#theme-picker, #settings-menu, .help-button { +#theme-picker, #settings-menu, .help-button, #copy-path { border-color: #e0e0e0; background-color: #fff; } #theme-picker:hover, #theme-picker:focus, #settings-menu:hover, #settings-menu:focus, -.help-button:hover, .help-button:focus { +.help-button:hover, .help-button:focus, +#copy-path:hover, #copy-path:focus { border-color: #717171; } From ad3a791e2a8c0300090fa73d4ce414a738346a41 Mon Sep 17 00:00:00 2001 From: The8472 Date: Wed, 31 Mar 2021 23:09:28 +0200 Subject: [PATCH 264/370] panic early when TrustedLen indicates a length > usize::MAX --- library/alloc/src/rc.rs | 7 +++++-- library/alloc/src/sync.rs | 7 +++++-- library/alloc/src/vec/mod.rs | 8 ++++++++ library/alloc/src/vec/spec_extend.rs | 7 ++++++- library/alloc/src/vec/spec_from_iter_nested.rs | 9 ++++++--- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index dac4acc4692..2ee5e6c791c 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1848,8 +1848,11 @@ impl> ToRcSlice for I { Rc::from_iter_exact(self, low) } } else { - // Fall back to normal implementation. - self.collect::>().into() + // TrustedLen contract guarantees that `upper_bound == `None` implies an iterator + // length exceeding `usize::MAX`. + // The default implementation would collect into a vec which would panic. + // Thus we panic here immediately without invoking `Vec` code. + panic!("capacity overflow"); } } } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index aeae888dddc..1b7e656cefd 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2481,8 +2481,11 @@ impl> ToArcSlice for I { Arc::from_iter_exact(self, low) } } else { - // Fall back to normal implementation. - self.collect::>().into() + // TrustedLen contract guarantees that `upper_bound == `None` implies an iterator + // length exceeding `usize::MAX`. + // The default implementation would collect into a vec which would panic. + // Thus we panic here immediately without invoking `Vec` code. + panic!("capacity overflow"); } } } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 20c2aae1789..91c3b16deee 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -410,6 +410,10 @@ impl Vec { /// /// [Capacity and reallocation]: #capacity-and-reallocation /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` bytes. + /// /// # Examples /// /// ``` @@ -541,6 +545,10 @@ impl Vec { /// /// [Capacity and reallocation]: #capacity-and-reallocation /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` bytes. + /// /// # Examples /// /// ``` diff --git a/library/alloc/src/vec/spec_extend.rs b/library/alloc/src/vec/spec_extend.rs index b6186a7ebaf..e132befcfa5 100644 --- a/library/alloc/src/vec/spec_extend.rs +++ b/library/alloc/src/vec/spec_extend.rs @@ -47,7 +47,12 @@ where }); } } else { - self.extend_desugared(iterator) + // Per TrustedLen contract a `None` upper bound means that the iterator length + // truly exceeds usize::MAX, which would eventually lead to a capacity overflow anyway. + // Since the other branch already panics eagerly (via `reserve()`) we do the same here. + // This avoids additional codegen for a fallback code path which would eventually + // panic anyway. + panic!("capacity overflow"); } } } diff --git a/library/alloc/src/vec/spec_from_iter_nested.rs b/library/alloc/src/vec/spec_from_iter_nested.rs index ec390c62165..948cf044197 100644 --- a/library/alloc/src/vec/spec_from_iter_nested.rs +++ b/library/alloc/src/vec/spec_from_iter_nested.rs @@ -46,10 +46,13 @@ where fn from_iter(iterator: I) -> Self { let mut vector = match iterator.size_hint() { (_, Some(upper)) => Vec::with_capacity(upper), - _ => Vec::new(), + // TrustedLen contract guarantees that `size_hint() == (_, None)` means that there + // are more than `usize::MAX` elements. + // Since the previous branch would eagerly panic if the capacity is too large + // (via `with_capacity`) we do the same here. + _ => panic!("capacity overflow"), }; - // must delegate to spec_extend() since extend() itself delegates - // to spec_from for empty Vecs + // reuse extend specialization for TrustedLen vector.spec_extend(iterator); vector } From 413938d7a9df4efe800552fa03ce1a5866539cbc Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 31 Mar 2021 17:23:32 -0400 Subject: [PATCH 265/370] Fix `--external-css` to be invocation-specific and note main.js should be invocation specific --- src/librustdoc/html/render/write_shared.rs | 11 ++++++++- src/test/run-make/emit-shared-files/Makefile | 24 ++++++++++++++------ src/test/run-make/emit-shared-files/y.css | 0 src/test/run-make/emit-shared-files/z.css | 0 4 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 src/test/run-make/emit-shared-files/y.css create mode 100644 src/test/run-make/emit-shared-files/z.css diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 34994097812..b2f2283c177 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -213,6 +213,9 @@ pub(super) fn write_shared( let mut themes: Vec<&String> = themes.iter().collect(); themes.sort(); + // FIXME: this should probably not be a toolchain file since it depends on `--theme`. + // But it seems a shame to copy it over and over when it's almost always the same. + // Maybe we can change the representation to move this out of main.js? write_minify( "main.js", &static_files::MAIN_JS.replace( @@ -238,7 +241,13 @@ pub(super) fn write_shared( if let Some(ref css) = cx.shared.layout.css_file_extension { let buffer = try_err!(fs::read_to_string(css), css); - write_minify("theme.css", &buffer)?; + // This varies based on the invocation, so it can't go through the write_minify wrapper. + cx.write_minify( + SharedResource::InvocationSpecific { basename: "theme.css" }, + &buffer, + options.enable_minification, + &options.emit, + )?; } write_minify("normalize.css", static_files::NORMALIZE_CSS)?; for (name, contents) in &*FILES_UNVERSIONED { diff --git a/src/test/run-make/emit-shared-files/Makefile b/src/test/run-make/emit-shared-files/Makefile index 66a36dae9d3..5c4825ae66c 100644 --- a/src/test/run-make/emit-shared-files/Makefile +++ b/src/test/run-make/emit-shared-files/Makefile @@ -7,30 +7,40 @@ ALL_SHARED = $(TMPDIR)/all-shared all: invocation-only toolchain-only all-shared invocation-only: - $(RUSTDOC) -Z unstable-options --emit=invocation-specific --output $(INVOCATION_ONLY) --resource-suffix=-xxx --theme y.css x.rs + $(RUSTDOC) -Z unstable-options --emit=invocation-specific --output $(INVOCATION_ONLY) --resource-suffix=-xxx --theme y.css --extend-css z.css x.rs [ -e $(INVOCATION_ONLY)/search-index-xxx.js ] [ -e $(INVOCATION_ONLY)/settings.html ] [ -e $(INVOCATION_ONLY)/x/all.html ] [ -e $(INVOCATION_ONLY)/x/index.html ] - # FIXME: this probably shouldn't have a suffix - [ -e $(INVOCATION_ONLY)/y-xxx.css ] + [ -e $(INVOCATION_ONLY)/theme-xxx.css ] # generated from z.css ! [ -e $(INVOCATION_ONLY)/storage-xxx.js ] ! [ -e $(INVOCATION_ONLY)/SourceSerifPro-It.ttf.woff ] + # FIXME: this probably shouldn't have a suffix + [ -e $(INVOCATION_ONLY)/y-xxx.css ] + # FIXME: this is technically incorrect (see `write_shared`) + ! [ -e $(INVOCATION_ONLY)/main-xxx.js ] + toolchain-only: - $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources --output $(TOOLCHAIN_ONLY) --resource-suffix=-xxx x.rs + $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources --output $(TOOLCHAIN_ONLY) --resource-suffix=-xxx --extend-css z.css x.rs [ -e $(TOOLCHAIN_ONLY)/storage-xxx.js ] - ! [ -e $(TOOLCHAIN_ONLY)/y-xxx.css ] ! [ -e $(TOOLCHAIN_ONLY)/SourceSerifPro-It.ttf.woff ] ! [ -e $(TOOLCHAIN_ONLY)/search-index-xxx.js ] ! [ -e $(TOOLCHAIN_ONLY)/x/index.html ] + ! [ -e $(TOOLCHAIN_ONLY)/theme.css ] + + [ -e $(TOOLCHAIN_ONLY)/main-xxx.js ] + ! [ -e $(TOOLCHAIN_ONLY)/y-xxx.css ] all-shared: - $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources,unversioned-shared-resources --output $(ALL_SHARED) --resource-suffix=-xxx x.rs + $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources,unversioned-shared-resources --output $(ALL_SHARED) --resource-suffix=-xxx --extend-css z.css x.rs [ -e $(ALL_SHARED)/storage-xxx.js ] [ -e $(ALL_SHARED)/SourceSerifPro-It.ttf.woff ] - ! [ -e $(ALL_SHARED)/y-xxx.css ] ! [ -e $(ALL_SHARED)/search-index-xxx.js ] ! [ -e $(ALL_SHARED)/settings.html ] ! [ -e $(ALL_SHARED)/x ] ! [ -e $(ALL_SHARED)/src ] + ! [ -e $(ALL_SHARED)/theme.css ] + + [ -e $(ALL_SHARED)/main-xxx.js ] + ! [ -e $(ALL_SHARED)/y-xxx.css ] diff --git a/src/test/run-make/emit-shared-files/y.css b/src/test/run-make/emit-shared-files/y.css new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/test/run-make/emit-shared-files/z.css b/src/test/run-make/emit-shared-files/z.css new file mode 100644 index 00000000000..e69de29bb2d From 3194b26ab00447662897fdfb98c01160456f9e08 Mon Sep 17 00:00:00 2001 From: b-naber Date: Tue, 23 Mar 2021 12:41:26 +0100 Subject: [PATCH 266/370] prevent very long compilation runtimes in LateBoundRegionNameCollector --- compiler/rustc_middle/src/ty/print/pretty.rs | 36 +++++++++++++++++--- src/test/ui/recursion/issue-83150.rs | 11 ++++++ src/test/ui/recursion/issue-83150.stderr | 8 +++++ 3 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/recursion/issue-83150.rs create mode 100644 src/test/ui/recursion/issue-83150.stderr diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index b8f39fce21d..f697cd51930 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -4,6 +4,7 @@ use crate::ty::subst::{GenericArg, GenericArgKind, Subst}; use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Ty, TyCtxt, TypeFoldable}; use rustc_apfloat::ieee::{Double, Single}; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sso::SsoHashSet; use rustc_hir as hir; use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -1421,7 +1422,8 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { } fn print_type(mut self, ty: Ty<'tcx>) -> Result { - if self.tcx.sess.type_length_limit().value_within_limit(self.printed_type_count) { + let type_length_limit = self.tcx.sess.type_length_limit(); + if type_length_limit.value_within_limit(self.printed_type_count) { self.printed_type_count += 1; self.pretty_print_type(ty) } else { @@ -1863,18 +1865,42 @@ impl FmtPrinter<'_, 'tcx, F> { where T: TypeFoldable<'tcx>, { - struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet); - impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> { + debug!("prepare_late_bound_region_info(value: {:?})", value); + + struct LateBoundRegionNameCollector<'a, 'tcx> { + used_region_names: &'a mut FxHashSet, + type_collector: SsoHashSet>, + } + + impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_, 'tcx> { + type BreakTy = (); + fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { + debug!("LateBoundRegionNameCollector::visit_region(r: {:?}, address: {:p})", r, &r); if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r { - self.0.insert(name); + self.used_region_names.insert(name); } r.super_visit_with(self) } + + // We collect types in order to prevent really large types from compiling for + // a really long time. See issue #83150 for why this is necessary. + fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { + debug!("LateBoundRegionNameCollector::visit_ty(ty: {:?}", ty); + let not_previously_inserted = self.type_collector.insert(ty); + if not_previously_inserted { + ty.super_visit_with(self) + } else { + ControlFlow::CONTINUE + } + } } self.used_region_names.clear(); - let mut collector = LateBoundRegionNameCollector(&mut self.used_region_names); + let mut collector = LateBoundRegionNameCollector { + used_region_names: &mut self.used_region_names, + type_collector: SsoHashSet::new(), + }; value.visit_with(&mut collector); self.region_index = 0; } diff --git a/src/test/ui/recursion/issue-83150.rs b/src/test/ui/recursion/issue-83150.rs new file mode 100644 index 00000000000..650ad22d206 --- /dev/null +++ b/src/test/ui/recursion/issue-83150.rs @@ -0,0 +1,11 @@ +// build-fail + //~^ overflow evaluating + +fn main() { + let mut iter = 0u8..1; + func(&mut iter) +} + +fn func>(iter: &mut T) { + func(&mut iter.map(|x| x + 1)) +} diff --git a/src/test/ui/recursion/issue-83150.stderr b/src/test/ui/recursion/issue-83150.stderr new file mode 100644 index 00000000000..943d5133097 --- /dev/null +++ b/src/test/ui/recursion/issue-83150.stderr @@ -0,0 +1,8 @@ +error[E0275]: overflow evaluating the requirement `Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>: Iterator` + | + = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`issue_83150`) + = note: required because of the requirements on the impl of `Iterator` for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>, [closure@$DIR/issue-83150.rs:10:24: 10:33]>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. From cb969e86a56f2440ef8be585e99477064c786d72 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 31 Mar 2021 17:45:03 -0700 Subject: [PATCH 267/370] Update cargo --- Cargo.lock | 3 ++- src/tools/cargo | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 284a1ba5482..0238b856cc2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -281,7 +281,7 @@ checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da" [[package]] name = "cargo" -version = "0.53.0" +version = "0.54.0" dependencies = [ "anyhow", "atty", @@ -326,6 +326,7 @@ dependencies = [ "serde", "serde_ignored", "serde_json", + "shell-escape", "strip-ansi-escapes", "tar", "tempfile", diff --git a/src/tools/cargo b/src/tools/cargo index 1e8703890f2..3c44c3c4b79 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 1e8703890f285befb5e32627ad4e0a0454dde1fb +Subproject commit 3c44c3c4b7900b8b13c85ead25ccaa8abb7d8989 From b5782bad743f596061e9c75d0a3f8a8ed8213b03 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 1 Apr 2021 10:45:42 +0900 Subject: [PATCH 268/370] Catch a bad placeholder type error for statics in `extern`s --- compiler/rustc_typeck/src/collect.rs | 10 ++++++++-- .../typeck/issue-83621-placeholder-static-in-extern.rs | 7 +++++++ .../issue-83621-placeholder-static-in-extern.stderr | 9 +++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/typeck/issue-83621-placeholder-static-in-extern.rs create mode 100644 src/test/ui/typeck/issue-83621-placeholder-static-in-extern.stderr diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 0ef5f4d1c18..479098a5a7a 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -735,8 +735,14 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { tcx.ensure().generics_of(item.def_id); tcx.ensure().type_of(item.def_id); tcx.ensure().predicates_of(item.def_id); - if let hir::ForeignItemKind::Fn(..) = item.kind { - tcx.ensure().fn_sig(item.def_id); + match item.kind { + hir::ForeignItemKind::Fn(..) => tcx.ensure().fn_sig(item.def_id), + hir::ForeignItemKind::Static(..) => { + let mut visitor = PlaceholderHirTyCollector::default(); + visitor.visit_foreign_item(item); + placeholder_type_error(tcx, None, &[], visitor.0, false, None); + } + _ => (), } } } diff --git a/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.rs b/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.rs new file mode 100644 index 00000000000..16ec2a54643 --- /dev/null +++ b/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.rs @@ -0,0 +1,7 @@ +// Regression test for #83621. + +extern "C" { + static x: _; //~ ERROR: [E0121] +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.stderr b/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.stderr new file mode 100644 index 00000000000..b1bec4c0827 --- /dev/null +++ b/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.stderr @@ -0,0 +1,9 @@ +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/issue-83621-placeholder-static-in-extern.rs:4:15 + | +LL | static x: _; + | ^ not allowed in type signatures + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0121`. From fe9c4fbb9e8e280ba17faf7a524f84c0c9e2774b Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 1 Apr 2021 10:56:51 +0900 Subject: [PATCH 269/370] Fix the `unsafe_block_in_unsafe_fn`s stabilized version --- compiler/rustc_feature/src/accepted.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index ce9f711b27e..f006351647e 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -276,7 +276,7 @@ declare_features! ( /// The smallest useful subset of `const_generics`. (accepted, min_const_generics, "1.51.0", Some(74878), None), /// The `unsafe_op_in_unsafe_fn` lint (allowed by default): no longer treat an unsafe function as an unsafe block. - (accepted, unsafe_block_in_unsafe_fn, "1.51.0", Some(71668), None), + (accepted, unsafe_block_in_unsafe_fn, "1.52.0", Some(71668), None), /// Allows the use of or-patterns (e.g., `0 | 1`). (accepted, or_patterns, "1.53.0", Some(54883), None), From 2e4215cb72a256b4843323ea5c9f1552e2c13a43 Mon Sep 17 00:00:00 2001 From: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com> Date: Thu, 1 Apr 2021 00:52:02 -0400 Subject: [PATCH 270/370] Fix minor typo in once.rs --- library/std/src/sync/once.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs index 2e5f843fc43..a24a5cb2ae3 100644 --- a/library/std/src/sync/once.rs +++ b/library/std/src/sync/once.rs @@ -471,7 +471,7 @@ fn wait(state_and_queue: &AtomicUsize, mut current_state: usize) { // If the managing thread happens to signal and unpark us before we // can park ourselves, the result could be this thread never gets // unparked. Luckily `park` comes with the guarantee that if it got - // an `unpark` just before on an unparked thread is does not park. + // an `unpark` just before on an unparked thread it does not park. thread::park(); } break; From d81f5ab100fce6646bfdfe309954de45efe5ca71 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 31 Mar 2021 15:38:11 +0000 Subject: [PATCH 271/370] Inline some functions that suddenly show up more in traces --- compiler/rustc_middle/src/ty/instance.rs | 1 + compiler/rustc_middle/src/ty/normalize_erasing_regions.rs | 1 + compiler/rustc_middle/src/ty/subst.rs | 4 +--- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index a753c4ab6ce..41d953216e0 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -483,6 +483,7 @@ impl<'tcx> Instance<'tcx> { if let Some(substs) = self.substs_for_mir_body() { v.subst(tcx, substs) } else { *v } } + #[inline(always)] pub fn subst_mir_and_normalize_erasing_regions( &self, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 2a8502cab41..071d908655f 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -103,6 +103,7 @@ impl TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> { self.tcx.normalize_generic_arg_after_erasing_regions(arg).expect_const() } + #[inline] fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { let arg = self.param_env.and(c); self.tcx.normalize_mir_const_after_erasing_regions(arg) diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 48db2d11f52..0eb379219eb 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -505,10 +505,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { } } + #[inline] fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { - if !c.needs_subst() { - return c; - } c.super_fold_with(self) } } From 49705e0709eb4d04b6d9fa8c43e0fb07b2939e44 Mon Sep 17 00:00:00 2001 From: Hameer Abbasi Date: Thu, 1 Apr 2021 09:24:01 +0000 Subject: [PATCH 272/370] Limit the problematic tests to x86_64. --- .../union-const-eval-field.32bit.stderr | 14 ------ .../const-eval/union-const-eval-field.rs | 2 +- ...t.stderr => union-const-eval-field.stderr} | 0 .../consts/const-eval/union-ice.32bit.stderr | 47 ------------------- src/test/ui/consts/const-eval/union-ice.rs | 2 +- ...nion-ice.64bit.stderr => union-ice.stderr} | 0 6 files changed, 2 insertions(+), 63 deletions(-) delete mode 100644 src/test/ui/consts/const-eval/union-const-eval-field.32bit.stderr rename src/test/ui/consts/const-eval/{union-const-eval-field.64bit.stderr => union-const-eval-field.stderr} (100%) delete mode 100644 src/test/ui/consts/const-eval/union-ice.32bit.stderr rename src/test/ui/consts/const-eval/{union-ice.64bit.stderr => union-ice.stderr} (100%) diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.32bit.stderr b/src/test/ui/consts/const-eval/union-const-eval-field.32bit.stderr deleted file mode 100644 index 472bd214de7..00000000000 --- a/src/test/ui/consts/const-eval/union-const-eval-field.32bit.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0080]: it is undefined behavior to use this value - --> $DIR/union-const-eval-field.rs:29:5 - | -LL | const FIELD3: Field3 = unsafe { UNION.field3 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 8, align: 4) { - __ __ __ __ __ __ __ __ │ ░░░░░░░░ - } - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.rs b/src/test/ui/consts/const-eval/union-const-eval-field.rs index c91ed0acb2e..f8e1d6d569d 100644 --- a/src/test/ui/consts/const-eval/union-const-eval-field.rs +++ b/src/test/ui/consts/const-eval/union-const-eval-field.rs @@ -1,4 +1,4 @@ -// stderr-per-bitwidth +// only-x86_64 #![feature(const_fn)] type Field1 = i32; diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.64bit.stderr b/src/test/ui/consts/const-eval/union-const-eval-field.stderr similarity index 100% rename from src/test/ui/consts/const-eval/union-const-eval-field.64bit.stderr rename to src/test/ui/consts/const-eval/union-const-eval-field.stderr diff --git a/src/test/ui/consts/const-eval/union-ice.32bit.stderr b/src/test/ui/consts/const-eval/union-ice.32bit.stderr deleted file mode 100644 index f8502ad66c5..00000000000 --- a/src/test/ui/consts/const-eval/union-ice.32bit.stderr +++ /dev/null @@ -1,47 +0,0 @@ -error[E0080]: it is undefined behavior to use this value - --> $DIR/union-ice.rs:15:1 - | -LL | const FIELD3: Field3 = unsafe { UNION.field3 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 8, align: 4) { - __ __ __ __ __ __ __ __ │ ░░░░░░░░ - } - -error[E0080]: it is undefined behavior to use this value - --> $DIR/union-ice.rs:17:1 - | -LL | / const FIELD_PATH: Struct = Struct { -LL | | a: 42, -LL | | b: unsafe { UNION.field3 }, -LL | | }; - | |__^ type validation failed: encountered uninitialized bytes at .b, but expected initialized plain (non-pointer) bytes - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 12, align: 4) { - __ __ __ __ __ __ __ __ 2a __ __ __ │ ░░░░░░░░*░░░ - } - -error[E0080]: it is undefined behavior to use this value - --> $DIR/union-ice.rs:27:1 - | -LL | / const FIELD_PATH2: Struct2 = Struct2 { -LL | | b: [ -LL | | 21, -LL | | unsafe { UNION.field3 }, -... | -LL | | a: 42, -LL | | }; - | |__^ type validation failed: encountered uninitialized bytes at .b[1] - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 36, align: 4) { - 0x00 │ 15 00 00 00 00 00 00 00 __ __ __ __ __ __ __ __ │ ........░░░░░░░░ - 0x10 │ 17 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 │ ................ - 0x20 │ 2a __ __ __ │ *░░░ - } - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/union-ice.rs b/src/test/ui/consts/const-eval/union-ice.rs index c1e780d9bb7..40e5a005ba4 100644 --- a/src/test/ui/consts/const-eval/union-ice.rs +++ b/src/test/ui/consts/const-eval/union-ice.rs @@ -1,4 +1,4 @@ -// stderr-per-bitwidth +// only-x86_64 #![feature(const_fn)] type Field1 = i32; diff --git a/src/test/ui/consts/const-eval/union-ice.64bit.stderr b/src/test/ui/consts/const-eval/union-ice.stderr similarity index 100% rename from src/test/ui/consts/const-eval/union-ice.64bit.stderr rename to src/test/ui/consts/const-eval/union-ice.stderr From c6676db7aecc217d86dc1a478ca28b61acac87f4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 1 Apr 2021 10:40:50 +0000 Subject: [PATCH 273/370] Some more fine-grained forced inlining --- compiler/rustc_middle/src/mir/type_foldable.rs | 1 + compiler/rustc_mir/src/interpret/eval_context.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index ceed4fd2467..f3124e5bf42 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -348,6 +348,7 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> { + #[inline(always)] fn fold_with>(self, folder: &mut F) -> Self { folder.fold_mir_const(self) } diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 149a9f81ea0..a0e912c84d5 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -527,6 +527,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } + #[inline(always)] pub fn layout_of_local( &self, frame: &Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>, From a38d3cb17aed86e9cf977b571926954224c43869 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 1 Apr 2021 20:43:44 +0900 Subject: [PATCH 274/370] Add my new email address to .mailmap --- .mailmap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index 3f23aed31a8..1019710dc97 100644 --- a/.mailmap +++ b/.mailmap @@ -286,7 +286,7 @@ Xuefeng Wu Xuefeng Wu Xuefeng Wu XuefengWu York Xiang Youngsoo Son -Yuki Okushi +Yuki Okushi Zach Pomerantz Zack Corr Zack Slayton From 2c66e154681087f8c1da6809e41e23c1e0962d30 Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Thu, 25 Mar 2021 21:42:21 +0800 Subject: [PATCH 275/370] add OR_PATTERNS_BACK_COMPAT lint test: add more cases test: add comments refine msg --- compiler/rustc_expand/src/mbe/macro_rules.rs | 42 +++++++++++++++++-- compiler/rustc_lint/src/context.rs | 3 ++ compiler/rustc_lint_defs/src/builtin.rs | 35 ++++++++++++++++ compiler/rustc_lint_defs/src/lib.rs | 1 + .../macro-or-patterns-back-compat.fixed | 26 ++++++++++++ .../macros/macro-or-patterns-back-compat.rs | 26 ++++++++++++ .../macro-or-patterns-back-compat.stderr | 32 ++++++++++++++ 7 files changed, 162 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/macros/macro-or-patterns-back-compat.fixed create mode 100644 src/test/ui/macros/macro-or-patterns-back-compat.rs create mode 100644 src/test/ui/macros/macro-or-patterns-back-compat.stderr diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 9ed478e6fcc..a85ed18055b 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -18,7 +18,8 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_feature::Features; -use rustc_lint_defs::builtin::SEMICOLON_IN_EXPRESSIONS_FROM_MACROS; +use rustc_lint_defs::builtin::{OR_PATTERNS_BACK_COMPAT, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS}; +use rustc_lint_defs::BuiltinLintDiagnostics; use rustc_parse::parser::Parser; use rustc_session::parse::ParseSess; use rustc_session::Session; @@ -951,8 +952,32 @@ fn check_matcher_core( // Now `last` holds the complete set of NT tokens that could // end the sequence before SUFFIX. Check that every one works with `suffix`. for token in &last.tokens { - if let TokenTree::MetaVarDecl(_, name, Some(kind)) = *token { + if let TokenTree::MetaVarDecl(span, name, Some(kind)) = *token { for next_token in &suffix_first.tokens { + // Check if the old pat is used and the next token is `|`. + if let NonterminalKind::Pat2015 { inferred: true } = kind { + if let TokenTree::Token(token) = next_token { + if let BinOp(token) = token.kind { + if let token::BinOpToken::Or = token { + // It is suggestion to use pat2015, for example: $x:pat -> $x:pat2015. + let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl( + span, + name, + Some(NonterminalKind::Pat2015 { inferred: false }), + )); + sess.buffer_lint_with_diagnostic( + &OR_PATTERNS_BACK_COMPAT, + span, + ast::CRATE_NODE_ID, + &*format!("the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro",), + BuiltinLintDiagnostics::OrPatternsBackCompat( + span, suggestion, + ), + ); + } + } + } + } match is_in_follow(next_token, kind) { IsInFollow::Yes => {} IsInFollow::No(possible) => { @@ -1080,7 +1105,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { _ => IsInFollow::No(TOKENS), } } - NonterminalKind::Pat2015 { .. } | NonterminalKind::Pat2021 { .. } => { + NonterminalKind::Pat2015 { .. } => { const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"]; match tok { TokenTree::Token(token) => match token.kind { @@ -1091,6 +1116,17 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { _ => IsInFollow::No(TOKENS), } } + NonterminalKind::Pat2021 { .. } => { + const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`if`", "`in`"]; + match tok { + TokenTree::Token(token) => match token.kind { + FatArrow | Comma | Eq => IsInFollow::Yes, + Ident(name, false) if name == kw::If || name == kw::In => IsInFollow::Yes, + _ => IsInFollow::No(TOKENS), + }, + _ => IsInFollow::No(TOKENS), + } + } NonterminalKind::Path | NonterminalKind::Ty => { const TOKENS: &[&str] = &[ "`{`", "`[`", "`=>`", "`,`", "`>`", "`=`", "`:`", "`;`", "`|`", "`as`", diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 14bd823ea22..b3a19bfbf75 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -709,6 +709,9 @@ pub trait LintContext: Sized { BuiltinLintDiagnostics::ProcMacroBackCompat(note) => { db.note(¬e); } + BuiltinLintDiagnostics::OrPatternsBackCompat(span,suggestion) => { + db.span_suggestion(span, "use pat2015 to preserve semantics", suggestion, Applicability::MachineApplicable); + } } // Rewrap `db`, and pass control to the user. decorate(LintDiagnosticBuilder::new(db)); diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 4eaee7bf6e8..b602490905c 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2959,6 +2959,7 @@ declare_lint_pass! { DISJOINT_CAPTURE_DROP_REORDER, LEGACY_DERIVE_HELPERS, PROC_MACRO_BACK_COMPAT, + OR_PATTERNS_BACK_COMPAT, ] } @@ -3136,3 +3137,37 @@ declare_lint! { }) }; } + +declare_lint! { + /// The `or_patterns_back_compat` lint detects usage of old versions of or-patterns. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![deny(or_patterns_back_compat)] + /// macro_rules! match_any { + /// ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => { + /// match $expr { + /// $( + /// $( $pat => $expr_arm, )+ + /// )+ + /// } + /// }; + /// } + /// + /// fn main() { + /// let result: Result = Err(42); + /// let int: i64 = match_any!(result, Ok(i) | Err(i) => i.into()); + /// assert_eq!(int, 42); + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// In Rust 2021, the pat matcher will match new patterns, which include the | character. + pub OR_PATTERNS_BACK_COMPAT, + Allow, + "detects usage of old versions of or-patterns", +} diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 400b367095e..70475563a4a 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -267,6 +267,7 @@ pub enum BuiltinLintDiagnostics { LegacyDeriveHelpers(Span), ExternDepSpec(String, ExternDepSpec), ProcMacroBackCompat(String), + OrPatternsBackCompat(Span, String), } /// Lints that are buffered up early on in the `Session` before the diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.fixed b/src/test/ui/macros/macro-or-patterns-back-compat.fixed new file mode 100644 index 00000000000..60ec0f7430d --- /dev/null +++ b/src/test/ui/macros/macro-or-patterns-back-compat.fixed @@ -0,0 +1,26 @@ +// ignore-tidy-linelength +// run-rustfix + +#![feature(edition_macro_pats)] +#![deny(or_patterns_back_compat)] +#![allow(unused_macros)] +macro_rules! foo { ($x:pat2015 | $y:pat) => {} } //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +macro_rules! bar { ($($x:pat2015)+ | $($y:pat)+) => {} } //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +macro_rules! baz { ($x:pat2015 | $y:pat2015) => {} } // should be ok +macro_rules! qux { ($x:pat2015 | $y:pat) => {} } // should be ok +macro_rules! ogg { ($x:pat2015 | $y:pat2015) => {} } //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +macro_rules! match_any { + ( $expr:expr , $( $( $pat:pat2015 )|+ => $expr_arm:expr ),+ ) => { //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro + match $expr { + $( + $( $pat => $expr_arm, )+ + )+ + } + }; +} + +fn main() { + let result: Result = Err(42); + let int: i64 = match_any!(result, Ok(i) | Err(i) => i.into()); + assert_eq!(int, 42); +} diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.rs b/src/test/ui/macros/macro-or-patterns-back-compat.rs new file mode 100644 index 00000000000..dc9e8595ca2 --- /dev/null +++ b/src/test/ui/macros/macro-or-patterns-back-compat.rs @@ -0,0 +1,26 @@ +// ignore-tidy-linelength +// run-rustfix + +#![feature(edition_macro_pats)] +#![deny(or_patterns_back_compat)] +#![allow(unused_macros)] +macro_rules! foo { ($x:pat | $y:pat) => {} } //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} } //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +macro_rules! baz { ($x:pat2015 | $y:pat2015) => {} } // should be ok +macro_rules! qux { ($x:pat2015 | $y:pat) => {} } // should be ok +macro_rules! ogg { ($x:pat | $y:pat2015) => {} } //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +macro_rules! match_any { + ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => { //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro + match $expr { + $( + $( $pat => $expr_arm, )+ + )+ + } + }; +} + +fn main() { + let result: Result = Err(42); + let int: i64 = match_any!(result, Ok(i) | Err(i) => i.into()); + assert_eq!(int, 42); +} diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.stderr b/src/test/ui/macros/macro-or-patterns-back-compat.stderr new file mode 100644 index 00000000000..630a11c1734 --- /dev/null +++ b/src/test/ui/macros/macro-or-patterns-back-compat.stderr @@ -0,0 +1,32 @@ +error: the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro + --> $DIR/macro-or-patterns-back-compat.rs:7:21 + | +LL | macro_rules! foo { ($x:pat | $y:pat) => {} } + | ^^^^^^ help: use pat2015 to preserve semantics: `$x:pat2015` + | +note: the lint level is defined here + --> $DIR/macro-or-patterns-back-compat.rs:5:9 + | +LL | #![deny(or_patterns_back_compat)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro + --> $DIR/macro-or-patterns-back-compat.rs:8:23 + | +LL | macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} } + | ^^^^^^ help: use pat2015 to preserve semantics: `$x:pat2015` + +error: the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro + --> $DIR/macro-or-patterns-back-compat.rs:11:21 + | +LL | macro_rules! ogg { ($x:pat | $y:pat2015) => {} } + | ^^^^^^ help: use pat2015 to preserve semantics: `$x:pat2015` + +error: the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro + --> $DIR/macro-or-patterns-back-compat.rs:13:26 + | +LL | ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => { + | ^^^^^^^^ help: use pat2015 to preserve semantics: `$pat:pat2015` + +error: aborting due to 4 previous errors + From 4464cc2256b2ccf5fbdaaf60135db11537d5bff9 Mon Sep 17 00:00:00 2001 From: AngelicosPhosphoros Date: Tue, 30 Mar 2021 00:19:10 +0300 Subject: [PATCH 276/370] Simplify logical operations CFG This is basically same commit as e38e954a0d249f88d0a55504f70d6055e865a931 which was reverted later in 676953fde9120cda62e4ef2f75a804af7481d6af In both cases, this changes weren't benchmarked. e38e954a0d249f88d0a55504f70d6055e865a931 leads to missed optimization described in [this issue](https://github.com/rust-lang/rust/issues/62993) 676953fde9120cda62e4ef2f75a804af7481d6af leads to missed optimization described in [this issue](https://github.com/rust-lang/rust/issues/83623) Also it changes some src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump* files automatically. --- .../rustc_mir_build/src/build/expr/into.rs | 63 ++- .../codegen/issue-83623-SIMD-PartialEq.rs | 46 +++ ...ons.main.-------.InstrumentCoverage.0.html | 382 +++++++++--------- ...ean.main.-------.InstrumentCoverage.0.html | 170 ++++---- ...pl#6}-eq.-------.InstrumentCoverage.0.html | 2 +- ...pl#6}-ne.-------.InstrumentCoverage.0.html | 2 +- ...used.foo.-------.InstrumentCoverage.0.html | 10 +- ...ate_func.-------.InstrumentCoverage.0.html | 10 +- 8 files changed, 360 insertions(+), 325 deletions(-) create mode 100644 src/test/codegen/issue-83623-SIMD-PartialEq.rs diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 2097f38c25d..80a5bff8cad 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -111,18 +111,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ExprKind::LogicalOp { op, lhs, rhs } => { // And: // - // [block: If(lhs)] -true-> [else_block: If(rhs)] -true-> [true_block] - // | | (false) - // +----------false-----------+------------------> [false_block] + // [block: If(lhs)] -true-> [else_block: dest = (rhs)] + // | (false) + // [shortcurcuit_block: dest = false] // // Or: // - // [block: If(lhs)] -false-> [else_block: If(rhs)] -true-> [true_block] - // | (true) | (false) - // [true_block] [false_block] + // [block: If(lhs)] -false-> [else_block: dest = (rhs)] + // | (true) + // [shortcurcuit_block: dest = true] - let (true_block, false_block, mut else_block, join_block) = ( - this.cfg.start_new_block(), + let (shortcircuit_block, mut else_block, join_block) = ( this.cfg.start_new_block(), this.cfg.start_new_block(), this.cfg.start_new_block(), @@ -130,41 +129,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let lhs = unpack!(block = this.as_local_operand(block, lhs)); let blocks = match op { - LogicalOp::And => (else_block, false_block), - LogicalOp::Or => (true_block, else_block), + LogicalOp::And => (else_block, shortcircuit_block), + LogicalOp::Or => (shortcircuit_block, else_block), }; let term = TerminatorKind::if_(this.tcx, lhs, blocks.0, blocks.1); this.cfg.terminate(block, source_info, term); + this.cfg.push_assign_constant( + shortcircuit_block, + source_info, + destination, + Constant { + span: expr_span, + user_ty: None, + literal: match op { + LogicalOp::And => ty::Const::from_bool(this.tcx, false).into(), + LogicalOp::Or => ty::Const::from_bool(this.tcx, true).into(), + }, + }, + ); + this.cfg.goto(shortcircuit_block, source_info, join_block); + let rhs = unpack!(else_block = this.as_local_operand(else_block, rhs)); - let term = TerminatorKind::if_(this.tcx, rhs, true_block, false_block); - this.cfg.terminate(else_block, source_info, term); + this.cfg.push_assign(else_block, source_info, destination, Rvalue::Use(rhs)); + this.cfg.goto(else_block, source_info, join_block); - this.cfg.push_assign_constant( - true_block, - source_info, - destination, - Constant { - span: expr_span, - user_ty: None, - literal: ty::Const::from_bool(this.tcx, true).into(), - }, - ); - - this.cfg.push_assign_constant( - false_block, - source_info, - destination, - Constant { - span: expr_span, - user_ty: None, - literal: ty::Const::from_bool(this.tcx, false).into(), - }, - ); - - // Link up both branches: - this.cfg.goto(true_block, source_info, join_block); - this.cfg.goto(false_block, source_info, join_block); join_block.unit() } ExprKind::Loop { body } => { diff --git a/src/test/codegen/issue-83623-SIMD-PartialEq.rs b/src/test/codegen/issue-83623-SIMD-PartialEq.rs new file mode 100644 index 00000000000..b22b7f52402 --- /dev/null +++ b/src/test/codegen/issue-83623-SIMD-PartialEq.rs @@ -0,0 +1,46 @@ +// This test checks that jumps generated by logical operators can be optimized away + +// compile-flags: -Copt-level=3 +// only-64bit + +#![crate_type="lib"] + +pub struct Blueprint { + pub fuel_tank_size: u32, + pub payload: u32, + pub wheel_diameter: u32, + pub wheel_width: u32, + pub storage: u32, +} + +// && chains should not prevent SIMD optimizations for primitives +impl PartialEq for Blueprint{ + fn eq(&self, other: &Self)->bool{ + // CHECK-NOT: call{{.*}}bcmp + // CHECK-NOT: call{{.*}}memcmp + // CHECK-NOT: br {{.*}} + self.fuel_tank_size == other.fuel_tank_size + && self.payload == other.payload + && self.wheel_diameter == other.wheel_diameter + && self.wheel_width == other.wheel_width + && self.storage == other.storage + } +} + +#[derive(PartialEq)] +pub struct Blueprint2 { + pub fuel_tank_size: u32, + pub payload: u32, + pub wheel_diameter: u32, + pub wheel_width: u32, + pub storage: u32, +} + +// Derived PartialEq should not generate jumps and should use SIMD +#[no_mangle] +pub fn partial_eq_should_not_jump(a: &Blueprint2, b:&Blueprint2)->bool{ + // CHECK-NOT: call{{.*}}bcmp + // CHECK-NOT: call{{.*}}memcmp + // CHECK-NOT: br {{.*}} + a==b +} diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.conditions/conditions.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.conditions/conditions.main.-------.InstrumentCoverage.0.html index 0aa6fe65686..3d1b737ec2d 100644 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.conditions/conditions.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.conditions/conditions.main.-------.InstrumentCoverage.0.html @@ -83,7 +83,7 @@ For revisions in Pull Requests (PR): 5:13-7:6: @1[1]: _2 = const ()"> }⦉@1@2⦊⦉@2 const B: u32 = 100; - let @21⦊x⦉@21 = if let @19⦊x⦉@19 = if @3⦊countdown > 7⦉@3 { } else if @5⦊countdown > 2⦉@5 { if @7⦊countdown < 1⦉@7 || @15⦊countdown > 5⦉@15 || @11⦊countdown != 9⦉@11 @17⦊{ - countdown = 0; - }⦉@17@18⦊⦉@18 - @19,20⦊countdown -= 5; - countdown⦉@19,20 +14:12-14:25: @7[6]: _13 = Lt(move _14, const 1_u32)">@7⦊countdown < 1⦉@7 || @13⦊countdown > 5⦉@13 || @10⦊countdown != 9⦉@10 @15⦊{ + countdown = 0; + }⦉@15@16⦊⦉@16 + @17,18⦊countdown -= 5; + countdown⦉@17,18 } else { @8⦊return⦉@8; }; - let @21⦊mut countdown = 0; - if true⦉@21 @22⦊{ - countdown = 10; - }⦉@22@23⦊⦉@23 + let @19⦊mut countdown = 0; + if true⦉@19 @20⦊{ + countdown = 10; + }⦉@20@21⦊⦉@21 - if @24⦊countdown > 7⦉@24 @25,27⦊{ - countdown -= 4; - }⦉@25,27 else if @26⦊countdown > 2⦉@26 { - if @28⦊countdown < 1⦉@28 || @36⦊countdown > 5⦉@36 || @32⦊countdown != 9⦉@32 @38⦊{ - countdown = 0; - }⦉@38@39⦊⦉@39 - @40,41⦊countdown -= 5⦉@40,41; + if @22⦊countdown > 7⦉@22 @23,25⦊{ + countdown -= 4; + }⦉@23,25 else if @24⦊countdown > 2⦉@24 { + if @26⦊countdown < 1⦉@26 || @32⦊countdown > 5⦉@32 || @29⦊countdown != 9⦉@29 @34⦊{ + countdown = 0; + }⦉@34@35⦊⦉@35 + @36,37⦊countdown -= 5⦉@36,37; } else { - @29⦊return⦉@29; + @27⦊return⦉@27; } - if @42⦊true⦉@42 { - let @43⦊mut countdown = 0; - if true⦉@43 @45⦊{ - countdown = 10; - }⦉@45@46⦊⦉@46 + if @38⦊true⦉@38 { + let @39⦊mut countdown = 0; + if true⦉@39 @41⦊{ + countdown = 10; + }⦉@41@42⦊⦉@42 - if @47⦊countdown > 7⦉@47 @48,50⦊{ - countdown -= 4; - }⦉@48,50 - else if @49⦊countdown > 2⦉@49 { - if @51⦊countdown < 1⦉@51 || @59⦊countdown > 5⦉@59 || @55⦊countdown != 9⦉@55 @61⦊{ - countdown = 0; - }⦉@61@62⦊⦉@62 - @63,64⦊countdown -= 5⦉@63,64; + if @43⦊countdown > 7⦉@43 @44,46⦊{ + countdown -= 4; + }⦉@44,46 + else if @45⦊countdown > 2⦉@45 { + if @47⦊countdown < 1⦉@47 || @53⦊countdown > 5⦉@53 || @50⦊countdown != 9⦉@50 @55⦊{ + countdown = 0; + }⦉@55@56⦊⦉@56 + @57,58⦊countdown -= 5⦉@57,58; } else { - @52⦊return⦉@52; + @48⦊return⦉@48; } - }@44⦊⦉@44 // Note: closing brace shows uncovered (vs. `0` for implicit else) because condition literal + }@40⦊⦉@40 // Note: closing brace shows uncovered (vs. `0` for implicit else) because condition literal // `true` was const-evaluated. The compiler knows the `if` block will be executed. - let @66⦊mut countdown = 0; - if true⦉@66 @67⦊{ - countdown = 1; - }⦉@67@68⦊⦉@68 + let @60⦊mut countdown = 0; + if true⦉@60 @61⦊{ + countdown = 1; + }⦉@61@62⦊⦉@62 - let @89⦊z⦉@89 = if @69⦊countdown > 7⦉@69 @70,72⦊{ - countdown -= 4; - }⦉@70,72 else if @71⦊countdown > 2⦉@71 { - if @73⦊countdown < 1⦉@73 || @81⦊countdown > 5⦉@81 || @77⦊countdown != 9⦉@77 @83⦊{ - countdown = 0; - }⦉@83@84⦊⦉@84 - @85,86⦊countdown -= 5⦉@85,86; + let @81⦊z⦉@81 = if @63⦊countdown > 7⦉@63 @64,66⦊{ + countdown -= 4; + }⦉@64,66 else if @65⦊countdown > 2⦉@65 { + if @67⦊countdown < 1⦉@67 || @73⦊countdown > 5⦉@73 || @70⦊countdown != 9⦉@70 @75⦊{ + countdown = 0; + }⦉@75@76⦊⦉@76 + @77,78⦊countdown -= 5⦉@77,78; } else { - let @74,87,88⦊should_be_reachable = countdown; - println!("reached"); - return⦉@74,87,88; + let @68,79,80⦊should_be_reachable = countdown; + println!("reached"); + return⦉@68,79,80; }; - let @107⦊w⦉@107 = if @89⦊countdown > 7⦉@89 @90,92⦊{ - countdown -= 4; - }⦉@90,92 else if @91⦊countdown > 2⦉@91 { - if @93⦊countdown < 1⦉@93 || @101⦊countdown > 5⦉@101 || @97⦊countdown != 9⦉@97 @103⦊{ - countdown = 0; - }⦉@103@104⦊⦉@104 - @105,106⦊countdown -= 5⦉@105,106; + let @97⦊w⦉@97 = if @81⦊countdown > 7⦉@81 @82,84⦊{ + countdown -= 4; + }⦉@82,84 else if @83⦊countdown > 2⦉@83 { + if @85⦊countdown < 1⦉@85 || @91⦊countdown > 5⦉@91 || @88⦊countdown != 9⦉@88 @93⦊{ + countdown = 0; + }⦉@93@94⦊⦉@94 + @95,96⦊countdown -= 5⦉@95,96; } else { - @94⦊return⦉@94; + @86⦊return⦉@86; }; -}@111⦊⦉@111 +}@101⦊⦉@101 diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html index 358e2e2bbba..a6f8d500065 100644 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html @@ -69,9 +69,9 @@ For revisions in Pull Requests (PR): -

@0,1,2,3⦊fn main() { - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let is_true = std::env::args().len() == 1; - - let (mut a, mut b, mut c) = (0, 0, 0); - }⦉@4@5⦊⦉@5 let - @10⦊somebool⦉@10 + @9⦊somebool⦉@9 = @6⦊a < b⦉@6 || - @9⦊b < c⦉@9 + @8⦊b < c⦉@8 ; let - @14⦊somebool⦉@14 + @12⦊somebool⦉@12 = - @10⦊b < a⦉@10 + @9⦊b < a⦉@9 || - @13⦊b < c⦉@13 + @11⦊b < c⦉@11 ; - let @18⦊somebool⦉@18 = @14⦊a < b⦉@14 && @17⦊b < c⦉@17; - let @22⦊somebool⦉@22 = @18⦊b < a⦉@18 && @21⦊b < c⦉@21; + let @15⦊somebool⦉@15 = @12⦊a < b⦉@12 && @14⦊b < c⦉@14; + let @18⦊somebool⦉@18 = @15⦊b < a⦉@15 && @17⦊b < c⦉@17; if - @22⦊! - is_true⦉@22 - @23⦊{ - a = 2 - ; - }⦉@23@24⦊⦉@24 + @18⦊! + is_true⦉@18 + @19⦊{ + a = 2 + ; + }⦉@19@20⦊⦉@20 if - @25⦊is_true⦉@25 - @26⦊{ - b = 30 - ; - }⦉@26 + @21⦊is_true⦉@21 + @22⦊{ + b = 30 + ; + }⦉@22 else - @27⦊{ - c = 400 - ; - }⦉@27 + @23⦊{ + c = 400 + ; + }⦉@23 - if @28⦊!is_true⦉@28 @29⦊{ - a = 2; - }⦉@29@30⦊⦉@30 + if @24⦊!is_true⦉@24 @25⦊{ + a = 2; + }⦉@25@26⦊⦉@26 - if @31⦊is_true⦉@31 @32⦊{ - b = 30; - }⦉@32 else @33⦊{ - c = 400; - }⦉@33 -}@34⦊⦉@34
+ if @27⦊is_true⦉@27 @28⦊{ + b = 30; + }⦉@28 else @29⦊{ + c = 400; + }⦉@29 +}@30⦊⦉@30 diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-eq.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-eq.-------.InstrumentCoverage.0.html index 2e128181c5e..9858b270d7e 100644 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-eq.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-eq.-------.InstrumentCoverage.0.html @@ -69,6 +69,6 @@ For revisions in Pull Requests (PR): -
@0⦊⦉@0PartialEq@4⦊⦉@4
+
@0⦊⦉@0PartialEq@3⦊⦉@3
diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-ne.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-ne.-------.InstrumentCoverage.0.html index 637b1c62086..bf94e5cbf73 100644 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-ne.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-ne.-------.InstrumentCoverage.0.html @@ -69,6 +69,6 @@ For revisions in Pull Requests (PR): -
@0⦊⦉@0PartialEq@4⦊⦉@4
+
@0⦊⦉@0PartialEq@3⦊⦉@3
diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.foo.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.foo.-------.InstrumentCoverage.0.html index 45fec46f55c..ef431a356c2 100644 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.foo.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.foo.-------.InstrumentCoverage.0.html @@ -77,11 +77,11 @@ For revisions in Pull Requests (PR): 3:11-3:17: @2[3]: _4 = Lt(move _5, const 10_i32) 3:11-3:17: @2[5]: FakeRead(ForMatchedPlace, _4)">@1,2⦊i < 10⦉@1,2
{ @3,5⦊i != 0⦉@3,5 || @8⦊i != 0⦉@8; - @9,10⦊i += 1⦉@9,10; +4:9-4:15: @5[4]: _7 = Ne(move _8, const 0_i32)">@3,5⦊i != 0⦉@3,5 || @7⦊i != 0⦉@7; + @8,9⦊i += 1⦉@8,9; } -}@4,11⦊⦉@4,11 +}@4,10⦊⦉@4,10 diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_template_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_template_func.-------.InstrumentCoverage.0.html index 9b32bcb47f6..be4f5efc5db 100644 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_template_func.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_template_func.-------.InstrumentCoverage.0.html @@ -77,11 +77,11 @@ For revisions in Pull Requests (PR): 11:11-11:17: @2[3]: _4 = Lt(move _5, const 10_i32) 11:11-11:17: @2[5]: FakeRead(ForMatchedPlace, _4)">@1,2⦊i < 10⦉@1,2 { @3,5⦊i != 0⦉@3,5 || @8⦊i != 0⦉@8; - @9,10⦊i += 1⦉@9,10; +12:9-12:15: @5[4]: _7 = Ne(move _8, const 0_i32)">@3,5⦊i != 0⦉@3,5 || @7⦊i != 0⦉@7; + @8,9⦊i += 1⦉@8,9; } -}@4,11⦊⦉@4,11 +}@4,10⦊⦉@4,10 From 2d813b26092ac67933de06009e2eede04b056923 Mon Sep 17 00:00:00 2001 From: Midas Lambrichts Date: Thu, 1 Apr 2021 20:54:57 +0200 Subject: [PATCH 277/370] Add a test that triggers the out-of-bounds ICE. Add a test that has the right input to trigger an out-of-bounds error when in MIR the local_decls and the normalized_input_tys don't match in amount. --- .../issue-83499-input-output-iteration-ice.rs | 10 +++++++++ ...ue-83499-input-output-iteration-ice.stderr | 21 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/test/ui/mir/issue-83499-input-output-iteration-ice.rs create mode 100644 src/test/ui/mir/issue-83499-input-output-iteration-ice.stderr diff --git a/src/test/ui/mir/issue-83499-input-output-iteration-ice.rs b/src/test/ui/mir/issue-83499-input-output-iteration-ice.rs new file mode 100644 index 00000000000..4d404d015ec --- /dev/null +++ b/src/test/ui/mir/issue-83499-input-output-iteration-ice.rs @@ -0,0 +1,10 @@ +// Test that when in MIR the amount of local_decls and amount of normalized_input_tys don't match +// that an out-of-bounds access does not occur. +#![feature(c_variadic)] + +fn main() {} + +fn foo(_: Bar, ...) -> impl {} +//~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic +//~| ERROR cannot find type `Bar` in this scope +//~| ERROR at least one trait must be specified diff --git a/src/test/ui/mir/issue-83499-input-output-iteration-ice.stderr b/src/test/ui/mir/issue-83499-input-output-iteration-ice.stderr new file mode 100644 index 00000000000..eb172684899 --- /dev/null +++ b/src/test/ui/mir/issue-83499-input-output-iteration-ice.stderr @@ -0,0 +1,21 @@ +error: only foreign or `unsafe extern "C" functions may be C-variadic + --> $DIR/issue-83499-input-output-iteration-ice.rs:7:16 + | +LL | fn foo(_: Bar, ...) -> impl {} + | ^^^ + +error: at least one trait must be specified + --> $DIR/issue-83499-input-output-iteration-ice.rs:7:24 + | +LL | fn foo(_: Bar, ...) -> impl {} + | ^^^^ + +error[E0412]: cannot find type `Bar` in this scope + --> $DIR/issue-83499-input-output-iteration-ice.rs:7:11 + | +LL | fn foo(_: Bar, ...) -> impl {} + | ^^^ not found in this scope + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0412`. From 227f5ed679ed0ad997b6530df842d55980c8c90e Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 1 Apr 2021 10:56:11 -0700 Subject: [PATCH 278/370] rustdoc: Separate filter-empty-string out into its own function --- src/librustdoc/html/static/main.js | 13 +++++++++++-- src/tools/rustdoc-js/tester.js | 3 ++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 52c3ff68d91..947c9298225 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -219,6 +219,15 @@ function hideThemeButtonState() { var titleBeforeSearch = document.title; var searchTitle = null; + function removeEmptyStringsFromArray(x) { + for (var i = 0, len = x.length; i < len; ++i) { + if (x[i] === "") { + x.splice(i, 1); + i -= 1; + } + } + } + function clearInputTimeout() { if (searchTimeout !== null) { clearTimeout(searchTimeout); @@ -756,7 +765,7 @@ function hideThemeButtonState() { results = {}, results_in_args = {}, results_returned = {}, split = valLower.split("::"); - split = split.filter(function(segment) { return segment !== ""; }); + removeEmptyStringsFromArray(split); function transformResults(results, isType) { var out = []; @@ -1338,7 +1347,7 @@ function hideThemeButtonState() { var valGenerics = extractGenerics(val); var paths = valLower.split("::"); - paths = paths.filter(function(segment) { return segment !== ""; }); + removeEmptyStringsFromArray(paths); val = paths[paths.length - 1]; var contains = paths.slice(0, paths.length > 1 ? paths.length - 1 : 1); diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index c21277de335..a551a97bda5 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -264,7 +264,8 @@ function loadMainJsAndIndex(mainJs, searchIndex, storageJs, crate) { // execQuery last parameter is built in buildIndex. // buildIndex requires the hashmap from search-index. var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult", - "handleAliases", "getQuery", "buildIndex", "execQuery", "execSearch"]; + "handleAliases", "getQuery", "buildIndex", "execQuery", "execSearch", + "removeEmptyStringsFromArray"]; ALIASES = {}; finalJS += 'window = { "currentCrate": "' + crate + '", rootPath: "../" };\n'; From f13135070cf8b973673f2383e283e3d8af26a794 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 1 Apr 2021 21:55:06 +0200 Subject: [PATCH 279/370] Add test to ensure search tabs behaviour --- ...rch-tab-selection-if-current-is-empty.goml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/test/rustdoc-gui/search-tab-selection-if-current-is-empty.goml diff --git a/src/test/rustdoc-gui/search-tab-selection-if-current-is-empty.goml b/src/test/rustdoc-gui/search-tab-selection-if-current-is-empty.goml new file mode 100644 index 00000000000..a4df102d245 --- /dev/null +++ b/src/test/rustdoc-gui/search-tab-selection-if-current-is-empty.goml @@ -0,0 +1,21 @@ +goto: file://|DOC_PATH|/index.html +write: (".search-input", "Foo") +// Waiting for the search results to appear... +wait-for: "#titles" +assert: ("#titles > button:nth-of-type(1)", "class", "selected") + +// To go back to the original "state" +goto: file://|DOC_PATH|/index.html +write: (".search-input", "-> String") +// Waiting for the search results to appear... +wait-for: "#titles" +// With this search, only the last tab shouldn't be empty so it should be selected. +assert: ("#titles > button:nth-of-type(3)", "class", "selected") + +// To go back to the original "state" +goto: file://|DOC_PATH|/index.html +write: (".search-input", "-> Something") +// Waiting for the search results to appear... +wait-for: "#titles" +// With this search, all the tabs are empty so the first one should remain selected. +assert: ("#titles > button:nth-of-type(1)", "class", "selected") From 18af989c063efd759e03d6eebb7b18e2b03349a4 Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Thu, 1 Apr 2021 16:49:05 -0400 Subject: [PATCH 280/370] Update lint message --- compiler/rustc_typeck/src/check/upvar.rs | 43 +++++++++++++++++------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 124076a889b..cd93cbbe965 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -479,7 +479,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); if !need_migrations.is_empty() { - let migrations_text = migration_suggestion_for_2229(self.tcx, &need_migrations); + let (migration_string, migrated_variables_concat) = + migration_suggestion_for_2229(self.tcx, &need_migrations); let local_def_id = closure_def_id.expect_local(); let closure_hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id); @@ -495,15 +496,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (sugg, app) = match self.tcx.sess.source_map().span_to_snippet(closure_body_span) { Ok(s) => ( - format!("{{ {} {} }}", migrations_text, s), + format!("{{ {}; {} }}", migration_string, s), Applicability::MachineApplicable, ), - Err(_) => (migrations_text.clone(), Applicability::HasPlaceholders), + Err(_) => (migration_string.clone(), Applicability::HasPlaceholders), }; + let diagnostic_msg = format!( + "`{}` causes {} to be fully captured", + migration_string, migrated_variables_concat + ); + diagnostics_builder.span_suggestion( closure_body_span, - &format!("You can restore original behavior adding `{}` to the closure/generator", migrations_text), + &diagnostic_msg, sugg, app, ); @@ -1537,16 +1543,29 @@ fn should_do_migration_analysis(tcx: TyCtxt<'_>, closure_id: hir::HirId) -> bool !matches!(level, lint::Level::Allow) } -fn migration_suggestion_for_2229(tcx: TyCtxt<'_>, need_migrations: &Vec) -> String { - let need_migrations_strings = - need_migrations.iter().map(|v| format!("&{}", var_name(tcx, *v))).collect::>(); - let migrations_list_concat = need_migrations_strings.join(", "); +/// Return a two string tuple (s1, s2) +/// - s1: Line of code that is needed for the migration: eg: `let _ = (&x, ...)`. +/// - s2: Comma separated names of the variables being migrated. +fn migration_suggestion_for_2229( + tcx: TyCtxt<'_>, + need_migrations: &Vec, +) -> (String, String) { + let need_migrations_variables = + need_migrations.iter().map(|v| var_name(tcx, *v)).collect::>(); - if 1 == need_migrations.len() { - format!("let _ = {};", migrations_list_concat) + let migration_ref_concat = + need_migrations_variables.iter().map(|v| format!("&{}", v)).collect::>().join(", "); + + let migration_string = if 1 == need_migrations.len() { + format!("let _ = {}", migration_ref_concat) } else { - format!("let _ = ({});", migrations_list_concat) - } + format!("let _ = ({})", migration_ref_concat) + }; + + let migrated_variables_concat = + need_migrations_variables.iter().map(|v| format!("`{}`", v)).collect::>().join(", "); + + (migration_string, migrated_variables_concat) } /// Helper function to determine if we need to escalate CaptureKind from From da863487072bf94273862e7eb48bcc392c900234 Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Thu, 1 Apr 2021 16:32:25 -0400 Subject: [PATCH 281/370] Update test cases --- .../migrations/insignificant_drop.fixed | 133 +++++++++++++++++ .../migrations/insignificant_drop.rs | 31 ++-- .../migrations/insignificant_drop.stderr | 88 +++++++++--- .../migrations/precise.fixed | 56 ++++++++ .../migrations/precise.rs | 34 +---- .../migrations/precise.stderr | 49 ++++--- .../migrations/significant_drop.fixed | 136 ++++++++++++++++++ .../migrations/significant_drop.rs | 31 ++-- .../migrations/significant_drop.stderr | 82 +++++++++-- 9 files changed, 527 insertions(+), 113 deletions(-) create mode 100644 src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed create mode 100644 src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed create mode 100644 src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed new file mode 100644 index 00000000000..3e346078915 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed @@ -0,0 +1,133 @@ +// run-rustfix + +#![deny(disjoint_capture_drop_reorder)] +//~^ NOTE: the lint level is defined here + +// Test cases for types that implement a insignificant drop (stlib defined) + +// `t` needs Drop because one of its elements needs drop, +// therefore precise capture might affect drop ordering +fn test1_all_need_migration() { + let t = (String::new(), String::new()); + let t1 = (String::new(), String::new()); + let t2 = (String::new(), String::new()); + + let c = || { let _ = (&t, &t1, &t2); { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP:` let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured + + let _t = t.0; + let _t1 = t1.0; + let _t2 = t2.0; + } }; + + c(); +} + +// String implements drop and therefore should be migrated. +// But in this test cases, `t2` is completely captured and when it is dropped won't be affected +fn test2_only_precise_paths_need_migration() { + let t = (String::new(), String::new()); + let t1 = (String::new(), String::new()); + let t2 = (String::new(), String::new()); + + let c = || { let _ = (&t, &t1); { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP:` let _ = (&t, &t1)` causes `t`, `t1` to be fully captured + let _t = t.0; + let _t1 = t1.0; + let _t2 = t2; + } }; + + c(); +} + +// If a variable would've not been captured by value then it would've not been +// dropped with the closure and therefore doesn't need migration. +fn test3_only_by_value_need_migration() { + let t = (String::new(), String::new()); + let t1 = (String::new(), String::new()); + let c = || { let _ = &t; { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured + let _t = t.0; + println!("{}", t1.1); + } }; + + c(); +} + +// Copy types get copied into the closure instead of move. Therefore we don't need to +// migrate then as their drop order isn't tied to the closure. +fn test4_only_non_copy_types_need_migration() { + let t = (String::new(), String::new()); + + // `t1` is Copy because all of its elements are Copy + let t1 = (0i32, 0i32); + + let c = || { let _ = &t; { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured + let _t = t.0; + let _t1 = t1.0; + } }; + + c(); +} + +fn test5_only_drop_types_need_migration() { + struct S(i32, i32); + + let t = (String::new(), String::new()); + + // `s` doesn't implement Drop or any elements within it, and doesn't need migration + let s = S(0i32, 0i32); + + let c = || { let _ = &t; { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured + let _t = t.0; + let _s = s.0; + } }; + + c(); +} + +// Since we are using a move closure here, both `t` and `t1` get moved +// even though they are being used by ref inside the closure. +fn test6_move_closures_non_copy_types_might_need_migration() { + let t = (String::new(), String::new()); + let t1 = (String::new(), String::new()); + let c = move || { let _ = (&t1, &t); { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured + println!("{} {}", t1.1, t.1); + } }; + + c(); +} + +// Test migration analysis in case of Drop + Non Drop aggregates. +// Note we need migration here only because the non-copy (because Drop type) is captured, +// otherwise we won't need to, since we can get away with just by ref capture in that case. +fn test7_drop_non_drop_aggregate_need_migration() { + let t = (String::new(), String::new(), 0i32); + + let c = || { let _ = &t; { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured + let _t = t.0; + } }; + + c(); +} + +fn main() { + test1_all_need_migration(); + test2_only_precise_paths_need_migration(); + test3_only_by_value_need_migration(); + test4_only_non_copy_types_need_migration(); + test5_only_drop_types_need_migration(); + test6_move_closures_non_copy_types_might_need_migration(); + test7_drop_non_drop_aggregate_need_migration(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs index 02b37362096..2472c8afc87 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs @@ -1,3 +1,5 @@ +// run-rustfix + #![deny(disjoint_capture_drop_reorder)] //~^ NOTE: the lint level is defined here @@ -11,8 +13,9 @@ fn test1_all_need_migration() { let t2 = (String::new(), String::new()); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t, t1, t2)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP:` let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured + let _t = t.0; let _t1 = t1.0; let _t2 = t2.0; @@ -29,8 +32,8 @@ fn test2_only_precise_paths_need_migration() { let t2 = (String::new(), String::new()); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t, t1)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP:` let _ = (&t, &t1)` causes `t`, `t1` to be fully captured let _t = t.0; let _t1 = t1.0; let _t2 = t2; @@ -45,8 +48,8 @@ fn test3_only_by_value_need_migration() { let t = (String::new(), String::new()); let t1 = (String::new(), String::new()); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; println!("{}", t1.1); }; @@ -63,8 +66,8 @@ fn test4_only_non_copy_types_need_migration() { let t1 = (0i32, 0i32); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; let _t1 = t1.0; }; @@ -81,8 +84,8 @@ fn test5_only_drop_types_need_migration() { let s = S(0i32, 0i32); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; let _s = s.0; }; @@ -96,8 +99,8 @@ fn test6_move_closures_non_copy_types_might_need_migration() { let t = (String::new(), String::new()); let t1 = (String::new(), String::new()); let c = move || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t1, t)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured println!("{} {}", t1.1, t.1); }; @@ -111,8 +114,8 @@ fn test7_drop_non_drop_aggregate_need_migration() { let t = (String::new(), String::new(), 0i32); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; }; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr index 656c132c12d..925df1160c8 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr @@ -1,25 +1,33 @@ error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/insignificant_drop.rs:13:13 + --> $DIR/insignificant_drop.rs:15:13 | LL | let c = || { | _____________^ LL | | LL | | -LL | | let _t = t.0; -LL | | let _t1 = t1.0; +LL | | +... | LL | | let _t2 = t2.0; LL | | }; | |_____^ | note: the lint level is defined here - --> $DIR/insignificant_drop.rs:1:9 + --> $DIR/insignificant_drop.rs:3:9 | LL | #![deny(disjoint_capture_drop_reorder)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: drop(&(t, t1, t2)); +help: `let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured + | +LL | let c = || { let _ = (&t, &t1, &t2); { +LL | +LL | +LL | +LL | let _t = t.0; +LL | let _t1 = t1.0; + ... error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/insignificant_drop.rs:31:13 + --> $DIR/insignificant_drop.rs:34:13 | LL | let c = || { | _____________^ @@ -31,10 +39,18 @@ LL | | let _t2 = t2; LL | | }; | |_____^ | - = note: drop(&(t, t1)); +help: `let _ = (&t, &t1)` causes `t`, `t1` to be fully captured + | +LL | let c = || { let _ = (&t, &t1); { +LL | +LL | +LL | let _t = t.0; +LL | let _t1 = t1.0; +LL | let _t2 = t2; + ... error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/insignificant_drop.rs:47:13 + --> $DIR/insignificant_drop.rs:50:13 | LL | let c = || { | _____________^ @@ -45,10 +61,18 @@ LL | | println!("{}", t1.1); LL | | }; | |_____^ | - = note: drop(&(t)); +help: `let _ = &t` causes `t` to be fully captured + | +LL | let c = || { let _ = &t; { +LL | +LL | +LL | let _t = t.0; +LL | println!("{}", t1.1); +LL | } }; + | error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/insignificant_drop.rs:65:13 + --> $DIR/insignificant_drop.rs:68:13 | LL | let c = || { | _____________^ @@ -59,10 +83,18 @@ LL | | let _t1 = t1.0; LL | | }; | |_____^ | - = note: drop(&(t)); +help: `let _ = &t` causes `t` to be fully captured + | +LL | let c = || { let _ = &t; { +LL | +LL | +LL | let _t = t.0; +LL | let _t1 = t1.0; +LL | } }; + | error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/insignificant_drop.rs:83:13 + --> $DIR/insignificant_drop.rs:86:13 | LL | let c = || { | _____________^ @@ -73,10 +105,18 @@ LL | | let _s = s.0; LL | | }; | |_____^ | - = note: drop(&(t)); +help: `let _ = &t` causes `t` to be fully captured + | +LL | let c = || { let _ = &t; { +LL | +LL | +LL | let _t = t.0; +LL | let _s = s.0; +LL | } }; + | error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/insignificant_drop.rs:98:13 + --> $DIR/insignificant_drop.rs:101:13 | LL | let c = move || { | _____________^ @@ -86,10 +126,17 @@ LL | | println!("{} {}", t1.1, t.1); LL | | }; | |_____^ | - = note: drop(&(t1, t)); +help: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured + | +LL | let c = move || { let _ = (&t1, &t); { +LL | +LL | +LL | println!("{} {}", t1.1, t.1); +LL | } }; + | error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/insignificant_drop.rs:113:13 + --> $DIR/insignificant_drop.rs:116:13 | LL | let c = || { | _____________^ @@ -99,7 +146,14 @@ LL | | let _t = t.0; LL | | }; | |_____^ | - = note: drop(&(t)); +help: `let _ = &t` causes `t` to be fully captured + | +LL | let c = || { let _ = &t; { +LL | +LL | +LL | let _t = t.0; +LL | } }; + | error: aborting due to 7 previous errors diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed new file mode 100644 index 00000000000..53793be8a69 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed @@ -0,0 +1,56 @@ +// run-rustfix + +#![deny(disjoint_capture_drop_reorder)] + +#[derive(Debug)] +struct Foo(i32); +impl Drop for Foo { + fn drop(&mut self) { + println!("{:?} dropped", self.0); + } +} + +struct ConstainsDropField(Foo, Foo); + +// Test that lint is triggered if a path that implements Drop is not captured by move +fn test_precise_analysis_drop_paths_not_captured_by_move() { + let t = ConstainsDropField(Foo(10), Foo(20)); + + let c = || { let _ = &t; { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured + let _t = t.0; + let _t = &t.1; + } }; + + c(); +} + +struct S; +impl Drop for S { + fn drop(&mut self) { + } +} + +struct T(S, S); +struct U(T, T); + +// Test precise analysis for the lint works with paths longer than one. +fn test_precise_analysis_long_path_missing() { + let u = U(T(S, S), T(S, S)); + + let c = || { let _ = &u; { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &u` causes `u` to be fully captured + let _x = u.0.0; + let _x = u.0.1; + let _x = u.1.0; + } }; + + c(); +} + +fn main() { + test_precise_analysis_drop_paths_not_captured_by_move(); + test_precise_analysis_long_path_missing(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs b/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs index 79702cc6b56..3661c2ca7ed 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs @@ -1,5 +1,6 @@ +// run-rustfix + #![deny(disjoint_capture_drop_reorder)] -//~^ NOTE: the lint level is defined here #[derive(Debug)] struct Foo(i32); @@ -11,35 +12,13 @@ impl Drop for Foo { struct ConstainsDropField(Foo, Foo); -#[derive(Debug)] -struct ContainsAndImplsDrop(Foo); -impl Drop for ContainsAndImplsDrop { - fn drop(&mut self) { - println!("{:?} dropped", self.0); - } -} - -// Test that even if all paths starting at root variable that implement Drop are captured, -// the lint is triggered if the root variable implements drop and isn't captured. -fn test_precise_analysis_parent_root_impl_drop_not_captured() { - let t = ContainsAndImplsDrop(Foo(10)); - - let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t)); - let _t = t.0; - }; - - c(); -} - // Test that lint is triggered if a path that implements Drop is not captured by move fn test_precise_analysis_drop_paths_not_captured_by_move() { let t = ConstainsDropField(Foo(10), Foo(20)); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; let _t = &t.1; }; @@ -61,8 +40,8 @@ fn test_precise_analysis_long_path_missing() { let u = U(T(S, S), T(S, S)); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(u)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &u` causes `u` to be fully captured let _x = u.0.0; let _x = u.0.1; let _x = u.1.0; @@ -72,7 +51,6 @@ fn test_precise_analysis_long_path_missing() { } fn main() { - test_precise_analysis_parent_root_impl_drop_not_captured(); test_precise_analysis_drop_paths_not_captured_by_move(); test_precise_analysis_long_path_missing(); } diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr index 968ca395f94..4cd75a15adb 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr @@ -1,23 +1,5 @@ error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/precise.rs:27:13 - | -LL | let c = || { - | _____________^ -LL | | -LL | | -LL | | let _t = t.0; -LL | | }; - | |_____^ - | -note: the lint level is defined here - --> $DIR/precise.rs:1:9 - | -LL | #![deny(disjoint_capture_drop_reorder)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: drop(&(t)); - -error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/precise.rs:40:13 + --> $DIR/precise.rs:19:13 | LL | let c = || { | _____________^ @@ -28,10 +10,23 @@ LL | | let _t = &t.1; LL | | }; | |_____^ | - = note: drop(&(t)); +note: the lint level is defined here + --> $DIR/precise.rs:3:9 + | +LL | #![deny(disjoint_capture_drop_reorder)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: `let _ = &t` causes `t` to be fully captured + | +LL | let c = || { let _ = &t; { +LL | +LL | +LL | let _t = t.0; +LL | let _t = &t.1; +LL | } }; + | error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/precise.rs:63:13 + --> $DIR/precise.rs:42:13 | LL | let c = || { | _____________^ @@ -43,7 +38,15 @@ LL | | let _x = u.1.0; LL | | }; | |_____^ | - = note: drop(&(u)); +help: `let _ = &u` causes `u` to be fully captured + | +LL | let c = || { let _ = &u; { +LL | +LL | +LL | let _x = u.0.0; +LL | let _x = u.0.1; +LL | let _x = u.1.0; + ... -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed new file mode 100644 index 00000000000..82b9299c1f4 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed @@ -0,0 +1,136 @@ +// run-rustfix +#![deny(disjoint_capture_drop_reorder)] +//~^ NOTE: the lint level is defined here + +// Test cases for types that implement a significant drop (user defined) + +#[derive(Debug)] +struct Foo(i32); +impl Drop for Foo { + fn drop(&mut self) { + println!("{:?} dropped", self.0); + } +} + +#[derive(Debug)] +struct ConstainsDropField(Foo, Foo); + +// `t` needs Drop because one of its elements needs drop, +// therefore precise capture might affect drop ordering +fn test1_all_need_migration() { + let t = (Foo(0), Foo(0)); + let t1 = (Foo(0), Foo(0)); + let t2 = (Foo(0), Foo(0)); + + let c = || { let _ = (&t, &t1, &t2); { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP:` let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured + let _t = t.0; + let _t1 = t1.0; + let _t2 = t2.0; + } }; + + c(); +} + +// String implements drop and therefore should be migrated. +// But in this test cases, `t2` is completely captured and when it is dropped won't be affected +fn test2_only_precise_paths_need_migration() { + let t = (Foo(0), Foo(0)); + let t1 = (Foo(0), Foo(0)); + let t2 = (Foo(0), Foo(0)); + + let c = || { let _ = (&t, &t1); { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP:` let _ = (&t, &t1)` causes `t`, `t1` to be fully captured + let _t = t.0; + let _t1 = t1.0; + let _t2 = t2; + } }; + + c(); +} + +// If a variable would've not been captured by value then it would've not been +// dropped with the closure and therefore doesn't need migration. +fn test3_only_by_value_need_migration() { + let t = (Foo(0), Foo(0)); + let t1 = (Foo(0), Foo(0)); + let c = || { let _ = &t; { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured + let _t = t.0; + println!("{:?}", t1.1); + } }; + + c(); +} + +// The root variable might not implement drop themselves but some path starting +// at the root variable might implement Drop. +// +// If this path isn't captured we need to migrate for the root variable. +fn test4_type_contains_drop_need_migration() { + let t = ConstainsDropField(Foo(0), Foo(0)); + + let c = || { let _ = &t; { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured + let _t = t.0; + } }; + + c(); +} + +// Test migration analysis in case of Drop + Non Drop aggregates. +// Note we need migration here only because the non-copy (because Drop type) is captured, +// otherwise we won't need to, since we can get away with just by ref capture in that case. +fn test5_drop_non_drop_aggregate_need_migration() { + let t = (Foo(0), Foo(0), 0i32); + + let c = || { let _ = &t; { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured + let _t = t.0; + } }; + + c(); +} + +// Test migration analysis in case of Significant and Insignificant Drop aggregates. +fn test6_significant_insignificant_drop_aggregate_need_migration() { + let t = (Foo(0), String::new()); + + let c = || { let _ = &t; { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured + let _t = t.1; + } }; + + c(); +} + +// Since we are using a move closure here, both `t` and `t1` get moved +// even though they are being used by ref inside the closure. +fn test7_move_closures_non_copy_types_might_need_migration() { + let t = (Foo(0), Foo(0)); + let t1 = (Foo(0), Foo(0), Foo(0)); + + let c = move || { let _ = (&t1, &t); { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured + println!("{:?} {:?}", t1.1, t.1); + } }; + + c(); +} + +fn main() { + test1_all_need_migration(); + test2_only_precise_paths_need_migration(); + test3_only_by_value_need_migration(); + test4_type_contains_drop_need_migration(); + test5_drop_non_drop_aggregate_need_migration(); + test6_significant_insignificant_drop_aggregate_need_migration(); + test7_move_closures_non_copy_types_might_need_migration(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs index ed5e4ea8be0..5cb2f611bc1 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs @@ -1,3 +1,4 @@ +// run-rustfix #![deny(disjoint_capture_drop_reorder)] //~^ NOTE: the lint level is defined here @@ -22,8 +23,8 @@ fn test1_all_need_migration() { let t2 = (Foo(0), Foo(0)); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t, t1, t2)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP:` let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured let _t = t.0; let _t1 = t1.0; let _t2 = t2.0; @@ -40,8 +41,8 @@ fn test2_only_precise_paths_need_migration() { let t2 = (Foo(0), Foo(0)); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t, t1)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP:` let _ = (&t, &t1)` causes `t`, `t1` to be fully captured let _t = t.0; let _t1 = t1.0; let _t2 = t2; @@ -56,8 +57,8 @@ fn test3_only_by_value_need_migration() { let t = (Foo(0), Foo(0)); let t1 = (Foo(0), Foo(0)); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; println!("{:?}", t1.1); }; @@ -73,8 +74,8 @@ fn test4_type_contains_drop_need_migration() { let t = ConstainsDropField(Foo(0), Foo(0)); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; }; @@ -88,8 +89,8 @@ fn test5_drop_non_drop_aggregate_need_migration() { let t = (Foo(0), Foo(0), 0i32); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; }; @@ -98,13 +99,11 @@ fn test5_drop_non_drop_aggregate_need_migration() { // Test migration analysis in case of Significant and Insignificant Drop aggregates. fn test6_significant_insignificant_drop_aggregate_need_migration() { - struct S(i32, i32); - let t = (Foo(0), String::new()); let c = || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.1; }; @@ -118,8 +117,8 @@ fn test7_move_closures_non_copy_types_might_need_migration() { let t1 = (Foo(0), Foo(0), Foo(0)); let c = move || { - //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| NOTE: drop(&(t1, t)); + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured println!("{:?} {:?}", t1.1, t.1); }; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr index 6c21b27b493..fcf734020ce 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr @@ -1,5 +1,5 @@ error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/significant_drop.rs:24:13 + --> $DIR/significant_drop.rs:25:13 | LL | let c = || { | _____________^ @@ -12,14 +12,22 @@ LL | | }; | |_____^ | note: the lint level is defined here - --> $DIR/significant_drop.rs:1:9 + --> $DIR/significant_drop.rs:2:9 | LL | #![deny(disjoint_capture_drop_reorder)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: drop(&(t, t1, t2)); +help: `let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured + | +LL | let c = || { let _ = (&t, &t1, &t2); { +LL | +LL | +LL | let _t = t.0; +LL | let _t1 = t1.0; +LL | let _t2 = t2.0; + ... error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/significant_drop.rs:42:13 + --> $DIR/significant_drop.rs:43:13 | LL | let c = || { | _____________^ @@ -31,10 +39,18 @@ LL | | let _t2 = t2; LL | | }; | |_____^ | - = note: drop(&(t, t1)); +help: `let _ = (&t, &t1)` causes `t`, `t1` to be fully captured + | +LL | let c = || { let _ = (&t, &t1); { +LL | +LL | +LL | let _t = t.0; +LL | let _t1 = t1.0; +LL | let _t2 = t2; + ... error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/significant_drop.rs:58:13 + --> $DIR/significant_drop.rs:59:13 | LL | let c = || { | _____________^ @@ -45,10 +61,18 @@ LL | | println!("{:?}", t1.1); LL | | }; | |_____^ | - = note: drop(&(t)); +help: `let _ = &t` causes `t` to be fully captured + | +LL | let c = || { let _ = &t; { +LL | +LL | +LL | let _t = t.0; +LL | println!("{:?}", t1.1); +LL | } }; + | error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/significant_drop.rs:75:13 + --> $DIR/significant_drop.rs:76:13 | LL | let c = || { | _____________^ @@ -58,10 +82,17 @@ LL | | let _t = t.0; LL | | }; | |_____^ | - = note: drop(&(t)); +help: `let _ = &t` causes `t` to be fully captured + | +LL | let c = || { let _ = &t; { +LL | +LL | +LL | let _t = t.0; +LL | } }; + | error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/significant_drop.rs:90:13 + --> $DIR/significant_drop.rs:91:13 | LL | let c = || { | _____________^ @@ -71,10 +102,17 @@ LL | | let _t = t.0; LL | | }; | |_____^ | - = note: drop(&(t)); +help: `let _ = &t` causes `t` to be fully captured + | +LL | let c = || { let _ = &t; { +LL | +LL | +LL | let _t = t.0; +LL | } }; + | error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/significant_drop.rs:105:13 + --> $DIR/significant_drop.rs:104:13 | LL | let c = || { | _____________^ @@ -84,10 +122,17 @@ LL | | let _t = t.1; LL | | }; | |_____^ | - = note: drop(&(t)); +help: `let _ = &t` causes `t` to be fully captured + | +LL | let c = || { let _ = &t; { +LL | +LL | +LL | let _t = t.1; +LL | } }; + | error: drop order affected for closure because of `capture_disjoint_fields` - --> $DIR/significant_drop.rs:120:13 + --> $DIR/significant_drop.rs:119:13 | LL | let c = move || { | _____________^ @@ -97,7 +142,14 @@ LL | | println!("{:?} {:?}", t1.1, t.1); LL | | }; | |_____^ | - = note: drop(&(t1, t)); +help: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured + | +LL | let c = move || { let _ = (&t1, &t); { +LL | +LL | +LL | println!("{:?} {:?}", t1.1, t.1); +LL | } }; + | error: aborting due to 7 previous errors From aa987c2f57d5604d5dd3a7db5031f021dc8418a6 Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Fri, 2 Apr 2021 08:08:02 +0800 Subject: [PATCH 282/370] address comments --- compiler/rustc_expand/src/mbe/macro_rules.rs | 2 +- src/test/ui/macros/macro-or-patterns-back-compat.fixed | 8 ++++---- src/test/ui/macros/macro-or-patterns-back-compat.rs | 8 ++++---- src/test/ui/macros/macro-or-patterns-back-compat.stderr | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index a85ed18055b..bc45c57596e 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -969,7 +969,7 @@ fn check_matcher_core( &OR_PATTERNS_BACK_COMPAT, span, ast::CRATE_NODE_ID, - &*format!("the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro",), + &*format!("the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro",), BuiltinLintDiagnostics::OrPatternsBackCompat( span, suggestion, ), diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.fixed b/src/test/ui/macros/macro-or-patterns-back-compat.fixed index 60ec0f7430d..4e8b057457c 100644 --- a/src/test/ui/macros/macro-or-patterns-back-compat.fixed +++ b/src/test/ui/macros/macro-or-patterns-back-compat.fixed @@ -4,13 +4,13 @@ #![feature(edition_macro_pats)] #![deny(or_patterns_back_compat)] #![allow(unused_macros)] -macro_rules! foo { ($x:pat2015 | $y:pat) => {} } //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro -macro_rules! bar { ($($x:pat2015)+ | $($y:pat)+) => {} } //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +macro_rules! foo { ($x:pat2015 | $y:pat) => {} } //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro +macro_rules! bar { ($($x:pat2015)+ | $($y:pat)+) => {} } //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro macro_rules! baz { ($x:pat2015 | $y:pat2015) => {} } // should be ok macro_rules! qux { ($x:pat2015 | $y:pat) => {} } // should be ok -macro_rules! ogg { ($x:pat2015 | $y:pat2015) => {} } //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +macro_rules! ogg { ($x:pat2015 | $y:pat2015) => {} } //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro macro_rules! match_any { - ( $expr:expr , $( $( $pat:pat2015 )|+ => $expr_arm:expr ),+ ) => { //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro + ( $expr:expr , $( $( $pat:pat2015 )|+ => $expr_arm:expr ),+ ) => { //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro match $expr { $( $( $pat => $expr_arm, )+ diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.rs b/src/test/ui/macros/macro-or-patterns-back-compat.rs index dc9e8595ca2..023abae36d0 100644 --- a/src/test/ui/macros/macro-or-patterns-back-compat.rs +++ b/src/test/ui/macros/macro-or-patterns-back-compat.rs @@ -4,13 +4,13 @@ #![feature(edition_macro_pats)] #![deny(or_patterns_back_compat)] #![allow(unused_macros)] -macro_rules! foo { ($x:pat | $y:pat) => {} } //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro -macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} } //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +macro_rules! foo { ($x:pat | $y:pat) => {} } //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro +macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} } //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro macro_rules! baz { ($x:pat2015 | $y:pat2015) => {} } // should be ok macro_rules! qux { ($x:pat2015 | $y:pat) => {} } // should be ok -macro_rules! ogg { ($x:pat | $y:pat2015) => {} } //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +macro_rules! ogg { ($x:pat | $y:pat2015) => {} } //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro macro_rules! match_any { - ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => { //~ ERROR the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro + ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => { //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro match $expr { $( $( $pat => $expr_arm, )+ diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.stderr b/src/test/ui/macros/macro-or-patterns-back-compat.stderr index 630a11c1734..29bbd696033 100644 --- a/src/test/ui/macros/macro-or-patterns-back-compat.stderr +++ b/src/test/ui/macros/macro-or-patterns-back-compat.stderr @@ -1,4 +1,4 @@ -error: the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro --> $DIR/macro-or-patterns-back-compat.rs:7:21 | LL | macro_rules! foo { ($x:pat | $y:pat) => {} } @@ -10,19 +10,19 @@ note: the lint level is defined here LL | #![deny(or_patterns_back_compat)] | ^^^^^^^^^^^^^^^^^^^^^^^ -error: the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro --> $DIR/macro-or-patterns-back-compat.rs:8:23 | LL | macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} } | ^^^^^^ help: use pat2015 to preserve semantics: `$x:pat2015` -error: the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro --> $DIR/macro-or-patterns-back-compat.rs:11:21 | LL | macro_rules! ogg { ($x:pat | $y:pat2015) => {} } | ^^^^^^ help: use pat2015 to preserve semantics: `$x:pat2015` -error: the meaning of the pat fragment specific is changing in Rust 2021, which may affect this macro +error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro --> $DIR/macro-or-patterns-back-compat.rs:13:26 | LL | ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => { From a721957a3d019f26e709546f27a4048eb8b9621b Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Thu, 1 Apr 2021 21:08:04 -0400 Subject: [PATCH 283/370] Don't introduce a block if a block exists --- compiler/rustc_typeck/src/check/upvar.rs | 16 ++++++-- .../migrations/insignificant_drop.fixed | 28 ++++++------- .../migrations/insignificant_drop.stderr | 24 +++++------ .../migrations/migrations_rustfix.fixed | 40 +++++++++++++++++++ .../migrations/migrations_rustfix.rs | 40 +++++++++++++++++++ .../migrations/migrations_rustfix.stderr | 38 ++++++++++++++++++ .../migrations/precise.fixed | 8 ++-- .../migrations/precise.stderr | 6 +-- .../migrations/significant_drop.fixed | 28 ++++++------- .../migrations/significant_drop.stderr | 24 +++++------ 10 files changed, 189 insertions(+), 63 deletions(-) create mode 100644 src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed create mode 100644 src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index cd93cbbe965..bbe843f468b 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -495,10 +495,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let closure_body_span = self.tcx.hir().span(body_id.hir_id); let (sugg, app) = match self.tcx.sess.source_map().span_to_snippet(closure_body_span) { - Ok(s) => ( - format!("{{ {}; {} }}", migration_string, s), - Applicability::MachineApplicable, - ), + Ok(s) => { + let trimmed = s.trim_start(); + + // If the closure contains a block then replace the opening brace + // with "{ let _ = (..); " + let sugg = if let Some('{') = trimmed.chars().next() { + format!("{{ {}; {}", migration_string, &trimmed[1..]) + } else { + format!("{{ {}; {} }}", migration_string, s) + }; + (sugg, Applicability::MachineApplicable) + } Err(_) => (migration_string.clone(), Applicability::HasPlaceholders), }; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed index 3e346078915..0f4c7dcb0df 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed @@ -12,14 +12,14 @@ fn test1_all_need_migration() { let t1 = (String::new(), String::new()); let t2 = (String::new(), String::new()); - let c = || { let _ = (&t, &t1, &t2); { + let c = || { let _ = (&t, &t1, &t2); //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP:` let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured let _t = t.0; let _t1 = t1.0; let _t2 = t2.0; - } }; + }; c(); } @@ -31,13 +31,13 @@ fn test2_only_precise_paths_need_migration() { let t1 = (String::new(), String::new()); let t2 = (String::new(), String::new()); - let c = || { let _ = (&t, &t1); { + let c = || { let _ = (&t, &t1); //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP:` let _ = (&t, &t1)` causes `t`, `t1` to be fully captured let _t = t.0; let _t1 = t1.0; let _t2 = t2; - } }; + }; c(); } @@ -47,12 +47,12 @@ fn test2_only_precise_paths_need_migration() { fn test3_only_by_value_need_migration() { let t = (String::new(), String::new()); let t1 = (String::new(), String::new()); - let c = || { let _ = &t; { + let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; println!("{}", t1.1); - } }; + }; c(); } @@ -65,12 +65,12 @@ fn test4_only_non_copy_types_need_migration() { // `t1` is Copy because all of its elements are Copy let t1 = (0i32, 0i32); - let c = || { let _ = &t; { + let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; let _t1 = t1.0; - } }; + }; c(); } @@ -83,12 +83,12 @@ fn test5_only_drop_types_need_migration() { // `s` doesn't implement Drop or any elements within it, and doesn't need migration let s = S(0i32, 0i32); - let c = || { let _ = &t; { + let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; let _s = s.0; - } }; + }; c(); } @@ -98,11 +98,11 @@ fn test5_only_drop_types_need_migration() { fn test6_move_closures_non_copy_types_might_need_migration() { let t = (String::new(), String::new()); let t1 = (String::new(), String::new()); - let c = move || { let _ = (&t1, &t); { + let c = move || { let _ = (&t1, &t); //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured println!("{} {}", t1.1, t.1); - } }; + }; c(); } @@ -113,11 +113,11 @@ fn test6_move_closures_non_copy_types_might_need_migration() { fn test7_drop_non_drop_aggregate_need_migration() { let t = (String::new(), String::new(), 0i32); - let c = || { let _ = &t; { + let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; - } }; + }; c(); } diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr index 925df1160c8..253a906a0ec 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr @@ -18,7 +18,7 @@ LL | #![deny(disjoint_capture_drop_reorder)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured | -LL | let c = || { let _ = (&t, &t1, &t2); { +LL | let c = || { let _ = (&t, &t1, &t2); LL | LL | LL | @@ -41,7 +41,7 @@ LL | | }; | help: `let _ = (&t, &t1)` causes `t`, `t1` to be fully captured | -LL | let c = || { let _ = (&t, &t1); { +LL | let c = || { let _ = (&t, &t1); LL | LL | LL | let _t = t.0; @@ -63,12 +63,12 @@ LL | | }; | help: `let _ = &t` causes `t` to be fully captured | -LL | let c = || { let _ = &t; { +LL | let c = || { let _ = &t; LL | LL | LL | let _t = t.0; LL | println!("{}", t1.1); -LL | } }; +LL | }; | error: drop order affected for closure because of `capture_disjoint_fields` @@ -85,12 +85,12 @@ LL | | }; | help: `let _ = &t` causes `t` to be fully captured | -LL | let c = || { let _ = &t; { +LL | let c = || { let _ = &t; LL | LL | LL | let _t = t.0; LL | let _t1 = t1.0; -LL | } }; +LL | }; | error: drop order affected for closure because of `capture_disjoint_fields` @@ -107,12 +107,12 @@ LL | | }; | help: `let _ = &t` causes `t` to be fully captured | -LL | let c = || { let _ = &t; { +LL | let c = || { let _ = &t; LL | LL | LL | let _t = t.0; LL | let _s = s.0; -LL | } }; +LL | }; | error: drop order affected for closure because of `capture_disjoint_fields` @@ -128,11 +128,11 @@ LL | | }; | help: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured | -LL | let c = move || { let _ = (&t1, &t); { +LL | let c = move || { let _ = (&t1, &t); LL | LL | LL | println!("{} {}", t1.1, t.1); -LL | } }; +LL | }; | error: drop order affected for closure because of `capture_disjoint_fields` @@ -148,11 +148,11 @@ LL | | }; | help: `let _ = &t` causes `t` to be fully captured | -LL | let c = || { let _ = &t; { +LL | let c = || { let _ = &t; LL | LL | LL | let _t = t.0; -LL | } }; +LL | }; | error: aborting due to 7 previous errors diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed new file mode 100644 index 00000000000..f17fab8e81f --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed @@ -0,0 +1,40 @@ +// run-rustfix +#![deny(disjoint_capture_drop_reorder)] +//~^ NOTE: the lint level is defined here + +// Test the two possible cases for automated migartion using rustfix +// - Closure contains a block i.e. `|| { .. };` +// - Closure contains just an expr `|| ..;` + +#[derive(Debug)] +struct Foo(i32); +impl Drop for Foo { + fn drop(&mut self) { + println!("{:?} dropped", self.0); + } +} + +fn closure_contains_block() { + let t = (Foo(0), Foo(0)); + let c = || { let _ = &t; + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured + let _t = t.0; + }; + + c(); +} + +fn closure_doesnt_contain_block() { + let t = (Foo(0), Foo(0)); + let c = || { let _ = &t; t.0 }; + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured + + c(); +} + +fn main() { + closure_contains_block(); + closure_doesnt_contain_block(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs new file mode 100644 index 00000000000..33aff10c520 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs @@ -0,0 +1,40 @@ +// run-rustfix +#![deny(disjoint_capture_drop_reorder)] +//~^ NOTE: the lint level is defined here + +// Test the two possible cases for automated migartion using rustfix +// - Closure contains a block i.e. `|| { .. };` +// - Closure contains just an expr `|| ..;` + +#[derive(Debug)] +struct Foo(i32); +impl Drop for Foo { + fn drop(&mut self) { + println!("{:?} dropped", self.0); + } +} + +fn closure_contains_block() { + let t = (Foo(0), Foo(0)); + let c = || { + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured + let _t = t.0; + }; + + c(); +} + +fn closure_doesnt_contain_block() { + let t = (Foo(0), Foo(0)); + let c = || t.0; + //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: `let _ = &t` causes `t` to be fully captured + + c(); +} + +fn main() { + closure_contains_block(); + closure_doesnt_contain_block(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr new file mode 100644 index 00000000000..611fbc4fff3 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr @@ -0,0 +1,38 @@ +error: drop order affected for closure because of `capture_disjoint_fields` + --> $DIR/migrations_rustfix.rs:19:13 + | +LL | let c = || { + | _____________^ +LL | | +LL | | +LL | | let _t = t.0; +LL | | }; + | |_____^ + | +note: the lint level is defined here + --> $DIR/migrations_rustfix.rs:2:9 + | +LL | #![deny(disjoint_capture_drop_reorder)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: `let _ = &t` causes `t` to be fully captured + | +LL | let c = || { let _ = &t; +LL | +LL | +LL | let _t = t.0; +LL | }; + | + +error: drop order affected for closure because of `capture_disjoint_fields` + --> $DIR/migrations_rustfix.rs:30:13 + | +LL | let c = || t.0; + | ^^^^^^ + | +help: `let _ = &t` causes `t` to be fully captured + | +LL | let c = || { let _ = &t; t.0 }; + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed index 53793be8a69..06932c1ae64 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed @@ -16,12 +16,12 @@ struct ConstainsDropField(Foo, Foo); fn test_precise_analysis_drop_paths_not_captured_by_move() { let t = ConstainsDropField(Foo(10), Foo(20)); - let c = || { let _ = &t; { + let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; let _t = &t.1; - } }; + }; c(); } @@ -39,13 +39,13 @@ struct U(T, T); fn test_precise_analysis_long_path_missing() { let u = U(T(S, S), T(S, S)); - let c = || { let _ = &u; { + let c = || { let _ = &u; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP: `let _ = &u` causes `u` to be fully captured let _x = u.0.0; let _x = u.0.1; let _x = u.1.0; - } }; + }; c(); } diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr index 4cd75a15adb..fcfd08d61e0 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr @@ -17,12 +17,12 @@ LL | #![deny(disjoint_capture_drop_reorder)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `let _ = &t` causes `t` to be fully captured | -LL | let c = || { let _ = &t; { +LL | let c = || { let _ = &t; LL | LL | LL | let _t = t.0; LL | let _t = &t.1; -LL | } }; +LL | }; | error: drop order affected for closure because of `capture_disjoint_fields` @@ -40,7 +40,7 @@ LL | | }; | help: `let _ = &u` causes `u` to be fully captured | -LL | let c = || { let _ = &u; { +LL | let c = || { let _ = &u; LL | LL | LL | let _x = u.0.0; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed index 82b9299c1f4..b44624be5f9 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed +++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed @@ -22,13 +22,13 @@ fn test1_all_need_migration() { let t1 = (Foo(0), Foo(0)); let t2 = (Foo(0), Foo(0)); - let c = || { let _ = (&t, &t1, &t2); { + let c = || { let _ = (&t, &t1, &t2); //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP:` let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured let _t = t.0; let _t1 = t1.0; let _t2 = t2.0; - } }; + }; c(); } @@ -40,13 +40,13 @@ fn test2_only_precise_paths_need_migration() { let t1 = (Foo(0), Foo(0)); let t2 = (Foo(0), Foo(0)); - let c = || { let _ = (&t, &t1); { + let c = || { let _ = (&t, &t1); //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP:` let _ = (&t, &t1)` causes `t`, `t1` to be fully captured let _t = t.0; let _t1 = t1.0; let _t2 = t2; - } }; + }; c(); } @@ -56,12 +56,12 @@ fn test2_only_precise_paths_need_migration() { fn test3_only_by_value_need_migration() { let t = (Foo(0), Foo(0)); let t1 = (Foo(0), Foo(0)); - let c = || { let _ = &t; { + let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; println!("{:?}", t1.1); - } }; + }; c(); } @@ -73,11 +73,11 @@ fn test3_only_by_value_need_migration() { fn test4_type_contains_drop_need_migration() { let t = ConstainsDropField(Foo(0), Foo(0)); - let c = || { let _ = &t; { + let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; - } }; + }; c(); } @@ -88,11 +88,11 @@ fn test4_type_contains_drop_need_migration() { fn test5_drop_non_drop_aggregate_need_migration() { let t = (Foo(0), Foo(0), 0i32); - let c = || { let _ = &t; { + let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.0; - } }; + }; c(); } @@ -101,11 +101,11 @@ fn test5_drop_non_drop_aggregate_need_migration() { fn test6_significant_insignificant_drop_aggregate_need_migration() { let t = (Foo(0), String::new()); - let c = || { let _ = &t; { + let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP: `let _ = &t` causes `t` to be fully captured let _t = t.1; - } }; + }; c(); } @@ -116,11 +116,11 @@ fn test7_move_closures_non_copy_types_might_need_migration() { let t = (Foo(0), Foo(0)); let t1 = (Foo(0), Foo(0), Foo(0)); - let c = move || { let _ = (&t1, &t); { + let c = move || { let _ = (&t1, &t); //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` //~| HELP: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured println!("{:?} {:?}", t1.1, t.1); - } }; + }; c(); } diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr index fcf734020ce..2ca2baa9cbc 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr @@ -18,7 +18,7 @@ LL | #![deny(disjoint_capture_drop_reorder)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured | -LL | let c = || { let _ = (&t, &t1, &t2); { +LL | let c = || { let _ = (&t, &t1, &t2); LL | LL | LL | let _t = t.0; @@ -41,7 +41,7 @@ LL | | }; | help: `let _ = (&t, &t1)` causes `t`, `t1` to be fully captured | -LL | let c = || { let _ = (&t, &t1); { +LL | let c = || { let _ = (&t, &t1); LL | LL | LL | let _t = t.0; @@ -63,12 +63,12 @@ LL | | }; | help: `let _ = &t` causes `t` to be fully captured | -LL | let c = || { let _ = &t; { +LL | let c = || { let _ = &t; LL | LL | LL | let _t = t.0; LL | println!("{:?}", t1.1); -LL | } }; +LL | }; | error: drop order affected for closure because of `capture_disjoint_fields` @@ -84,11 +84,11 @@ LL | | }; | help: `let _ = &t` causes `t` to be fully captured | -LL | let c = || { let _ = &t; { +LL | let c = || { let _ = &t; LL | LL | LL | let _t = t.0; -LL | } }; +LL | }; | error: drop order affected for closure because of `capture_disjoint_fields` @@ -104,11 +104,11 @@ LL | | }; | help: `let _ = &t` causes `t` to be fully captured | -LL | let c = || { let _ = &t; { +LL | let c = || { let _ = &t; LL | LL | LL | let _t = t.0; -LL | } }; +LL | }; | error: drop order affected for closure because of `capture_disjoint_fields` @@ -124,11 +124,11 @@ LL | | }; | help: `let _ = &t` causes `t` to be fully captured | -LL | let c = || { let _ = &t; { +LL | let c = || { let _ = &t; LL | LL | LL | let _t = t.1; -LL | } }; +LL | }; | error: drop order affected for closure because of `capture_disjoint_fields` @@ -144,11 +144,11 @@ LL | | }; | help: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured | -LL | let c = move || { let _ = (&t1, &t); { +LL | let c = move || { let _ = (&t1, &t); LL | LL | LL | println!("{:?} {:?}", t1.1, t.1); -LL | } }; +LL | }; | error: aborting due to 7 previous errors From 1b9620d75f75aad6629bb8815344a1a2f14a2081 Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Thu, 1 Apr 2021 21:33:11 -0400 Subject: [PATCH 284/370] Make the diagnostic message more readable --- compiler/rustc_typeck/src/check/upvar.rs | 4 ++-- .../migrations/insignificant_drop.fixed | 14 +++++++------- .../migrations/insignificant_drop.rs | 14 +++++++------- .../migrations/insignificant_drop.stderr | 14 +++++++------- .../migrations/migrations_rustfix.fixed | 4 ++-- .../migrations/migrations_rustfix.rs | 4 ++-- .../migrations/migrations_rustfix.stderr | 4 ++-- .../2229_closure_analysis/migrations/precise.fixed | 4 ++-- .../2229_closure_analysis/migrations/precise.rs | 4 ++-- .../migrations/precise.stderr | 4 ++-- .../migrations/significant_drop.fixed | 14 +++++++------- .../migrations/significant_drop.rs | 14 +++++++------- .../migrations/significant_drop.stderr | 14 +++++++------- 13 files changed, 56 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index bbe843f468b..6f8dd39958c 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -511,8 +511,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let diagnostic_msg = format!( - "`{}` causes {} to be fully captured", - migration_string, migrated_variables_concat + "add a dummy let to cause {} to be fully captured", + migrated_variables_concat ); diagnostics_builder.span_suggestion( diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed index 0f4c7dcb0df..300f67e8b1e 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed @@ -14,7 +14,7 @@ fn test1_all_need_migration() { let c = || { let _ = (&t, &t1, &t2); //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP:` let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured + //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured let _t = t.0; let _t1 = t1.0; @@ -33,7 +33,7 @@ fn test2_only_precise_paths_need_migration() { let c = || { let _ = (&t, &t1); //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP:` let _ = (&t, &t1)` causes `t`, `t1` to be fully captured + //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured let _t = t.0; let _t1 = t1.0; let _t2 = t2; @@ -49,7 +49,7 @@ fn test3_only_by_value_need_migration() { let t1 = (String::new(), String::new()); let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; println!("{}", t1.1); }; @@ -67,7 +67,7 @@ fn test4_only_non_copy_types_need_migration() { let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; let _t1 = t1.0; }; @@ -85,7 +85,7 @@ fn test5_only_drop_types_need_migration() { let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; let _s = s.0; }; @@ -100,7 +100,7 @@ fn test6_move_closures_non_copy_types_might_need_migration() { let t1 = (String::new(), String::new()); let c = move || { let _ = (&t1, &t); //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured + //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured println!("{} {}", t1.1, t.1); }; @@ -115,7 +115,7 @@ fn test7_drop_non_drop_aggregate_need_migration() { let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; }; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs index 2472c8afc87..a17c70d3e28 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs @@ -14,7 +14,7 @@ fn test1_all_need_migration() { let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP:` let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured + //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured let _t = t.0; let _t1 = t1.0; @@ -33,7 +33,7 @@ fn test2_only_precise_paths_need_migration() { let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP:` let _ = (&t, &t1)` causes `t`, `t1` to be fully captured + //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured let _t = t.0; let _t1 = t1.0; let _t2 = t2; @@ -49,7 +49,7 @@ fn test3_only_by_value_need_migration() { let t1 = (String::new(), String::new()); let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; println!("{}", t1.1); }; @@ -67,7 +67,7 @@ fn test4_only_non_copy_types_need_migration() { let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; let _t1 = t1.0; }; @@ -85,7 +85,7 @@ fn test5_only_drop_types_need_migration() { let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; let _s = s.0; }; @@ -100,7 +100,7 @@ fn test6_move_closures_non_copy_types_might_need_migration() { let t1 = (String::new(), String::new()); let c = move || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured + //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured println!("{} {}", t1.1, t.1); }; @@ -115,7 +115,7 @@ fn test7_drop_non_drop_aggregate_need_migration() { let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; }; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr index 253a906a0ec..69c12d2bb56 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr @@ -16,7 +16,7 @@ note: the lint level is defined here | LL | #![deny(disjoint_capture_drop_reorder)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: `let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured +help: add a dummy let to cause `t`, `t1`, `t2` to be fully captured | LL | let c = || { let _ = (&t, &t1, &t2); LL | @@ -39,7 +39,7 @@ LL | | let _t2 = t2; LL | | }; | |_____^ | -help: `let _ = (&t, &t1)` causes `t`, `t1` to be fully captured +help: add a dummy let to cause `t`, `t1` to be fully captured | LL | let c = || { let _ = (&t, &t1); LL | @@ -61,7 +61,7 @@ LL | | println!("{}", t1.1); LL | | }; | |_____^ | -help: `let _ = &t` causes `t` to be fully captured +help: add a dummy let to cause `t` to be fully captured | LL | let c = || { let _ = &t; LL | @@ -83,7 +83,7 @@ LL | | let _t1 = t1.0; LL | | }; | |_____^ | -help: `let _ = &t` causes `t` to be fully captured +help: add a dummy let to cause `t` to be fully captured | LL | let c = || { let _ = &t; LL | @@ -105,7 +105,7 @@ LL | | let _s = s.0; LL | | }; | |_____^ | -help: `let _ = &t` causes `t` to be fully captured +help: add a dummy let to cause `t` to be fully captured | LL | let c = || { let _ = &t; LL | @@ -126,7 +126,7 @@ LL | | println!("{} {}", t1.1, t.1); LL | | }; | |_____^ | -help: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured +help: add a dummy let to cause `t1`, `t` to be fully captured | LL | let c = move || { let _ = (&t1, &t); LL | @@ -146,7 +146,7 @@ LL | | let _t = t.0; LL | | }; | |_____^ | -help: `let _ = &t` causes `t` to be fully captured +help: add a dummy let to cause `t` to be fully captured | LL | let c = || { let _ = &t; LL | diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed index f17fab8e81f..a3e51a2b8e9 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed +++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed @@ -18,7 +18,7 @@ fn closure_contains_block() { let t = (Foo(0), Foo(0)); let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; }; @@ -29,7 +29,7 @@ fn closure_doesnt_contain_block() { let t = (Foo(0), Foo(0)); let c = || { let _ = &t; t.0 }; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured c(); } diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs index 33aff10c520..0eb837b6888 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs @@ -18,7 +18,7 @@ fn closure_contains_block() { let t = (Foo(0), Foo(0)); let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; }; @@ -29,7 +29,7 @@ fn closure_doesnt_contain_block() { let t = (Foo(0), Foo(0)); let c = || t.0; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured c(); } diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr index 611fbc4fff3..e6173217edc 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr @@ -14,7 +14,7 @@ note: the lint level is defined here | LL | #![deny(disjoint_capture_drop_reorder)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: `let _ = &t` causes `t` to be fully captured +help: add a dummy let to cause `t` to be fully captured | LL | let c = || { let _ = &t; LL | @@ -29,7 +29,7 @@ error: drop order affected for closure because of `capture_disjoint_fields` LL | let c = || t.0; | ^^^^^^ | -help: `let _ = &t` causes `t` to be fully captured +help: add a dummy let to cause `t` to be fully captured | LL | let c = || { let _ = &t; t.0 }; | ^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed index 06932c1ae64..b739035c784 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed @@ -18,7 +18,7 @@ fn test_precise_analysis_drop_paths_not_captured_by_move() { let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; let _t = &t.1; }; @@ -41,7 +41,7 @@ fn test_precise_analysis_long_path_missing() { let c = || { let _ = &u; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &u` causes `u` to be fully captured + //~| HELP: add a dummy let to cause `u` to be fully captured let _x = u.0.0; let _x = u.0.1; let _x = u.1.0; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs b/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs index 3661c2ca7ed..e1f29c9d0e9 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs @@ -18,7 +18,7 @@ fn test_precise_analysis_drop_paths_not_captured_by_move() { let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; let _t = &t.1; }; @@ -41,7 +41,7 @@ fn test_precise_analysis_long_path_missing() { let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &u` causes `u` to be fully captured + //~| HELP: add a dummy let to cause `u` to be fully captured let _x = u.0.0; let _x = u.0.1; let _x = u.1.0; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr index fcfd08d61e0..7135ded13c2 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr @@ -15,7 +15,7 @@ note: the lint level is defined here | LL | #![deny(disjoint_capture_drop_reorder)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: `let _ = &t` causes `t` to be fully captured +help: add a dummy let to cause `t` to be fully captured | LL | let c = || { let _ = &t; LL | @@ -38,7 +38,7 @@ LL | | let _x = u.1.0; LL | | }; | |_____^ | -help: `let _ = &u` causes `u` to be fully captured +help: add a dummy let to cause `u` to be fully captured | LL | let c = || { let _ = &u; LL | diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed index b44624be5f9..e1b212153f4 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed +++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed @@ -24,7 +24,7 @@ fn test1_all_need_migration() { let c = || { let _ = (&t, &t1, &t2); //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP:` let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured + //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured let _t = t.0; let _t1 = t1.0; let _t2 = t2.0; @@ -42,7 +42,7 @@ fn test2_only_precise_paths_need_migration() { let c = || { let _ = (&t, &t1); //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP:` let _ = (&t, &t1)` causes `t`, `t1` to be fully captured + //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured let _t = t.0; let _t1 = t1.0; let _t2 = t2; @@ -58,7 +58,7 @@ fn test3_only_by_value_need_migration() { let t1 = (Foo(0), Foo(0)); let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; println!("{:?}", t1.1); }; @@ -75,7 +75,7 @@ fn test4_type_contains_drop_need_migration() { let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; }; @@ -90,7 +90,7 @@ fn test5_drop_non_drop_aggregate_need_migration() { let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; }; @@ -103,7 +103,7 @@ fn test6_significant_insignificant_drop_aggregate_need_migration() { let c = || { let _ = &t; //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.1; }; @@ -118,7 +118,7 @@ fn test7_move_closures_non_copy_types_might_need_migration() { let c = move || { let _ = (&t1, &t); //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured + //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured println!("{:?} {:?}", t1.1, t.1); }; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs index 5cb2f611bc1..106b2933515 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs @@ -24,7 +24,7 @@ fn test1_all_need_migration() { let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP:` let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured + //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured let _t = t.0; let _t1 = t1.0; let _t2 = t2.0; @@ -42,7 +42,7 @@ fn test2_only_precise_paths_need_migration() { let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP:` let _ = (&t, &t1)` causes `t`, `t1` to be fully captured + //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured let _t = t.0; let _t1 = t1.0; let _t2 = t2; @@ -58,7 +58,7 @@ fn test3_only_by_value_need_migration() { let t1 = (Foo(0), Foo(0)); let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; println!("{:?}", t1.1); }; @@ -75,7 +75,7 @@ fn test4_type_contains_drop_need_migration() { let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; }; @@ -90,7 +90,7 @@ fn test5_drop_non_drop_aggregate_need_migration() { let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.0; }; @@ -103,7 +103,7 @@ fn test6_significant_insignificant_drop_aggregate_need_migration() { let c = || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = &t` causes `t` to be fully captured + //~| HELP: add a dummy let to cause `t` to be fully captured let _t = t.1; }; @@ -118,7 +118,7 @@ fn test7_move_closures_non_copy_types_might_need_migration() { let c = move || { //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields` - //~| HELP: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured + //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured println!("{:?} {:?}", t1.1, t.1); }; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr index 2ca2baa9cbc..ee29fe13060 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr @@ -16,7 +16,7 @@ note: the lint level is defined here | LL | #![deny(disjoint_capture_drop_reorder)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: `let _ = (&t, &t1, &t2)` causes `t`, `t1`, `t2` to be fully captured +help: add a dummy let to cause `t`, `t1`, `t2` to be fully captured | LL | let c = || { let _ = (&t, &t1, &t2); LL | @@ -39,7 +39,7 @@ LL | | let _t2 = t2; LL | | }; | |_____^ | -help: `let _ = (&t, &t1)` causes `t`, `t1` to be fully captured +help: add a dummy let to cause `t`, `t1` to be fully captured | LL | let c = || { let _ = (&t, &t1); LL | @@ -61,7 +61,7 @@ LL | | println!("{:?}", t1.1); LL | | }; | |_____^ | -help: `let _ = &t` causes `t` to be fully captured +help: add a dummy let to cause `t` to be fully captured | LL | let c = || { let _ = &t; LL | @@ -82,7 +82,7 @@ LL | | let _t = t.0; LL | | }; | |_____^ | -help: `let _ = &t` causes `t` to be fully captured +help: add a dummy let to cause `t` to be fully captured | LL | let c = || { let _ = &t; LL | @@ -102,7 +102,7 @@ LL | | let _t = t.0; LL | | }; | |_____^ | -help: `let _ = &t` causes `t` to be fully captured +help: add a dummy let to cause `t` to be fully captured | LL | let c = || { let _ = &t; LL | @@ -122,7 +122,7 @@ LL | | let _t = t.1; LL | | }; | |_____^ | -help: `let _ = &t` causes `t` to be fully captured +help: add a dummy let to cause `t` to be fully captured | LL | let c = || { let _ = &t; LL | @@ -142,7 +142,7 @@ LL | | println!("{:?} {:?}", t1.1, t.1); LL | | }; | |_____^ | -help: `let _ = (&t1, &t)` causes `t1`, `t` to be fully captured +help: add a dummy let to cause `t1`, `t` to be fully captured | LL | let c = move || { let _ = (&t1, &t); LL | From ca14abbab1821d20d4d326af2acec916ccc0806e Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sat, 27 Mar 2021 11:12:38 -0600 Subject: [PATCH 285/370] Fix stack overflow detection on FreeBSD 11.1+ Beginning with FreeBSD 10.4 and 11.1, there is one guard page by default. And the stack autoresizes, so if Rust allocates its own guard page, then FreeBSD's will simply move up one page. The best solution is to just use the OS's guard page. --- library/std/src/sys/unix/thread.rs | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 01a12dcf5a2..b8f43caec32 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -343,6 +343,20 @@ pub mod guard { // it can eventually grow to. It cannot be used to determine // the position of kernel's stack guard. None + } else if cfg!(target_os = "freebsd") { + // FreeBSD's stack autogrows, and optionally includes a guard page + // at the bottom. If we try to remap the bottom of the stack + // ourselves, FreeBSD's guard page moves upwards. So we'll just use + // the builtin guard page. + let stackaddr = get_stack_start_aligned()?; + let guardaddr = stackaddr as usize; + // Technically the number of guard pages is tunable and controlled + // by the security.bsd.stack_guard_page sysctl, but there are + // few reasons to change it from the default. The default value has + // been 1 ever since FreeBSD 11.1 and 10.4. + const GUARD_PAGES: usize = 1; + let guard = guardaddr..guardaddr + GUARD_PAGES * page_size; + Some(guard) } else { // Reallocate the last page of the stack. // This ensures SIGBUS will be raised on @@ -371,9 +385,8 @@ pub mod guard { } let guardaddr = stackaddr as usize; - let offset = if cfg!(target_os = "freebsd") { 2 } else { 1 }; - Some(guardaddr..guardaddr + offset * page_size) + Some(guardaddr..guardaddr + page_size) } } @@ -417,11 +430,7 @@ pub mod guard { assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut size), 0); let stackaddr = stackaddr as usize; - ret = if cfg!(target_os = "freebsd") { - // FIXME does freebsd really fault *below* the guard addr? - let guardaddr = stackaddr - guardsize; - Some(guardaddr - PAGE_SIZE.load(Ordering::Relaxed)..guardaddr) - } else if cfg!(target_os = "netbsd") { + ret = if cfg!(any(target_os = "freebsd", target_os = "netbsd")) { Some(stackaddr - guardsize..stackaddr) } else if cfg!(all(target_os = "linux", target_env = "musl")) { Some(stackaddr - guardsize..stackaddr) From fad53880394f0cb4a8e2367fcc218c1fa55539d6 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Thu, 1 Apr 2021 12:25:45 -0700 Subject: [PATCH 286/370] Simplify coverage tests This change reduces the risk of impacting coverage tests on unrelated changes (such as MIR and Span changes), and reduces the burden when blessing coverage changes in case it is necessary. * Remove all spanview tests. The spanview tests were useful during development, but they can be generated as needed, via compiler command line flags. They aren't critical to confirming coverage results. (The coverage report tests are sufficient.) When spanview regeneration was necessary, the diffs were way too hard to read to be useful anyway. So I'm removing them to reduce friction from a feature that is no longer useful. * Remove the requirement for `llvm-cov show --debug` when blessing tests. The `--debug` flag is, unfortunately, only available if LLVM is built with `optimize = false` (in Rust's config.toml). This adds significant time and resource burdens to the contributor's build. As it turns out, for other reasons in the past, I wasn't actually using the debug output (counter info) to validate coverage anymore either, so it was required for no reason, I now realize. --- .../coverage-reports/Makefile | 80 - .../coverage-spanview/Makefile | 92 - .../coverage-spanview/escape_url.py | 12 - ...ort.main.-------.InstrumentCoverage.0.html | 106 - ...ht_abort.-------.InstrumentCoverage.0.html | 163 - ...ert.main.-------.InstrumentCoverage.0.html | 102 - ...l_assert.-------.InstrumentCoverage.0.html | 97 - ...osure#0}.-------.InstrumentCoverage.0.html | 82 - .../async.c.-------.InstrumentCoverage.0.html | 80 - ...osure#0}.-------.InstrumentCoverage.0.html | 75 - .../async.d.-------.InstrumentCoverage.0.html | 74 - ...osure#0}.-------.InstrumentCoverage.0.html | 75 - .../async.e.-------.InstrumentCoverage.0.html | 74 - ...osure#0}.-------.InstrumentCoverage.0.html | 84 - ...osure#1}.-------.InstrumentCoverage.0.html | 84 - ...osure#2}.-------.InstrumentCoverage.0.html | 84 - ...osure#3}.-------.InstrumentCoverage.0.html | 75 - ...block_on.-------.InstrumentCoverage.0.html | 239 - ...osure#0}.-------.InstrumentCoverage.0.html | 75 - .../async.f.-------.InstrumentCoverage.0.html | 74 - ...osure#0}.-------.InstrumentCoverage.0.html | 75 - ...sync.foo.-------.InstrumentCoverage.0.html | 74 - ...osure#0}.-------.InstrumentCoverage.0.html | 82 - .../async.g.-------.InstrumentCoverage.0.html | 80 - ...osure#0}.-------.InstrumentCoverage.0.html | 82 - .../async.h.-------.InstrumentCoverage.0.html | 81 - ...osure#0}.-------.InstrumentCoverage.0.html | 89 - .../async.i.-------.InstrumentCoverage.0.html | 83 - ...sync.j-c.-------.InstrumentCoverage.0.html | 90 - ...sync.j-d.-------.InstrumentCoverage.0.html | 75 - ...sync.j-f.-------.InstrumentCoverage.0.html | 75 - .../async.j.-------.InstrumentCoverage.0.html | 106 - .../async.k.-------.InstrumentCoverage.0.html | 80 - .../async.l.-------.InstrumentCoverage.0.html | 80 - ...osure#0}.-------.InstrumentCoverage.0.html | 78 - .../async.m.-------.InstrumentCoverage.0.html | 74 - ...ync.main.-------.InstrumentCoverage.0.html | 190 - ...osure#0}.-------.InstrumentCoverage.0.html | 96 - ...sure#10}.-------.InstrumentCoverage.0.html | 96 - ...sure#11}.-------.InstrumentCoverage.0.html | 96 - ...osure#1}.-------.InstrumentCoverage.0.html | 96 - ...osure#2}.-------.InstrumentCoverage.0.html | 128 - ...osure#3}.-------.InstrumentCoverage.0.html | 91 - ...osure#4}.-------.InstrumentCoverage.0.html | 76 - ...osure#5}.-------.InstrumentCoverage.0.html | 115 - ...osure#6}.-------.InstrumentCoverage.0.html | 87 - ...osure#7}.-------.InstrumentCoverage.0.html | 115 - ...osure#8}.-------.InstrumentCoverage.0.html | 89 - ...osure#9}.-------.InstrumentCoverage.0.html | 89 - ...ure.main.-------.InstrumentCoverage.0.html | 10921 ---------------- ...ons.main.-------.InstrumentCoverage.0.html | 307 - ...ode.main.-------.InstrumentCoverage.0.html | 143 - ...nused_fn.-------.InstrumentCoverage.0.html | 143 - ..._library.-------.InstrumentCoverage.0.html | 143 - ...est.main.-------.InstrumentCoverage.0.html | 96 - ...doctests.-------.InstrumentCoverage.0.html | 113 - ...ait.main.-------.InstrumentCoverage.0.html | 152 - ...#0}-drop.-------.InstrumentCoverage.0.html | 133 - ...ics.main.-------.InstrumentCoverage.0.html | 237 - ...strength.-------.InstrumentCoverage.0.html | 85 - ...#1}-drop.-------.InstrumentCoverage.0.html | 133 - .../if.main.-------.InstrumentCoverage.0.html | 238 - ...lse.main.-------.InstrumentCoverage.0.html | 195 - ....display.-------.InstrumentCoverage.0.html | 161 - ...ne.error.-------.InstrumentCoverage.0.html | 79 - ...e.length.-------.InstrumentCoverage.0.html | 82 - ...ine.main.-------.InstrumentCoverage.0.html | 94 - ...ermutate.-------.InstrumentCoverage.0.html | 183 - ...utations.-------.InstrumentCoverage.0.html | 113 - ...ine.swap.-------.InstrumentCoverage.0.html | 173 - ...ait_func.-------.InstrumentCoverage.0.html | 93 - ...-in_func.-------.InstrumentCoverage.0.html | 203 - ...ait_func.-------.InstrumentCoverage.0.html | 101 - ...ems.main.-------.InstrumentCoverage.0.html | 189 - ...ean.main.-------.InstrumentCoverage.0.html | 259 - ...lue.main.-------.InstrumentCoverage.0.html | 128 - ...hes.main.-------.InstrumentCoverage.0.html | 161 - ...l#0}-fmt.-------.InstrumentCoverage.0.html | 100 - ...ern.main.-------.InstrumentCoverage.0.html | 259 - ...ops.main.-------.InstrumentCoverage.0.html | 166 - ...low.main.-------.InstrumentCoverage.0.html | 258 - ...overflow.-------.InstrumentCoverage.0.html | 394 - ...ind.main.-------.InstrumentCoverage.0.html | 102 - ...ht_panic.-------.InstrumentCoverage.0.html | 163 - ..._eq.main.-------.InstrumentCoverage.0.html | 295 - ...l#0}-new.-------.InstrumentCoverage.0.html | 108 - ...l#1}-cmp.-------.InstrumentCoverage.0.html | 74 - ...tial_cmp.-------.InstrumentCoverage.0.html | 74 - ...total_eq.-------.InstrumentCoverage.0.html | 75 - ...pl#6}-eq.-------.InstrumentCoverage.0.html | 74 - ...pl#6}-ne.-------.InstrumentCoverage.0.html | 74 - ...l#7}-fmt.-------.InstrumentCoverage.0.html | 110 - ...8}-clone.-------.InstrumentCoverage.0.html | 88 - ...oop.main.-------.InstrumentCoverage.0.html | 193 - ...tch.main.-------.InstrumentCoverage.0.html | 222 - ...oop.main.-------.InstrumentCoverage.0.html | 81 - ...ult.call.-------.InstrumentCoverage.0.html | 82 - ...ult.main.-------.InstrumentCoverage.0.html | 129 - ...used.foo.-------.InstrumentCoverage.0.html | 87 - ...sed.main.-------.InstrumentCoverage.0.html | 98 - ...sed_func.-------.InstrumentCoverage.0.html | 86 - ...ed_func2.-------.InstrumentCoverage.0.html | 86 - ...ed_func3.-------.InstrumentCoverage.0.html | 86 - ...ate_func.-------.InstrumentCoverage.0.html | 87 - ...function.-------.InstrumentCoverage.0.html | 115 - ...function.-------.InstrumentCoverage.0.html | 133 - ...function.-------.InstrumentCoverage.0.html | 115 - ...ib_crate.-------.InstrumentCoverage.0.html | 190 - ...function.-------.InstrumentCoverage.0.html | 133 - ...function.-------.InstrumentCoverage.0.html | 110 - ...function.-------.InstrumentCoverage.0.html | 133 - ...function.-------.InstrumentCoverage.0.html | 133 - ...function.-------.InstrumentCoverage.0.html | 133 - ...function.-------.InstrumentCoverage.0.html | 115 - ...function.-------.InstrumentCoverage.0.html | 133 - ...function.-------.InstrumentCoverage.0.html | 115 - ...ib_crate.-------.InstrumentCoverage.0.html | 190 - ...function.-------.InstrumentCoverage.0.html | 133 - ...function.-------.InstrumentCoverage.0.html | 110 - ...function.-------.InstrumentCoverage.0.html | 110 - ...function.-------.InstrumentCoverage.0.html | 133 - ...function.-------.InstrumentCoverage.0.html | 133 - ...function.-------.InstrumentCoverage.0.html | 133 - ...ate.main.-------.InstrumentCoverage.0.html | 193 - ...ate.main.-------.InstrumentCoverage.0.html | 249 - ...ile.main.-------.InstrumentCoverage.0.html | 82 - ...ret.main.-------.InstrumentCoverage.0.html | 130 - ...osure#0}.-------.InstrumentCoverage.0.html | 79 - ...osure#1}.-------.InstrumentCoverage.0.html | 81 - ...eld.main.-------.InstrumentCoverage.0.html | 138 - .../coverage/coverage_tools.mk | 8 - 131 files changed, 26664 deletions(-) delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/Makefile delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/escape_url.py delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.abort/abort.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.abort/abort.might_abort.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.assert/assert.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.assert/assert.might_fail_assert.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.c-{closure#0}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.c.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.d-{closure#0}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.d.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.e-{closure#0}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.e.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#0}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#1}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#2}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#3}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.f-{closure#0}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.f.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.foo-{closure#0}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.foo.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.g-{closure#0}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.g.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.h-{closure#0}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.h.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.i-{closure#0}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.i.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j-c.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j-d.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j-f.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.k.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.l.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m-{closure#0}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#10}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#11}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#4}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#5}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#6}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#7}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#8}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#9}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.conditions/conditions.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.dead_code/dead_code.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.dead_code/dead_code.unused_fn.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.dead_code/dead_code.unused_pub_fn_not_in_library.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.drop_trait/drop_trait.{impl#0}-drop.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.generics/generics.{impl#0}-set_strength.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.generics/generics.{impl#1}-drop.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.display.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.error.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.length.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutate.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutations.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.swap.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main-InTrait-default_trait_func.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main-{impl#0}-trait_func.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.loop_break_value/loop_break_value.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.loops_branches/loops_branches.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.loops_branches/loops_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.match_or_pattern/match_or_pattern.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.overflow/overflow.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.overflow/overflow.might_overflow.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.panic_unwind/panic_unwind.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.panic_unwind/panic_unwind.might_panic.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#0}-new.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#1}-cmp.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-eq.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-ne.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#7}-fmt.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#8}-clone.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.tight_inf_loop/tight_inf_loop.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.foo.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func2.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func3.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_template_func.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.unused_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.unused_generic_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.unused_private_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.use_this_lib_crate.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_only_from_bin_crate_generic_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_only_from_this_lib_crate_generic_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_with_same_type_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_generic_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_private_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.use_this_lib_crate.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_inline_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_only_from_bin_crate_generic_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_only_from_this_lib_crate_generic_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_with_same_type_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_inline_crate/uses_inline_crate.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.while_early_ret/while_early_ret.main.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.yield/yield.main-{closure#0}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.yield/yield.main-{closure#1}.-------.InstrumentCoverage.0.html delete mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.yield/yield.main.-------.InstrumentCoverage.0.html diff --git a/src/test/run-make-fulldeps/coverage-reports/Makefile b/src/test/run-make-fulldeps/coverage-reports/Makefile index dd5e28b449c..d3d398f1fac 100644 --- a/src/test/run-make-fulldeps/coverage-reports/Makefile +++ b/src/test/run-make-fulldeps/coverage-reports/Makefile @@ -61,13 +61,6 @@ endif LLVM_COV_IGNORE_FILES=\ --ignore-filename-regex='(uses_crate.rs|uses_inline_crate.rs)' -# When generating `expected_*` results (using `x.py test --bless`), the `--debug` flag is forced. -# If assertions are disabled, the command will fail with an error, rather than attempt to generate -# only partial results. -ifdef RUSTC_BLESS_TEST -DEBUG_FLAG=--debug -endif - all: $(patsubst $(SOURCEDIR)/lib/%.rs,%,$(wildcard $(SOURCEDIR)/lib/*.rs)) $(patsubst $(SOURCEDIR)/%.rs,%,$(wildcard $(SOURCEDIR)/*.rs)) # Ensure there are no `expected` results for tests that may have been removed or renamed @@ -177,76 +170,3 @@ else false \ ) endif - -#################################################################################################### - -# The following Makefile content was used to copy the generated `counters` files -# to `expected_` files (when `--bless`ed) and to compare them via `diff`; but for -# multiple reasons, these files cannot easily be used for test validation: -# -# * Output lines can be produced in non-deterministic order (depending on the -# target platform, and sometimes on unrelated codegen changes). -# * Some lines include demangled function names, making them more challenging -# to interpret and compare. -# -# The files are still generated (in `$(TMPDIR)`) to support developers wanting -# to inspect the counters, for debugging purposes. -# -# ifdef RUSTC_BLESS_TEST -# cp "$(TMPDIR)"/actual_show_coverage_counters.$@.txt \ -# expected_show_coverage_counters.$@.txt -# else -# -# ifdef DEBUG_FLAG -# $(DIFF) expected_show_coverage_counters.$@.txt "$(TMPDIR)"/actual_show_coverage_counters.$@.txt || \ -# ( grep -q '^\/\/ ignore-llvm-cov-show-diffs' $(SOURCEDIR)/$@.rs && \ -# >&2 echo 'diff failed, but suppressed with `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs' \ -# ) || \ -# ( >&2 echo 'diff failed, and not suppressed without `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs'; \ -# >&2 echo '(Ignore anyway until mangled function names in "counters" files are demangled.)' \ -# ) -# endif -# -# endif - -#################################################################################################### - -# The following Makefile content, and short JSON script, were used to generate -# coverage reports in JSON when the `llvm-cov show` reports were less reliable for -# testing. At the present time, however, the `llvm-cov show` results, and methods -# for comparing them, are working for all tests, making the JSON reports redundant. -# -# If this changes in the future, the scripts are left here, commented out, but can -# be resurrected if desired. This could be used to compare *only* the JSON files; -# and in that case, the `llvm-cov show` reports can be ignored by inserting -# `// ignore-llvm-cov-show-diffs` at the top of the source file. -# -# # Generate a coverage report in JSON, using `llvm-cov export`, and fail if -# # there are differences from the expected output. -# "$(LLVM_BIN_DIR)"/llvm-cov export \ -# $(LLVM_COV_IGNORE_FILES) \ -# --summary-only \ -# --instr-profile="$(TMPDIR)"/$@.profdata \ -# $(call BIN,"$(TMPDIR)"/$@) \ -# | "$(PYTHON)" $(BASEDIR)/prettify_json.py \ -# > "$(TMPDIR)"/actual_export_coverage.$@.json -# -# ifdef RUSTC_BLESS_TEST -# cp "$(TMPDIR)"/actual_export_coverage.$@.json expected_export_coverage.$@.json -# else -# # Check that exported JSON coverage data matches what we expect (`--bless` refreshes `expected`) -# $(DIFF) expected_export_coverage.$@.json "$(TMPDIR)"/actual_export_coverage.$@.json -# endif -# -# # # If generating coverage reports in JSON, this Makefile is accompanied by -# # # a Python script, `prettify_json.py`, which is defined: -# # -# # #!/usr/bin/env python -# # -# # import sys -# # import json -# # -# # # Try to decode line in order to ensure it is a valid JSON document -# # for line in sys.stdin: -# # parsed = json.loads(line) -# # print (json.dumps(parsed, indent=2, separators=(',', ': '), sort_keys=True)) diff --git a/src/test/run-make-fulldeps/coverage-spanview/Makefile b/src/test/run-make-fulldeps/coverage-spanview/Makefile deleted file mode 100644 index b3d1009dbd0..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/Makefile +++ /dev/null @@ -1,92 +0,0 @@ -# needs-profiler-support -# min-llvm-version: 11.0 - --include ../coverage/coverage_tools.mk - -BASEDIR=../coverage-spanview -SOURCEDIR=../coverage - -define SPANVIEW_HEADER - - -endef -export SPANVIEW_HEADER - -all: $(patsubst $(SOURCEDIR)/lib/%.rs,%,$(wildcard $(SOURCEDIR)/lib/*.rs)) $(patsubst $(SOURCEDIR)/%.rs,%,$(wildcard $(SOURCEDIR)/*.rs)) - -# Ensure there are no `expected` results for tests that may have been removed or renamed -.PHONY: clear_expected_if_blessed -clear_expected_if_blessed: -ifdef RUSTC_BLESS_TEST - rm -rf expected_mir_dump.*/ -endif - --include clear_expected_if_blessed - -# FIXME(richkadel): The actions for these two types of targets (libraries and binaries) should be -# combined. - -%: $(SOURCEDIR)/lib/%.rs - # Compile the test library with coverage instrumentation - $(RUSTC) $(SOURCEDIR)/lib/$@.rs \ - $$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/lib/$@.rs ) \ - --crate-type rlib \ - -Ztrim-diagnostic-paths=no \ - -Zdump-mir=InstrumentCoverage -Zdump-mir-spanview -Zdump-mir-dir="$(TMPDIR)"/mir_dump.$@ \ - -Zinstrument-coverage - - for path in "$(TMPDIR)"/mir_dump.$@/*; do \ - file="$$(basename "$$path")"; \ - urlescaped="$$("$(PYTHON)" $(BASEDIR)/escape_url.py $$file)" || exit $$?; \ - printf "$$SPANVIEW_HEADER\n" "$@" "$$urlescaped" > "$$path".modified; \ - tail -n +2 "$$path" >> "$$path".modified; \ - mv "$$path".modified "$$path"; \ - done && true # for/done ends in non-zero status - -ifdef RUSTC_BLESS_TEST - mkdir -p expected_mir_dump.$@ - cp "$(TMPDIR)"/mir_dump.$@/*InstrumentCoverage.0.html expected_mir_dump.$@/ -else - # Check that the selected `mir_dump` files match what we expect (`--bless` refreshes `expected`) - mkdir -p "$(TMPDIR)"/actual_mir_dump.$@ - rm -f "$(TMPDIR)"/actual_mir_dump.$@/* - cp "$(TMPDIR)"/mir_dump.$@/*InstrumentCoverage.0.html "$(TMPDIR)"/actual_mir_dump.$@/ - $(DIFF) -r expected_mir_dump.$@/ "$(TMPDIR)"/actual_mir_dump.$@/ -endif - -%: $(SOURCEDIR)/%.rs - # Compile the test program with coverage instrumentation - $(RUSTC) $(SOURCEDIR)/$@.rs \ - $$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/$@.rs ) \ - -L "$(TMPDIR)" \ - -Ztrim-diagnostic-paths=no \ - -Zdump-mir=InstrumentCoverage -Zdump-mir-spanview -Zdump-mir-dir="$(TMPDIR)"/mir_dump.$@ \ - -Zinstrument-coverage - - for path in "$(TMPDIR)"/mir_dump.$@/*; do \ - file="$$(basename "$$path")"; \ - urlescaped="$$("$(PYTHON)" $(BASEDIR)/escape_url.py $$file)" || exit $$?; \ - printf "$$SPANVIEW_HEADER\n" "$@" "$$urlescaped" > "$$path".modified; \ - tail -n +2 "$$path" >> "$$path".modified; \ - mv "$$path".modified "$$path"; \ - done && true # for/done ends in non-zero status - -ifdef RUSTC_BLESS_TEST - mkdir -p expected_mir_dump.$@ - cp "$(TMPDIR)"/mir_dump.$@/*InstrumentCoverage.0.html expected_mir_dump.$@/ -else - # Check that the selected `mir_dump` files match what we expect (`--bless` refreshes `expected`) - mkdir -p "$(TMPDIR)"/actual_mir_dump.$@ - rm -f "$(TMPDIR)"/actual_mir_dump.$@/* - cp "$(TMPDIR)"/mir_dump.$@/*InstrumentCoverage.0.html "$(TMPDIR)"/actual_mir_dump.$@/ - $(DIFF) -r expected_mir_dump.$@/ "$(TMPDIR)"/actual_mir_dump.$@/ -endif diff --git a/src/test/run-make-fulldeps/coverage-spanview/escape_url.py b/src/test/run-make-fulldeps/coverage-spanview/escape_url.py deleted file mode 100644 index b725ed46303..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/escape_url.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python - -import sys - -# Support python 2 or 3 -try: - from urllib.parse import quote -except ImportError: - from urllib import quote - -# Converts the input string into a valid URL parameter string. -print (quote(' '.join(sys.argv[1:]))) diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.abort/abort.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.abort/abort.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 176587af25b..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.abort/abort.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - -abort.main - Coverage Spans - - - -
@0⦊fn main() -> Result<(), u8> { - let mut countdown = 10⦉@0; - while @1,2⦊countdown > 0⦉@1,2 { - if @3,5⦊countdown < 5⦉@3,5 @6,8⦊{ - might_abort(false); - }⦉@6,8@7⦊⦉@7 - // See discussion (below the `Notes` section) on coverage results for the closing brace. - if @9⦊countdown < 5⦉@9 @10,12⦊{ might_abort(false); }⦉@10,12@11⦊⦉@11 // Counts for different regions on one line. - // For the following example, the closing brace is the last character on the line. - // This shows the character after the closing brace is highlighted, even if that next - // character is a newline. - if @13⦊countdown < 5⦉@13 @14,16⦊{ might_abort(false); }⦉@14,16@15⦊⦉@15 - @17,18⦊countdown -= 1⦉@17,18; - } - @4⦊Ok(()) -}⦉@4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.abort/abort.might_abort.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.abort/abort.might_abort.-------.InstrumentCoverage.0.html deleted file mode 100644 index a302b974ae1..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.abort/abort.might_abort.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,163 +0,0 @@ - - - - -abort.might_abort - Coverage Spans - - - -
@0⦊fn might_abort(should_abort: bool) ⦉@0{ - if @0⦊should_abort⦉@0 { - @1,3,4⦊println!("aborting..."); - panic!("panics and aborts");⦉@1,3,4 - } else @2,5,6⦊{ - println!("Don't Panic"); - } -}⦉@2,5,6
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.assert/assert.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.assert/assert.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 365e94cd31e..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.assert/assert.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - -assert.main - Coverage Spans - - - -
@0⦊fn main() -> Result<(),u8> { - let mut countdown = 10⦉@0; - while @1,2⦊countdown > 0⦉@1,2 { - if @3,5⦊countdown == 1⦉@3,5 @6,8⦊{ - might_fail_assert(3); - }⦉@6,8 else if @7⦊countdown < 5⦉@7 @9,11⦊{ - might_fail_assert(2); - }⦉@9,11@10⦊⦉@10 - @13,14⦊countdown -= 1⦉@13,14; - } - @4⦊Ok(()) -}⦉@4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.assert/assert.might_fail_assert.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.assert/assert.might_fail_assert.-------.InstrumentCoverage.0.html deleted file mode 100644 index db72a5306ff..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.assert/assert.might_fail_assert.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - -assert.might_fail_assert - Coverage Spans - - - -
@0,1,2,3,4⦊fn might_fail_assert(one_plus_one: u32) ⦉@0,1,2,3,4{ - @0,1,2,3,4⦊println!("does 1 + 1 = {}?", one_plus_one);⦉@0,1,2,3,4 - assert_eq!(@0,1,2,3,4⦊1 + 1⦉@0,1,2,3,4, one_plus_one, @5,7⦊"the argument was wrong"⦉@5,7); -}@6⦊⦉@6
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.c-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.c-{closure#0}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 21bfce701fe..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.c-{closure#0}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - -async.c-{closure#0} - Coverage Spans - - - -
@0⦊{ - if x == 8⦉@0 { - @1⦊1⦉@1 - } else { - @2⦊0⦉@2 - } -}@3⦊⦉@3
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.c.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.c.-------.InstrumentCoverage.0.html deleted file mode 100644 index 3eee0dd4100..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.c.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,80 +0,0 @@ - - - - -async.c - Coverage Spans - - - -
@0,1⦊async fn c(x: u8) -> u8 ⦉@0,1{ - if x == 8 { - 1 - } else { - 0 - } -}
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.d-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.d-{closure#0}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 7cf34f07795..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.d-{closure#0}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - -async.d-{closure#0} - Coverage Spans - - - -
@0⦊⦉@0{ 1 }
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.d.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.d.-------.InstrumentCoverage.0.html deleted file mode 100644 index 5c7f6e00224..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.d.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - -async.d - Coverage Spans - - - -
@0,1⦊async fn d() -> u8 ⦉@0,1{ 1 }
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.e-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.e-{closure#0}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 1f95a7d35af..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.e-{closure#0}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - -async.e-{closure#0} - Coverage Spans - - - -
@0⦊⦉@0{ 1 }
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.e.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.e.-------.InstrumentCoverage.0.html deleted file mode 100644 index ee3b7b1d7ff..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.e.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - -async.e - Coverage Spans - - - -
@0,1⦊async fn e() -> u8 ⦉@0,1{ 1 }
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#0}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 64fc1568b00..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#0}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - -async.executor-block_on-VTABLE-{closure#0} - Coverage Spans - - - -
@0,1,2,3⦊⦉@0,1,2,3$crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+))
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#1}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#1}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 1bbcfa5744b..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#1}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - -async.executor-block_on-VTABLE-{closure#1} - Coverage Spans - - - -
@0,1,2,3⦊⦉@0,1,2,3$crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+))
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#2}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#2}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 14cb98d20c9..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#2}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - -async.executor-block_on-VTABLE-{closure#2} - Coverage Spans - - - -
@0,1,2,3⦊⦉@0,1,2,3$crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+))
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#3}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#3}.-------.InstrumentCoverage.0.html deleted file mode 100644 index ef2fe7d0682..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on-VTABLE-{closure#3}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - -async.executor-block_on-VTABLE-{closure#3} - Coverage Spans - - - -
|_| @0⦊()⦉@0
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on.-------.InstrumentCoverage.0.html deleted file mode 100644 index 9a5bd6e42cd..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,239 +0,0 @@ - - - - -async.executor-block_on - Coverage Spans - - - -
@0,1,2,3,4,5⦊pub fn block_on<F: Future>(mut future: F) -> F::Output { - let mut future = unsafe { Pin::new_unchecked(&mut future) }; - - static VTABLE: RawWakerVTable = RawWakerVTable::new( - |_| unimplemented!("clone"), - |_| unimplemented!("wake"), - |_| unimplemented!("wake_by_ref"), - |_| (), - ); - let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; - let mut context = Context::from_waker(&waker)⦉@0,1,2,3,4,5; - - loop { - if let Poll::Ready(@10,12,14,15,16,17⦊val⦉@10,12,14,15,16,17) = @6,7,8,9⦊future.as_mut().poll(&mut context)⦉@6,7,8,9 { - break @10,12,14,15,16,17⦊val⦉@10,12,14,15,16,17; - }@11,13⦊⦉@11,13 - } - }@10,12,14,15,16,17⦊⦉@10,12,14,15,16,17
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.f-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.f-{closure#0}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 74b62673ac9..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.f-{closure#0}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - -async.f-{closure#0} - Coverage Spans - - - -
@0⦊⦉@0{ 1 }
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.f.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.f.-------.InstrumentCoverage.0.html deleted file mode 100644 index a31bca54df2..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.f.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - -async.f - Coverage Spans - - - -
@0,1⦊async fn f() -> u8 ⦉@0,1{ 1 }
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.foo-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.foo-{closure#0}.-------.InstrumentCoverage.0.html deleted file mode 100644 index b8c53cccabd..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.foo-{closure#0}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - -async.foo-{closure#0} - Coverage Spans - - - -
@0⦊⦉@0{ [false; 10] }
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.foo.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.foo.-------.InstrumentCoverage.0.html deleted file mode 100644 index cf72a9d532c..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.foo.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - -async.foo - Coverage Spans - - - -
@0,1⦊async fn foo() -> [bool; 10] ⦉@0,1{ [false; 10] }
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.g-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.g-{closure#0}.-------.InstrumentCoverage.0.html deleted file mode 100644 index b10012621b7..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.g-{closure#0}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - -async.g-{closure#0} - Coverage Spans - - - -
@0,3,4⦊{ - match x⦉@0,3,4 { - @17⦊y⦉@17 if @0,3,4⦊e()⦉@0,3,4.await == @10,13,15,16⦊y⦉@10,13,15,16 => @17⦊()⦉@17, - @33⦊y⦉@33 if @1,19,20⦊f()⦉@1,19,20.await == @26,29,31,32⦊y⦉@26,29,31,32 => @33⦊()⦉@33, - _ => @2⦊()⦉@2, - } -}@35,36⦊⦉@35,36
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.g.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.g.-------.InstrumentCoverage.0.html deleted file mode 100644 index 973995477b9..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.g.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,80 +0,0 @@ - - - - -async.g - Coverage Spans - - - -
@0,1⦊pub async fn g(x: u8) ⦉@0,1{ - match x { - y if e().await == y => (), - y if f().await == y => (), - _ => (), - } -}
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.h-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.h-{closure#0}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 6b4b43f8365..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.h-{closure#0}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - -async.h-{closure#0} - Coverage Spans - - - -
@0,2,3⦊{ // The function signature is counted when called, but the body is not - // executed (not awaited) so the open brace has a `0` count (at least when - // displayed with `llvm-cov show` in color-mode). - match x⦉@0,2,3 { - @17⦊y⦉@17 if @0,2,3⦊foo()⦉@0,2,3.await[@9,12,14,15,16⦊y⦉@9,12,14,15,16] => @17⦊()⦉@17, - _ => @1⦊()⦉@1, - } -}@19,20⦊⦉@19,20
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.h.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.h.-------.InstrumentCoverage.0.html deleted file mode 100644 index f2ea01281fe..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.h.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - -async.h - Coverage Spans - - - -
@0,1⦊async fn h(x: usize) ⦉@0,1{ // The function signature is counted when called, but the body is not - // executed (not awaited) so the open brace has a `0` count (at least when - // displayed with `llvm-cov show` in color-mode). - match x { - y if foo().await[y] => (), - _ => (), - } -}
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.i-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.i-{closure#0}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 1c63875a8be..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.i-{closure#0}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - -async.i-{closure#0} - Coverage Spans - - - -
@0,3,4⦊{ // line coverage is 1, but there are 2 regions: - // (a) the function signature, counted when the function is called; and - // (b) the open brace for the function body, counted once when the body is - // executed asynchronously. - match x⦉@0,3,4 { - @17,19⦊y⦉@17,19 if @0,3,4⦊c(x)⦉@0,3,4.await == @10,13,15,16⦊y + 1⦉@10,13,15,16 => { @17,19⦊d()⦉@17,19.await; } - @46⦊y⦉@46 if @1,32,33⦊f()⦉@1,32,33.await == @39,42,44,45⦊y + 1⦉@39,42,44,45 => @46⦊()⦉@46, - _ => @2⦊()⦉@2, - } -}@48,49⦊⦉@48,49
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.i.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.i.-------.InstrumentCoverage.0.html deleted file mode 100644 index e5dc6ecd4eb..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.i.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - -async.i - Coverage Spans - - - -
@0,1⦊async fn i(x: u8) ⦉@0,1{ // line coverage is 1, but there are 2 regions: - // (a) the function signature, counted when the function is called; and - // (b) the open brace for the function body, counted once when the body is - // executed asynchronously. - match x { - y if c(x).await == y + 1 => { d().await; } - y if f().await == y + 1 => (), - _ => (), - } -}
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j-c.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j-c.-------.InstrumentCoverage.0.html deleted file mode 100644 index e6384b7598f..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j-c.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,90 +0,0 @@ - - - - -async.j-c - Coverage Spans - - - -
@0⦊fn c(x: u8) -> u8 { - if x == 8⦉@0 { - @1⦊1⦉@1 // This line appears covered, but the 1-character expression span covering the `1` - // is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because - // `fn j()` executes the open brace for the funciton body, followed by the function's - // first executable statement, `match x`. Inner function declarations are not - // "visible" to the MIR for `j()`, so the code region counts all lines between the - // open brace and the first statement as executed, which is, in a sense, true. - // `llvm-cov show` overcomes this kind of situation by showing the actual counts - // of the enclosed coverages, (that is, the `1` expression was not executed, and - // accurately displays a `0`). - } else { - @2⦊0⦉@2 - } - }@3⦊⦉@3
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j-d.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j-d.-------.InstrumentCoverage.0.html deleted file mode 100644 index 4eed8ee60dd..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j-d.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - -async.j-d - Coverage Spans - - - -
@0⦊fn d() -> u8 { 1 }⦉@0
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j-f.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j-f.-------.InstrumentCoverage.0.html deleted file mode 100644 index 6e80c8c786e..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j-f.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - -async.j-f - Coverage Spans - - - -
@0⦊fn f() -> u8 { 1 }⦉@0
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j.-------.InstrumentCoverage.0.html deleted file mode 100644 index 2b43c7bd25d..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.j.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - -async.j - Coverage Spans - - - -
@0,3,4⦊fn j(x: u8) { - // non-async versions of `c()`, `d()`, and `f()` to make it similar to async `i()`. - fn c(x: u8) -> u8 { - if x == 8 { - 1 // This line appears covered, but the 1-character expression span covering the `1` - // is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because - // `fn j()` executes the open brace for the funciton body, followed by the function's - // first executable statement, `match x`. Inner function declarations are not - // "visible" to the MIR for `j()`, so the code region counts all lines between the - // open brace and the first statement as executed, which is, in a sense, true. - // `llvm-cov show` overcomes this kind of situation by showing the actual counts - // of the enclosed coverages, (that is, the `1` expression was not executed, and - // accurately displays a `0`). - } else { - 0 - } - } - fn d() -> u8 { 1 } - fn f() -> u8 { 1 } - match x⦉@0,3,4 { - @5,7⦊y⦉@5,7 if @0,3,4⦊c(x) == y + 1⦉@0,3,4 => @5,7⦊{ d(); }⦉@5,7 - @10⦊y⦉@10 if @1,8,9⦊f() == y + 1⦉@1,8,9 => @10⦊()⦉@10, - _ => @2⦊()⦉@2, - } -}@12⦊⦉@12
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.k.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.k.-------.InstrumentCoverage.0.html deleted file mode 100644 index 5792521bb2c..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.k.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,80 +0,0 @@ - - - - -async.k - Coverage Spans - - - -
@0⦊fn k(x: u8) { // unused function - match x⦉@0 { - 1 => @1,4⦊()⦉@1,4, - 2 => @2,5⦊()⦉@2,5, - _ => @3⦊()⦉@3, - } -}@6⦊⦉@6
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.l.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.l.-------.InstrumentCoverage.0.html deleted file mode 100644 index cd92b88c24c..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.l.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,80 +0,0 @@ - - - - -async.l - Coverage Spans - - - -
@0⦊fn l(x: u8) { - match x⦉@0 { - 1 => @1,4⦊()⦉@1,4, - 2 => @2,5⦊()⦉@2,5, - _ => @3⦊()⦉@3, - } -}@6⦊⦉@6
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m-{closure#0}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 5cec484a964..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m-{closure#0}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - -async.m-{closure#0} - Coverage Spans - - - -
@0⦊{ x - 1 }⦉@0
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m.-------.InstrumentCoverage.0.html deleted file mode 100644 index 04412c1d994..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.m.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - -async.m - Coverage Spans - - - -
@0,1⦊async fn m(x: u8) -> u8 ⦉@0,1{ x - 1 }
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index b892af0ed37..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,190 +0,0 @@ - - - - -async.main - Coverage Spans - - - -
@0,1,2,3,4,5,6,7,8,9,10,11,12,13⦊fn main() { - let _ = g(10); - let _ = h(9); - let mut future = Box::pin(i(8)); - j(7); - l(6); - let _ = m(5); - executor::block_on(future.as_mut()); -}⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 3998295a052..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - -closure.main-{closure#0} - Coverage Spans - - - -
|| - @0⦊{ - let mut countdown = 0; - if is_false⦉@0 @1⦊{ - countdown = 10; - }⦉@1@2⦊⦉@2 - @3,4⦊"alt string 2".to_owned() - }⦉@3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#10}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#10}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 3bdfe71b48c..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#10}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - -closure.main-{closure#10} - Coverage Spans - - - -
|| - @0⦊{ - let mut countdown = 0; - if is_false⦉@0 @1⦊{ - countdown = 10; - }⦉@1@2⦊⦉@2 - @3,4⦊"alt string 1".to_owned() - }⦉@3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#11}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#11}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 4b3f04b5a0c..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#11}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - -closure.main-{closure#11} - Coverage Spans - - - -
|| - @0⦊{ - let mut countdown = 0; - if is_false⦉@0 @1⦊{ - countdown = 10; - }⦉@1@2⦊⦉@2 - @3,4⦊"alt string 3".to_owned() - }⦉@3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 8ae494178f7..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - -closure.main-{closure#1} - Coverage Spans - - - -
|| - @0⦊{ - let mut countdown = 0; - if is_false⦉@0 @1⦊{ - countdown = 10; - }⦉@1@2⦊⦉@2 - @3,4⦊"alt string 4".to_owned() - }⦉@3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html deleted file mode 100644 index ad40ba57d69..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,128 +0,0 @@ - - - - -closure.main-{closure#2} - Coverage Spans - - - -
|val| - @0⦊{ - let mut countdown = 0; - if is_false⦉@0 @1⦊{ - countdown = 10; - }⦉@1@2⦊⦉@2 - @3,4,5,6,7⦊format!("'{}'", val) - }⦉@3,4,5,6,7
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 23101d76a8e..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - -closure.main-{closure#3} - Coverage Spans - - - -
| - mut countdown - | - @0⦊{ - if is_false⦉@0 @1⦊{ - countdown = 10; - }⦉@1@2⦊⦉@2 - @3,4⦊"closure should be unused".to_owned() - }⦉@3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#4}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#4}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 420135e143d..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#4}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - -closure.main-{closure#4} - Coverage Spans - - - -
| _unused_arg: u8 | @0⦊countdown += 1⦉@0
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#5}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#5}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 1c19aa8eeef..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#5}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - -closure.main-{closure#5} - Coverage Spans - - - -
@0,1,2⦊{ - $crate::io::_print($crate::format_args_nl!($($arg)*)); - }⦉@0,1,2
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#6}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#6}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 74c75c6c46c..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#6}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,87 +0,0 @@ - - - - -closure.main-{closure#6} - Coverage Spans - - - -
| _unused_arg: u8 | @0,1,2⦊{ println!("not called") }⦉@0,1,2
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#7}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#7}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 386fb1b9e6f..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#7}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - -closure.main-{closure#7} - Coverage Spans - - - -
| _unused_arg: u8 | @0,1,2⦊{ - println!("not called") - }⦉@0,1,2
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#8}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#8}.-------.InstrumentCoverage.0.html deleted file mode 100644 index f9da6ac9dfc..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#8}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - -closure.main-{closure#8} - Coverage Spans - - - -
| - _unused_arg: u8 - | @0,1,2⦊{ println!("not called") }⦉@0,1,2
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#9}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#9}.-------.InstrumentCoverage.0.html deleted file mode 100644 index e259fc9bb67..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#9}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - -closure.main-{closure#9} - Coverage Spans - - - -
| - _unused_arg: u8 - | @0,1,2⦊{ println!("not called") }⦉@0,1,2
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index a7d1728114e..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,10921 +0,0 @@ - - - - -closure.main - Coverage Spans - - - -
@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42⦊fn main() { - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let is_true = std::env::args().len() == 1; - let is_false = ! is_true; - - let mut some_string = Some(String::from("the string content")); - println!( - "The string or alt: {}" - , - some_string - . - unwrap_or_else - ( - ⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42|| - { - let mut countdown = 0; - if is_false { - countdown = 10; - } - "alt string 1".to_owned() - }@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42⦊ - ) - ); - - some_string = Some(String::from("the string content")); - let - a - = - ⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42|| - { - let mut countdown = 0; - if is_false { - countdown = 10; - } - "alt string 2".to_owned() - }@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42⦊; - println!( - "The string or alt: {}" - , - some_string - . - unwrap_or_else - ( - a - ) - ); - - some_string = None; - println!( - "The string or alt: {}" - , - some_string - . - unwrap_or_else - ( - ⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42|| - { - let mut countdown = 0; - if is_false { - countdown = 10; - } - "alt string 3".to_owned() - }@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42⦊ - ) - ); - - some_string = None; - let - a - = - ⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42|| - { - let mut countdown = 0; - if is_false { - countdown = 10; - } - "alt string 4".to_owned() - }@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42⦊; - println!( - "The string or alt: {}" - , - some_string - . - unwrap_or_else - ( - a - ) - ); - - let - quote_closure - = - ⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42|val| - { - let mut countdown = 0; - if is_false { - countdown = 10; - } - format!("'{}'", val) - }@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42⦊; - println!( - "Repeated, quoted string: {:?}" - , - std::iter::repeat("repeat me") - .take(5) - .map - ( - quote_closure - ) - .collect::<Vec<_>>() - ); - - let - _unused_closure - = - ⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42| - mut countdown - | - { - if is_false { - countdown = 10; - } - "closure should be unused".to_owned() - }@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42⦊; - - let mut countdown = 10; - let _short_unused_closure = ⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42| _unused_arg: u8 | countdown += 1@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42⦊; - - // Macros can sometimes confuse the coverage results. Compare this next assignment, with an - // unused closure that invokes the `println!()` macro, with the closure assignment above, that - // does not use a macro. The closure above correctly shows `0` executions. - let _short_unused_closure = ⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42| _unused_arg: u8 | println!("not called")@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42⦊; - // The closure assignment above is executed, with a line count of `1`, but the `println!()` - // could not have been called, and yet, there is no indication that it wasn't... - - // ...but adding block braces gives the expected result, showing the block was not executed. - let _short_unused_closure_block = ⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42| _unused_arg: u8 | { println!("not called") }@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42⦊; - - let _shortish_unused_closure = ⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42| _unused_arg: u8 | { - println!("not called") - }@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42⦊; - - let _as_short_unused_closure = ⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42| - _unused_arg: u8 - | { println!("not called") }@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42⦊; - - let _almost_as_short_unused_closure = ⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42| - _unused_arg: u8 - | { println!("not called") }@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42⦊ - ; -}⦉@0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.conditions/conditions.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.conditions/conditions.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 3d1b737ec2d..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.conditions/conditions.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,307 +0,0 @@ - - - - -conditions.main - Coverage Spans - - - -
@0⦊fn main() ⦉@0{ - let @0⦊mut countdown = 0; - if true⦉@0 @1⦊{ - countdown = 10; - }⦉@1@2⦊⦉@2 - - const B: u32 = 100; - let @19⦊x⦉@19 = if @3⦊countdown > 7⦉@3 { - @4,6⦊countdown -= 4; - B⦉@4,6 - } else if @5⦊countdown > 2⦉@5 { - if @7⦊countdown < 1⦉@7 || @13⦊countdown > 5⦉@13 || @10⦊countdown != 9⦉@10 @15⦊{ - countdown = 0; - }⦉@15@16⦊⦉@16 - @17,18⦊countdown -= 5; - countdown⦉@17,18 - } else { - @8⦊return⦉@8; - }; - - let @19⦊mut countdown = 0; - if true⦉@19 @20⦊{ - countdown = 10; - }⦉@20@21⦊⦉@21 - - if @22⦊countdown > 7⦉@22 @23,25⦊{ - countdown -= 4; - }⦉@23,25 else if @24⦊countdown > 2⦉@24 { - if @26⦊countdown < 1⦉@26 || @32⦊countdown > 5⦉@32 || @29⦊countdown != 9⦉@29 @34⦊{ - countdown = 0; - }⦉@34@35⦊⦉@35 - @36,37⦊countdown -= 5⦉@36,37; - } else { - @27⦊return⦉@27; - } - - if @38⦊true⦉@38 { - let @39⦊mut countdown = 0; - if true⦉@39 @41⦊{ - countdown = 10; - }⦉@41@42⦊⦉@42 - - if @43⦊countdown > 7⦉@43 @44,46⦊{ - countdown -= 4; - }⦉@44,46 - else if @45⦊countdown > 2⦉@45 { - if @47⦊countdown < 1⦉@47 || @53⦊countdown > 5⦉@53 || @50⦊countdown != 9⦉@50 @55⦊{ - countdown = 0; - }⦉@55@56⦊⦉@56 - @57,58⦊countdown -= 5⦉@57,58; - } else { - @48⦊return⦉@48; - } - }@40⦊⦉@40 // Note: closing brace shows uncovered (vs. `0` for implicit else) because condition literal - // `true` was const-evaluated. The compiler knows the `if` block will be executed. - - let @60⦊mut countdown = 0; - if true⦉@60 @61⦊{ - countdown = 1; - }⦉@61@62⦊⦉@62 - - let @81⦊z⦉@81 = if @63⦊countdown > 7⦉@63 @64,66⦊{ - countdown -= 4; - }⦉@64,66 else if @65⦊countdown > 2⦉@65 { - if @67⦊countdown < 1⦉@67 || @73⦊countdown > 5⦉@73 || @70⦊countdown != 9⦉@70 @75⦊{ - countdown = 0; - }⦉@75@76⦊⦉@76 - @77,78⦊countdown -= 5⦉@77,78; - } else { - let @68,79,80⦊should_be_reachable = countdown; - println!("reached"); - return⦉@68,79,80; - }; - - let @97⦊w⦉@97 = if @81⦊countdown > 7⦉@81 @82,84⦊{ - countdown -= 4; - }⦉@82,84 else if @83⦊countdown > 2⦉@83 { - if @85⦊countdown < 1⦉@85 || @91⦊countdown > 5⦉@91 || @88⦊countdown != 9⦉@88 @93⦊{ - countdown = 0; - }⦉@93@94⦊⦉@94 - @95,96⦊countdown -= 5⦉@95,96; - } else { - @86⦊return⦉@86; - }; -}@101⦊⦉@101
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.dead_code/dead_code.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.dead_code/dead_code.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index be06ddd126d..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.dead_code/dead_code.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - -dead_code.main - Coverage Spans - - - -
@0,1,2,3⦊fn main() { - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let is_true = std::env::args().len() == 1; - - let mut countdown = 0; - if is_true⦉@0,1,2,3 @4⦊{ - countdown = 10; - }⦉@4@5⦊⦉@5 -}@6⦊⦉@6
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.dead_code/dead_code.unused_fn.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.dead_code/dead_code.unused_fn.-------.InstrumentCoverage.0.html deleted file mode 100644 index 7f2d8d3c8ec..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.dead_code/dead_code.unused_fn.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - -dead_code.unused_fn - Coverage Spans - - - -
@0,1,2,3⦊fn unused_fn() { - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let is_true = std::env::args().len() == 1; - - let mut countdown = 0; - if is_true⦉@0,1,2,3 @4⦊{ - countdown = 10; - }⦉@4@5⦊⦉@5 -}@6⦊⦉@6
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.dead_code/dead_code.unused_pub_fn_not_in_library.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.dead_code/dead_code.unused_pub_fn_not_in_library.-------.InstrumentCoverage.0.html deleted file mode 100644 index be44f71348c..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.dead_code/dead_code.unused_pub_fn_not_in_library.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - -dead_code.unused_pub_fn_not_in_library - Coverage Spans - - - -
@0,1,2,3⦊pub fn unused_pub_fn_not_in_library() { - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let is_true = std::env::args().len() == 1; - - let mut countdown = 0; - if is_true⦉@0,1,2,3 @4⦊{ - countdown = 10; - }⦉@4@5⦊⦉@5 -}@6⦊⦉@6
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 95813decf9f..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - -doctest.main - Coverage Spans - - - -
@0⦊fn main() ⦉@0{ - if @0⦊true⦉@0 { - @4⦊@3⦊assert_eq!(1, 1);⦉@3⦉@4 - } else { - @6⦊@5⦊assert_eq!(1, 2);⦉@5⦉@6 - } -}@7⦊⦉@7
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html deleted file mode 100644 index 3a41d3482b0..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,113 +0,0 @@ - - - - -doctest_crate.fn_run_in_doctests - Coverage Spans - - - -
@0⦊pub fn fn_run_in_doctests(conditional: usize) ⦉@0{ - match @0⦊conditional⦉@0 { - 1 => @7⦊@6⦊assert_eq!(1, 1)⦉@6⦉@7, // this is run, - 2 => @10⦊@9⦊assert_eq!(1, 1)⦉@9⦉@10, // this, - 3 => @13⦊@12⦊assert_eq!(1, 1)⦉@12⦉@13, // and this too - _ => @15⦊@14⦊assert_eq!(1, 2)⦉@14⦉@15, // however this is not - } -}@16⦊⦉@16
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 66a6e776a06..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,152 +0,0 @@ - - - - -drop_trait.main - Coverage Spans - - - -
@0⦊fn main() -> Result<(),u8> { - let _firecracker = Firework { strength: 1 }; - - let _tnt = Firework { strength: 100 }; - - if true⦉@0 { - @1,3,4,8,9⦊println!("Exiting with error..."); - return Err(1)⦉@1,3,4,8,9; - }@2,5,6,7⦊ - - let _ = Firework { strength: 1000 }; - - Ok(())⦉@2,5,6,7 -}@10⦊⦉@10
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.drop_trait/drop_trait.{impl#0}-drop.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.drop_trait/drop_trait.{impl#0}-drop.-------.InstrumentCoverage.0.html deleted file mode 100644 index 57d56c5cf73..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.drop_trait/drop_trait.{impl#0}-drop.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - -drop_trait.{impl#0}-drop - Coverage Spans - - - -
@0,1,2,3⦊fn drop(&mut self) { - println!("BOOM times {}!!!", self.strength); - }⦉@0,1,2,3
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 098c1404251..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,237 +0,0 @@ - - - - -generics.main - Coverage Spans - - - -
@0,1,2,3⦊fn main() -> Result<(),u8> { - let mut firecracker = Firework { strength: 1 }; - firecracker.set_strength(2); - - let mut tnt = Firework { strength: 100.1 }; - tnt.set_strength(200.1); - tnt.set_strength(300.3); - - if true⦉@0,1,2,3 { - @4,6,7,11,12⦊println!("Exiting with error..."); - return Err(1)⦉@4,6,7,11,12; - }@5,8,9,10⦊ // The remaining lines below have no coverage because `if true` (with the constant literal - // `true`) is guaranteed to execute the `then` block, which is also guaranteed to `return`. - // Thankfully, in the normal case, conditions are not guaranteed ahead of time, and as shown - // in other tests, the lines below would have coverage (which would show they had `0` - // executions, assuming the condition still evaluated to `true`). - - let _ = Firework { strength: 1000 }; - - Ok(())⦉@5,8,9,10 -}@13⦊⦉@13
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.generics/generics.{impl#0}-set_strength.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.generics/generics.{impl#0}-set_strength.-------.InstrumentCoverage.0.html deleted file mode 100644 index 329641d47bd..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.generics/generics.{impl#0}-set_strength.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,85 +0,0 @@ - - - - -generics.{impl#0}-set_strength - Coverage Spans - - - -
@0⦊fn set_strength(&mut self, new_strength: T) { - self.strength = new_strength; - }⦉@0
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.generics/generics.{impl#1}-drop.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.generics/generics.{impl#1}-drop.-------.InstrumentCoverage.0.html deleted file mode 100644 index 4908bc7b4a7..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.generics/generics.{impl#1}-drop.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - -generics.{impl#1}-drop - Coverage Spans - - - -
@0,1,2,3⦊fn drop(&mut self) { - println!("BOOM times {}!!!", self.strength); - }⦉@0,1,2,3
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index d6eccf57846..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,238 +0,0 @@ - - - - -if.main - Coverage Spans - - - -
@0,1,2,3⦊fn main() { - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let - is_true - = - std::env::args().len() - == - 1 - ; - let - mut - countdown - = - 0 - ; - if - is_true⦉@0,1,2,3 - @4⦊{ - countdown - = - 10 - ; - }⦉@4@5⦊⦉@5 -}@6⦊⦉@6
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index e0f0ac40205..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,195 +0,0 @@ - - - - -if_else.main - Coverage Spans - - - -
@0,1,2,3⦊fn main() { - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let is_true = std::env::args().len() == 1; - - let mut countdown = 0; - if - is_true⦉@0,1,2,3 - @4⦊{ - countdown - = - 10 - ; - }⦉@4 - else // Note coverage region difference without semicolon - { - @5⦊countdown - = - 100⦉@5 - } - - if - @6⦊is_true⦉@6 - @7⦊{ - countdown - = - 10 - ; - }⦉@7 - else - @8⦊{ - countdown - = - 100 - ; - }⦉@8 -}@9⦊⦉@9
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.display.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.display.-------.InstrumentCoverage.0.html deleted file mode 100644 index 6287516636e..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.display.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - -inline.display - Coverage Spans - - - -
@0,1⦊fn display<T: Display>(xs: &[T]) ⦉@0,1{ - for @6,8,9,10,11⦊x⦉@6,8,9,10,11 in @6,8,9,10,11⦊xs { - print!("{}", x); - }⦉@6,8,9,10,11 - @5,12,13⦊println!(); -}⦉@5,12,13
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.error.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.error.-------.InstrumentCoverage.0.html deleted file mode 100644 index bbf19c3e446..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.error.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - -inline.error - Coverage Spans - - - -
@0,1⦊fn error() { - panic!("error"); -}⦉@0,1
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.length.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.length.-------.InstrumentCoverage.0.html deleted file mode 100644 index 8e8efb6d9f6..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.length.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - -inline.length - Coverage Spans - - - -
@0,1⦊fn length<T>(xs: &[T]) -> usize { - xs.len() -}⦉@0,1
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 4ec2e9beede..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,94 +0,0 @@ - - - - -inline.main - Coverage Spans - - - -
@0,1⦊fn main() { - permutations(&['a', 'b', 'c']); -}⦉@0,1
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutate.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutate.-------.InstrumentCoverage.0.html deleted file mode 100644 index fd72973ccd0..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutate.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,183 +0,0 @@ - - - - -inline.permutate - Coverage Spans - - - -
@0,1⦊fn permutate<T: Copy + Display>(xs: &mut [T], k: usize) { - let n = length(xs); - if k == n⦉@0,1 @2,4⦊{ - display(xs); - }⦉@2,4 else if @3⦊k < n⦉@3 { - for @12,14,15,16,17,18⦊i⦉@12,14,15,16,17,18 in @5,7⦊k..n⦉@5,7 @12,14,15,16,17,18⦊{ - swap(xs, i, k); - permutate(xs, k + 1); - swap(xs, i, k); - }⦉@12,14,15,16,17,18 - } else @6,19⦊{ - error(); - }⦉@6,19 -}@21⦊⦉@21
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutations.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutations.-------.InstrumentCoverage.0.html deleted file mode 100644 index 4bfd22f3cd9..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutations.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,113 +0,0 @@ - - - - -inline.permutations - Coverage Spans - - - -
@0,1,2,3,4⦊fn permutations<T: Copy + Display>(xs: &[T]) { - let mut ys = xs.to_owned(); - permutate(&mut ys, 0); -}⦉@0,1,2,3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.swap.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.swap.-------.InstrumentCoverage.0.html deleted file mode 100644 index 4c3f63093d3..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.swap.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,173 +0,0 @@ - - - - -inline.swap - Coverage Spans - - - -
@0,1,2,3,4⦊fn swap<T: Copy>(xs: &mut [T], i: usize, j: usize) { - let t = xs[i]; - xs[i] = xs[j]; - xs[j] = t; -}⦉@0,1,2,3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main-InTrait-default_trait_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main-InTrait-default_trait_func.-------.InstrumentCoverage.0.html deleted file mode 100644 index 1dc5bb64e0b..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main-InTrait-default_trait_func.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - -inner_items.main-InTrait-default_trait_func - Coverage Spans - - - -
@0,1,2⦊fn default_trait_func(&mut self) { - in_func(IN_CONST); - self.trait_func(IN_CONST); - }⦉@0,1,2
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html deleted file mode 100644 index 82724e5e865..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - -inner_items.main-in_func - Coverage Spans - - - -
@0,1,2,3,4⦊fn in_func(a: u32) { - let b = 1; - let c = a + b; - println!("c = {}", c) - }⦉@0,1,2,3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main-{impl#0}-trait_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main-{impl#0}-trait_func.-------.InstrumentCoverage.0.html deleted file mode 100644 index b00a781a0a7..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main-{impl#0}-trait_func.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - -inner_items.main-{impl#0}-trait_func - Coverage Spans - - - -
@0,1,2⦊fn trait_func(&mut self, incr: u32) { - self.in_struct_field += incr; - in_func(self.in_struct_field); - }⦉@0,1,2
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 4a1003dfbed..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - -inner_items.main - Coverage Spans - - - -
@0,1,2,3⦊fn main() ⦉@0,1,2,3{ - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let @0,1,2,3⦊is_true = std::env::args().len() == 1; - - let mut countdown = 0; - if is_true⦉@0,1,2,3 @4⦊{ - countdown = 10; - }⦉@4@5⦊⦉@5 - - mod in_mod { - const IN_MOD_CONST: u32 = 1000; - } - - fn in_func(a: u32) { - let b = 1; - let c = a + b; - println!("c = {}", c) - } - - struct InStruct { - in_struct_field: u32, - } - - const IN_CONST: u32 = 1234; - - trait InTrait { - fn trait_func(&mut self, incr: u32); - - fn default_trait_func(&mut self) { - in_func(IN_CONST); - self.trait_func(IN_CONST); - } - } - - impl InTrait for InStruct { - fn trait_func(&mut self, incr: u32) { - self.in_struct_field += incr; - in_func(self.in_struct_field); - } - } - - type InType = String; - - if @6⦊is_true⦉@6 @7,9⦊{ - in_func(countdown); - }⦉@7,9@8⦊⦉@8 - - let @10,11⦊mut val = InStruct { - in_struct_field: 101, - }; - - val.default_trait_func(); -}⦉@10,11
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index a6f8d500065..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - -lazy_boolean.main - Coverage Spans - - - -
@0,1,2,3⦊fn main() { - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let is_true = std::env::args().len() == 1; - - let (mut a, mut b, mut c) = (0, 0, 0); - if is_true⦉@0,1,2,3 @4⦊{ - a = 1; - b = 10; - c = 100; - }⦉@4@5⦊⦉@5 - let - @9⦊somebool⦉@9 - = - @6⦊a < b⦉@6 - || - @8⦊b < c⦉@8 - ; - let - @12⦊somebool⦉@12 - = - @9⦊b < a⦉@9 - || - @11⦊b < c⦉@11 - ; - let @15⦊somebool⦉@15 = @12⦊a < b⦉@12 && @14⦊b < c⦉@14; - let @18⦊somebool⦉@18 = @15⦊b < a⦉@15 && @17⦊b < c⦉@17; - - if - @18⦊! - is_true⦉@18 - @19⦊{ - a = 2 - ; - }⦉@19@20⦊⦉@20 - - if - @21⦊is_true⦉@21 - @22⦊{ - b = 30 - ; - }⦉@22 - else - @23⦊{ - c = 400 - ; - }⦉@23 - - if @24⦊!is_true⦉@24 @25⦊{ - a = 2; - }⦉@25@26⦊⦉@26 - - if @27⦊is_true⦉@27 @28⦊{ - b = 30; - }⦉@28 else @29⦊{ - c = 400; - }⦉@29 -}@30⦊⦉@30
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.loop_break_value/loop_break_value.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.loop_break_value/loop_break_value.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 076d036c2af..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.loop_break_value/loop_break_value.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,128 +0,0 @@ - - - - -loop_break_value.main - Coverage Spans - - - -
@0,1⦊fn main() { - let result - = - loop - { - break - 10 - ; - } - ; -}⦉@0,1
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.loops_branches/loops_branches.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.loops_branches/loops_branches.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 95e8f0b71ea..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.loops_branches/loops_branches.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - -loops_branches.main - Coverage Spans - - - -
@0,1,2,3⦊fn main() { - let debug_test = DebugTest; - println!("{:?}", debug_test); -}⦉@0,1,2,3
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.loops_branches/loops_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.loops_branches/loops_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html deleted file mode 100644 index f6f08b6a770..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.loops_branches/loops_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,100 +0,0 @@ - - - - -loops_branches.{impl#0}-fmt - Coverage Spans - - - -
@0⦊fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - if true⦉@0 { - if @1⦊false⦉@1 { - while @4,5⦊true⦉@4,5 @6,8⦊{ - }⦉@6,8 - }@3⦊⦉@3 - @9,10,11,12⦊write!(f, "error")⦉@9,10,11,12@14,16,17,18⦊?⦉@14,16,17,18; - } else @2⦊{ - }⦉@2 - @19⦊Ok(())⦉@19 - }@20⦊⦉@20
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.match_or_pattern/match_or_pattern.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.match_or_pattern/match_or_pattern.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 013c292ce9a..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.match_or_pattern/match_or_pattern.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - -match_or_pattern.main - Coverage Spans - - - -
@0,1,2,3⦊fn main() { - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let is_true = std::env::args().len() == 1; - - let mut a: u8 = 0; - let mut b: u8 = 0; - if is_true⦉@0,1,2,3 @4⦊{ - a = 2; - b = 0; - }⦉@4@5⦊⦉@5 - match @6⦊(a, b)⦉@6 { - // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`. - // This test confirms a fix for Issue #79569. - (0 | 1, 2 | 3) => @9,10⦊{}⦉@9,10 - _ => @7⦊{}⦉@7 - } - if @11⦊is_true⦉@11 @12⦊{ - a = 0; - b = 0; - }⦉@12@13⦊⦉@13 - match @14⦊(a, b)⦉@14 { - (0 | 1, 2 | 3) => @17,18⦊{}⦉@17,18 - _ => @15⦊{}⦉@15 - } - if @19⦊is_true⦉@19 @20⦊{ - a = 2; - b = 2; - }⦉@20@21⦊⦉@21 - match @22⦊(a, b)⦉@22 { - (0 | 1, 2 | 3) => @25,26⦊{}⦉@25,26 - _ => @23⦊{}⦉@23 - } - if @27⦊is_true⦉@27 @28⦊{ - a = 0; - b = 2; - }⦉@28@29⦊⦉@29 - match @30⦊(a, b)⦉@30 { - (0 | 1, 2 | 3) => @33,34⦊{}⦉@33,34 - _ => @31⦊{}⦉@31 - } -}@35⦊⦉@35
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 1abc24156d9..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - -nested_loops.main - Coverage Spans - - - -
@0,1,2,3⦊fn main() { - let is_true = std::env::args().len() == 1; - let mut countdown = 10⦉@0,1,2,3; - - 'outer: while @4,5⦊countdown > 0⦉@4,5 { - let @6,8,9⦊mut a = 100; - let mut b = 100⦉@6,8,9; - for @14,16⦊_⦉@14,16 in @10,11,12⦊0..50⦉@10,11,12 { - if @14,16⦊a < 30⦉@14,16 { - @17⦊break⦉@17; - }@18,19,20⦊ - a -= 5; - b -= 5; - if b < 90⦉@18,19,20 { - @21,23⦊a -= 10; - if is_true⦉@21,23 { - @24⦊break 'outer⦉@24; - } else @25,26⦊{ - a -= 2; - }⦉@25,26 - }@22⦊⦉@22 - } - @28,29⦊countdown -= 1⦉@28,29; - } -}@30⦊⦉@30
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.overflow/overflow.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.overflow/overflow.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 2a9b1b10efc..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.overflow/overflow.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - -overflow.main - Coverage Spans - - - -
@0⦊fn main() -> Result<(),u8> { - let mut countdown = 10⦉@0; - while @1,2⦊countdown > 0⦉@1,2 { - if @3,5⦊countdown == 1⦉@3,5 @6,8,9,10,11⦊{ - let result = might_overflow(10); - println!("Result: {}", result); - }⦉@6,8,9,10,11 else if @7⦊countdown < 5⦉@7 @12,14,15,16,17⦊{ - let result = might_overflow(1); - println!("Result: {}", result); - }⦉@12,14,15,16,17@13⦊⦉@13 - @19,20⦊countdown -= 1⦉@19,20; - } - @4⦊Ok(()) -}⦉@4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.overflow/overflow.might_overflow.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.overflow/overflow.might_overflow.-------.InstrumentCoverage.0.html deleted file mode 100644 index c6043f0bd07..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.overflow/overflow.might_overflow.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,394 +0,0 @@ - - - - -overflow.might_overflow - Coverage Spans - - - -
@0⦊fn might_overflow(to_add: u32) -> u32 { - if to_add > 5⦉@0 @1,3,4⦊{ - println!("this will probably overflow"); - }⦉@1,3,4@2⦊⦉@2 - let @5,6,7,8,9,10,11,12,13⦊add_to = u32::MAX - 5; - println!("does {} + {} overflow?", add_to, to_add); - let result = to_add + add_to; - println!("continuing after overflow check"); - result -}⦉@5,6,7,8,9,10,11,12,13
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.panic_unwind/panic_unwind.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.panic_unwind/panic_unwind.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 5b097f118e3..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.panic_unwind/panic_unwind.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - -panic_unwind.main - Coverage Spans - - - -
@0⦊fn main() -> Result<(), u8> { - let mut countdown = 10⦉@0; - while @1,2⦊countdown > 0⦉@1,2 { - if @3,5⦊countdown == 1⦉@3,5 @6,8⦊{ - might_panic(true); - }⦉@6,8 else if @7⦊countdown < 5⦉@7 @9,11⦊{ - might_panic(false); - }⦉@9,11@10⦊⦉@10 - @13,14⦊countdown -= 1⦉@13,14; - } - @4⦊Ok(()) -}⦉@4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.panic_unwind/panic_unwind.might_panic.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.panic_unwind/panic_unwind.might_panic.-------.InstrumentCoverage.0.html deleted file mode 100644 index 32988629ba0..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.panic_unwind/panic_unwind.might_panic.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,163 +0,0 @@ - - - - -panic_unwind.might_panic - Coverage Spans - - - -
@0⦊fn might_panic(should_panic: bool) ⦉@0{ - if @0⦊should_panic⦉@0 { - @1,3,4⦊println!("panicking..."); - panic!("panics");⦉@1,3,4 - } else @2,5,6⦊{ - println!("Don't Panic"); - } -}⦉@2,5,6
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 3e307c4f460..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - -partial_eq.main - Coverage Spans - - - -
@0,1,2,3,4,5,6,7,8⦊fn main() { - let version_3_2_1 = Version::new(3, 2, 1); - let version_3_3_0 = Version::new(3, 3, 0); - - println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0); -}⦉@0,1,2,3,4,5,6,7,8
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#0}-new.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#0}-new.-------.InstrumentCoverage.0.html deleted file mode 100644 index 820ccf74d1b..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#0}-new.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - -partial_eq.{impl#0}-new - Coverage Spans - - - -
@0⦊pub fn new(major: usize, minor: usize, patch: usize) -> Self { - Self { - major, - minor, - patch, - } - }⦉@0
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#1}-cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#1}-cmp.-------.InstrumentCoverage.0.html deleted file mode 100644 index ee4c10afd8b..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#1}-cmp.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - -partial_eq.{impl#1}-cmp - Coverage Spans - - - -
@0,1⦊⦉@0,1Ord@15⦊⦉@15
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html deleted file mode 100644 index 2f5092bd51f..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - -partial_eq.{impl#2}-partial_cmp - Coverage Spans - - - -
@0,1⦊⦉@0,1PartialOrd@18⦊⦉@18
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html deleted file mode 100644 index ebb8b1c15ce..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - -partial_eq.{impl#4}-assert_receiver_is_total_eq - Coverage Spans - - - -
@0⦊⦉@0Eq
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-eq.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-eq.-------.InstrumentCoverage.0.html deleted file mode 100644 index 9858b270d7e..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-eq.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - -partial_eq.{impl#6}-eq - Coverage Spans - - - -
@0⦊⦉@0PartialEq@3⦊⦉@3
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-ne.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-ne.-------.InstrumentCoverage.0.html deleted file mode 100644 index bf94e5cbf73..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#6}-ne.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - -partial_eq.{impl#6}-ne - Coverage Spans - - - -
@0⦊⦉@0PartialEq@3⦊⦉@3
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#7}-fmt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#7}-fmt.-------.InstrumentCoverage.0.html deleted file mode 100644 index 930492f2484..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#7}-fmt.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - -partial_eq.{impl#7}-fmt - Coverage Spans - - - -
@0,1,2,3,4,5⦊Debug⦉@0,1,2,3,4,5
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#8}-clone.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#8}-clone.-------.InstrumentCoverage.0.html deleted file mode 100644 index f1c98393343..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#8}-clone.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - -partial_eq.{impl#8}-clone - Coverage Spans - - - -
@0,1,2,3⦊Clone⦉@0,1,2,3
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 6b911eea341..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - -simple_loop.main - Coverage Spans - - - -
@0,1,2,3⦊fn main() { - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let is_true = std::env::args().len() == 1; - - let mut countdown = 0; - - if - is_true⦉@0,1,2,3 - @4⦊{ - countdown - = - 10 - ; - }⦉@4@5⦊⦉@5 - - loop - { - if - @7,8⦊countdown - == - 0⦉@7,8 - { - @9⦊break⦉@9 - ; - }@10,11⦊ - countdown - -= - 1⦉@10,11 - ; - } -}@9⦊⦉@9
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index a56692d9c2a..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,222 +0,0 @@ - - - - -simple_match.main - Coverage Spans - - - -
@0,1,2,3⦊fn main() { - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let is_true = std::env::args().len() == 1; - - let mut countdown = 1; - if is_true⦉@0,1,2,3 @4⦊{ - countdown = 0; - }⦉@4@5⦊⦉@5 - - for - @12,14,16⦊_⦉@12,14,16 - in - @8,9,10⦊0..2⦉@8,9,10 - { - let z - ; - match - @12,14,16⦊countdown⦉@12,14,16 - { - @17⦊x⦉@17 - if - @12,14,16⦊x - < - 1⦉@12,14,16 - => - @17⦊{ - z = countdown - ; - let y = countdown - ; - countdown = 10 - ; - }⦉@17 - _ - => - @15⦊{}⦉@15 - } - } -}@11⦊⦉@11
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.tight_inf_loop/tight_inf_loop.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.tight_inf_loop/tight_inf_loop.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 8cbd265c6a0..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.tight_inf_loop/tight_inf_loop.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - -tight_inf_loop.main - Coverage Spans - - - -
@0⦊fn main() { - if false⦉@0 { - @3,4⦊loop {}⦉@3,4 - }@2⦊ -}⦉@2
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html deleted file mode 100644 index a8a3139334c..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - -try_error_result.call - Coverage Spans - - - -
@0⦊fn call(return_error: bool) -> Result<(),()> { - if return_error⦉@0 { - @1⦊Err(())⦉@1 - } else { - @2⦊Ok(())⦉@2 - } -}@3⦊⦉@3
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 5b0c5cb072f..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,129 +0,0 @@ - - - - -try_error_result.main - Coverage Spans - - - -
@0,1⦊fn main() -> Result<(),()> { - let mut - countdown = 10⦉@0,1 - ; - for - @6,8,9⦊_⦉@6,8,9 - in - @2,3,4⦊0..10⦉@2,3,4 - { - @6,8,9⦊countdown - -= 1 - ; - if - countdown < 5⦉@6,8,9 - { - @10,12,13⦊call(/*return_error=*/ true)⦉@10,12,13@15,17,18,19⦊?⦉@15,17,18,19; - @14,20,21⦊call(/*return_error=*/ false)⦉@14,20,21@23,25,26,27⦊?⦉@23,25,26,27; - } - else - { - @11,28,29⦊call(/*return_error=*/ false)⦉@11,28,29@31,33,34,35⦊?⦉@31,33,34,35; - } - } - @5⦊Ok(())⦉@5 -}@38⦊⦉@38
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.foo.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.foo.-------.InstrumentCoverage.0.html deleted file mode 100644 index ef431a356c2..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.foo.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,87 +0,0 @@ - - - - -unused.foo - Coverage Spans - - - -
@0⦊fn foo<T>(x: T) { - let mut i = 0⦉@0; - while @1,2⦊i < 10⦉@1,2 { - @3,5⦊i != 0⦉@3,5 || @7⦊i != 0⦉@7; - @8,9⦊i += 1⦉@8,9; - } -}@4,10⦊⦉@4,10
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 864f6c4feb1..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - -unused.main - Coverage Spans - - - -
@0,1,2⦊fn main() -> Result<(), u8> { - foo::<u32>(0); - foo::<f32>(0.0); - Ok(()) -}⦉@0,1,2
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func.-------.InstrumentCoverage.0.html deleted file mode 100644 index 52beea08023..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - -unused.unused_func - Coverage Spans - - - -
@0⦊fn unused_func(mut a: u32) { - if a != 0⦉@0 @1,3⦊{ - a += 1; - }⦉@1,3@2⦊⦉@2 -}@4⦊⦉@4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func2.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func2.-------.InstrumentCoverage.0.html deleted file mode 100644 index 816ef73ea6b..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func2.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - -unused.unused_func2 - Coverage Spans - - - -
@0⦊fn unused_func2(mut a: u32) { - if a != 0⦉@0 @1,3⦊{ - a += 1; - }⦉@1,3@2⦊⦉@2 -}@4⦊⦉@4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func3.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func3.-------.InstrumentCoverage.0.html deleted file mode 100644 index 739f9f42db3..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_func3.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - -unused.unused_func3 - Coverage Spans - - - -
@0⦊fn unused_func3(mut a: u32) { - if a != 0⦉@0 @1,3⦊{ - a += 1; - }⦉@1,3@2⦊⦉@2 -}@4⦊⦉@4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_template_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_template_func.-------.InstrumentCoverage.0.html deleted file mode 100644 index be4f5efc5db..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.unused/unused.unused_template_func.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,87 +0,0 @@ - - - - -unused.unused_template_func - Coverage Spans - - - -
@0⦊fn unused_template_func<T>(x: T) { - let mut i = 0⦉@0; - while @1,2⦊i < 10⦉@1,2 { - @3,5⦊i != 0⦉@3,5 || @7⦊i != 0⦉@7; - @8,9⦊i += 1⦉@8,9; - } -}@4,10⦊⦉@4,10
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.unused_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.unused_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index 65e21ecef13..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.unused_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - -used_crate.unused_function - Coverage Spans - - - -
@0,1,2,3⦊pub fn unused_function() { - let is_true = std::env::args().len() == 1; - let mut countdown = 2; - if !is_true⦉@0,1,2,3 @4⦊{ - countdown = 20; - }⦉@4@5⦊⦉@5 -}@6⦊⦉@6
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.unused_generic_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.unused_generic_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index 02154a2268b..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.unused_generic_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - -used_crate.unused_generic_function - Coverage Spans - - - -
@0,1,2,3,4⦊pub fn unused_generic_function<T: Debug>(arg: T) { - println!("unused_generic_function with {:?}", arg); -}⦉@0,1,2,3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.unused_private_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.unused_private_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index 78228594e37..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.unused_private_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - -used_crate.unused_private_function - Coverage Spans - - - -
@0,1,2,3⦊fn unused_private_function() { - let is_true = std::env::args().len() == 1; - let mut countdown = 2; - if !is_true⦉@0,1,2,3 @4⦊{ - countdown = 20; - }⦉@4@5⦊⦉@5 -}@6⦊⦉@6
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.use_this_lib_crate.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.use_this_lib_crate.-------.InstrumentCoverage.0.html deleted file mode 100644 index 8f618d2e249..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.use_this_lib_crate.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,190 +0,0 @@ - - - - -used_crate.use_this_lib_crate - Coverage Spans - - - -
@0,1,2,3,4,5,6,7,8⦊fn use_this_lib_crate() { - used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs"); - used_with_same_type_from_bin_crate_and_lib_crate_generic_function( - "used from library used_crate.rs", - ); - let some_vec = vec![5, 6, 7, 8]; - used_only_from_this_lib_crate_generic_function(some_vec); - used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs"); -}⦉@0,1,2,3,4,5,6,7,8
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index 61a709c4729..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - -used_crate.used_from_bin_crate_and_lib_crate_generic_function - Coverage Spans - - - -
@0,1,2,3,4⦊pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { - println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); -}⦉@0,1,2,3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index 974a24b2c6d..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - -used_crate.used_function - Coverage Spans - - - -
@0,1,2,3⦊pub fn used_function() ⦉@0,1,2,3{ - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let @0,1,2,3⦊is_true = std::env::args().len() == 1; - let mut countdown = 0; - if is_true⦉@0,1,2,3 @4⦊{ - countdown = 10; - }⦉@4@5⦊⦉@5 - @6,7⦊use_this_lib_crate(); -}⦉@6,7
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_only_from_bin_crate_generic_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_only_from_bin_crate_generic_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index 68035339fe4..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_only_from_bin_crate_generic_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - -used_crate.used_only_from_bin_crate_generic_function - Coverage Spans - - - -
@0,1,2,3,4⦊pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) { - println!("used_only_from_bin_crate_generic_function with {:?}", arg); -}⦉@0,1,2,3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_only_from_this_lib_crate_generic_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_only_from_this_lib_crate_generic_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index 63944eb9ab3..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_only_from_this_lib_crate_generic_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - -used_crate.used_only_from_this_lib_crate_generic_function - Coverage Spans - - - -
@0,1,2,3,4⦊pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) { - println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); -}⦉@0,1,2,3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_with_same_type_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_with_same_type_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index b146180fbd1..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.used_with_same_type_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - -used_crate.used_with_same_type_from_bin_crate_and_lib_crate_generic_function - Coverage Spans - - - -
@0,1,2,3,4⦊pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { - println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); -}⦉@0,1,2,3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index 322eaf07677..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - -used_inline_crate.unused_function - Coverage Spans - - - -
@0,1,2,3⦊pub fn unused_function() { - let is_true = std::env::args().len() == 1; - let mut countdown = 2; - if !is_true⦉@0,1,2,3 @4⦊{ - countdown = 20; - }⦉@4@5⦊⦉@5 -}@6⦊⦉@6
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_generic_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_generic_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index 9e3052ccac1..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_generic_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - -used_inline_crate.unused_generic_function - Coverage Spans - - - -
@0,1,2,3,4⦊pub fn unused_generic_function<T: Debug>(arg: T) { - println!("unused_generic_function with {:?}", arg); -}⦉@0,1,2,3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_private_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_private_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index e9c381db940..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.unused_private_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - -used_inline_crate.unused_private_function - Coverage Spans - - - -
@0,1,2,3⦊fn unused_private_function() { - let is_true = std::env::args().len() == 1; - let mut countdown = 2; - if !is_true⦉@0,1,2,3 @4⦊{ - countdown = 20; - }⦉@4@5⦊⦉@5 -}@6⦊⦉@6
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.use_this_lib_crate.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.use_this_lib_crate.-------.InstrumentCoverage.0.html deleted file mode 100644 index 056f618a403..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.use_this_lib_crate.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,190 +0,0 @@ - - - - -used_inline_crate.use_this_lib_crate - Coverage Spans - - - -
@0,1,2,3,4,5,6,7,8⦊fn use_this_lib_crate() { - used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs"); - used_with_same_type_from_bin_crate_and_lib_crate_generic_function( - "used from library used_crate.rs", - ); - let some_vec = vec![5, 6, 7, 8]; - used_only_from_this_lib_crate_generic_function(some_vec); - used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs"); -}⦉@0,1,2,3,4,5,6,7,8
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index 0d88b0bc60e..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - -used_inline_crate.used_from_bin_crate_and_lib_crate_generic_function - Coverage Spans - - - -
@0,1,2,3,4⦊pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { - println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); -}⦉@0,1,2,3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index d722d9f46ec..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - -used_inline_crate.used_function - Coverage Spans - - - -
@0,1,2,3⦊pub fn used_function() ⦉@0,1,2,3{ - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let @0,1,2,3⦊is_true = std::env::args().len() == 1; - let mut countdown = 0; - if is_true⦉@0,1,2,3 @4⦊{ - countdown = 10; - }⦉@4@5⦊⦉@5 - @6,7⦊use_this_lib_crate(); -}⦉@6,7
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_inline_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_inline_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index a15c31bb13f..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_inline_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - -used_inline_crate.used_inline_function - Coverage Spans - - - -
@0,1,2,3⦊pub fn used_inline_function() ⦉@0,1,2,3{ - // Initialize test constants in a way that cannot be determined at compile time, to ensure - // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from - // dependent conditions. - let @0,1,2,3⦊is_true = std::env::args().len() == 1; - let mut countdown = 0; - if is_true⦉@0,1,2,3 @4⦊{ - countdown = 10; - }⦉@4@5⦊⦉@5 - @6,7⦊use_this_lib_crate(); -}⦉@6,7
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_only_from_bin_crate_generic_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_only_from_bin_crate_generic_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index 252ff76d416..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_only_from_bin_crate_generic_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - -used_inline_crate.used_only_from_bin_crate_generic_function - Coverage Spans - - - -
@0,1,2,3,4⦊pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) { - println!("used_only_from_bin_crate_generic_function with {:?}", arg); -}⦉@0,1,2,3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_only_from_this_lib_crate_generic_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_only_from_this_lib_crate_generic_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index f8fb4990ad9..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_only_from_this_lib_crate_generic_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - -used_inline_crate.used_only_from_this_lib_crate_generic_function - Coverage Spans - - - -
@0,1,2,3,4⦊pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) { - println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); -}⦉@0,1,2,3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_with_same_type_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_with_same_type_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html deleted file mode 100644 index db5e24d9b1d..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_inline_crate/used_inline_crate.used_with_same_type_from_bin_crate_and_lib_crate_generic_function.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - -used_inline_crate.used_with_same_type_from_bin_crate_and_lib_crate_generic_function - Coverage Spans - - - -
@0,1,2,3,4⦊pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { - println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); -}⦉@0,1,2,3,4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 28cf051ecf8..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - -uses_crate.main - Coverage Spans - - - -
@0,1,2,3,4,5,6,7,8,9⦊fn main() { - used_crate::used_function(); - let some_vec = vec![1, 2, 3, 4]; - used_crate::used_only_from_bin_crate_generic_function(&some_vec); - used_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs"); - used_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec); - used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function("interesting?"); -}⦉@0,1,2,3,4,5,6,7,8,9
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_inline_crate/uses_inline_crate.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_inline_crate/uses_inline_crate.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 179940f6bd5..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_inline_crate/uses_inline_crate.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,249 +0,0 @@ - - - - -uses_inline_crate.main - Coverage Spans - - - -
@0,1,2,3,4,5,6,7,8,9,10⦊fn main() { - used_inline_crate::used_function(); - used_inline_crate::used_inline_function(); - let some_vec = vec![1, 2, 3, 4]; - used_inline_crate::used_only_from_bin_crate_generic_function(&some_vec); - used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs"); - used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec); - used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function( - "interesting?", - ); -}⦉@0,1,2,3,4,5,6,7,8,9,10
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index f037a8ee5c5..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - -while.main - Coverage Spans - - - -
@0⦊fn main() { - let num = 9⦉@0; - while @1,2⦊num >= 10⦉@1,2 @3,5⦊{ - }⦉@3,5 -}@4⦊⦉@4
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.while_early_ret/while_early_ret.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.while_early_ret/while_early_ret.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index fcb5418e1d0..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.while_early_ret/while_early_ret.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,130 +0,0 @@ - - - - -while_early_ret.main - Coverage Spans - - - -
@0⦊fn main() -> Result<(),u8> { - let mut countdown = 10⦉@0; - while - @1,2⦊countdown - > - 0⦉@1,2 - { - if - @3,5⦊countdown - < - 5⦉@3,5 - { - return - if - @6⦊countdown - > - 8⦉@6 - { - @8⦊Ok(())⦉@8 - } - else - { - @9⦊Err(1)⦉@9 - } - ; - }@7,11⦊ - countdown - -= - 1⦉@7,11 - ; - } - @4⦊Ok(())⦉@4 -}@12⦊⦉@12
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.yield/yield.main-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.yield/yield.main-{closure#0}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 1e68c345f84..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.yield/yield.main-{closure#0}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - -yield.main-{closure#0} - Coverage Spans - - - -
|| @0⦊{ - yield 1⦉@0; - return @1⦊"foo" - }⦉@1
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.yield/yield.main-{closure#1}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.yield/yield.main-{closure#1}.-------.InstrumentCoverage.0.html deleted file mode 100644 index 842d7823bfd..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.yield/yield.main-{closure#1}.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - -yield.main-{closure#1} - Coverage Spans - - - -
|| @0⦊{ - yield 1⦉@0; - @1⦊yield 2⦉@1; - @2⦊yield 3⦉@2; - return @3⦊"foo" - }⦉@3
- - diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.yield/yield.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.yield/yield.main.-------.InstrumentCoverage.0.html deleted file mode 100644 index 4c0c0d562b8..00000000000 --- a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.yield/yield.main.-------.InstrumentCoverage.0.html +++ /dev/null @@ -1,138 +0,0 @@ - - - - -yield.main - Coverage Spans - - - -
@0,1,2⦊fn main() ⦉@0,1,2{ - let @0,1,2⦊mut generator⦉@0,1,2 = || { - yield 1; - return "foo" - }; - - match @0,1,2⦊Pin::new(&mut generator).resume(()) { - GeneratorState::Yielded(1)⦉@0,1,2 => @4,6,7,8⦊{}⦉@4,6,7,8 - _ => @5⦊panic!("unexpected value from resume")⦉@5, - } - match @4,6,7,8⦊Pin::new(&mut generator).resume(())⦉@4,6,7,8 { - GeneratorState::Complete(@10,11⦊"foo"⦉@10,11) => @12,13,14,15⦊{}⦉@12,13,14,15 - _ => @9⦊panic!("unexpected value from resume")⦉@9, - } - - let @12,13,14,15⦊mut generator⦉@12,13,14,15 = || { - yield 1; - yield 2; - yield 3; - return "foo" - }; - - match @12,13,14,15⦊Pin::new(&mut generator).resume(()) { - GeneratorState::Yielded(1)⦉@12,13,14,15 => @17,19,20,21⦊{}⦉@17,19,20,21 - _ => @18⦊panic!("unexpected value from resume")⦉@18, - } - match @17,19,20,21⦊Pin::new(&mut generator).resume(()) { - GeneratorState::Yielded(2)⦉@17,19,20,21 => @23,25⦊{}⦉@23,25 - _ => @24⦊panic!("unexpected value from resume")⦉@24, - } -}@23,25⦊⦉@23,25
- - diff --git a/src/test/run-make-fulldeps/coverage/coverage_tools.mk b/src/test/run-make-fulldeps/coverage/coverage_tools.mk index 38643aaf902..aa1dc7b91ce 100644 --- a/src/test/run-make-fulldeps/coverage/coverage_tools.mk +++ b/src/test/run-make-fulldeps/coverage/coverage_tools.mk @@ -4,11 +4,3 @@ # -include ../coverage/coverage_tools.mk -include ../tools.mk - -# ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and -# `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw` -# file, required for coverage reports. -# -# Enabling `-C link-dead-code` is not necessary when compiling with `-Z instrument-coverage`, -# due to improvements in the coverage map generation, to add unreachable functions known to Rust. -# Therefore, `-C link-dead-code` is no longer automatically enabled. From 98ad0af60b28edae325237857a4544f634d0191f Mon Sep 17 00:00:00 2001 From: mibac138 <5672750+mibac138@users.noreply.github.com> Date: Sun, 6 Dec 2020 01:14:21 +0100 Subject: [PATCH 287/370] Properly suggest deref in else block --- compiler/rustc_typeck/src/check/demand.rs | 22 ++++++++++++++++++++++ src/test/ui/deref-suggestion.rs | 10 ++++++++++ src/test/ui/deref-suggestion.stderr | 11 ++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index f9f67769e96..8107cfbf32d 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -366,6 +366,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { false } + crate fn hir_id_sole_block_element( + &self, + hir_id: hir::HirId, + ) -> Option<&'tcx rustc_hir::Expr<'tcx>> { + let node: Option> = self.tcx.hir().find(hir_id); + match node { + Some(Node::Expr(rustc_hir::Expr { + kind: rustc_hir::ExprKind::Block(block, ..), + .. + })) if block.stmts.len() == 0 => block.expr, + _ => None, + } + } + /// This function is used to determine potential "simple" improvements or users' errors and /// provide them useful help. For example: /// @@ -652,6 +666,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let suggestion = if is_struct_pat_shorthand_field { format!("{}: *{}", code, code) + } else if let Some(expr) = + self.hir_id_sole_block_element(expr.hir_id) + { + if let Ok(inner_code) = sm.span_to_snippet(expr.span) { + format!("*{}", inner_code) + } else { + format!("*{}", code) + } } else { format!("*{}", code) }; diff --git a/src/test/ui/deref-suggestion.rs b/src/test/ui/deref-suggestion.rs index 580410aecf4..5cb680541dd 100644 --- a/src/test/ui/deref-suggestion.rs +++ b/src/test/ui/deref-suggestion.rs @@ -45,4 +45,14 @@ fn main() { //~^ ERROR mismatched types let r = R { i: i }; //~^ ERROR mismatched types + + + let a = &1; + let b = &2; + let val: i32 = if true { + a + 1 + } else { + b + //~^ ERROR mismatched types + }; } diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr index f59f05db9c0..6eef06b68cb 100644 --- a/src/test/ui/deref-suggestion.stderr +++ b/src/test/ui/deref-suggestion.stderr @@ -89,6 +89,15 @@ LL | let r = R { i: i }; | expected `u32`, found `&{integer}` | help: consider dereferencing the borrow: `*i` -error: aborting due to 10 previous errors +error[E0308]: mismatched types + --> $DIR/deref-suggestion.rs:55:9 + | +LL | b + | ^ + | | + | expected `i32`, found `&{integer}` + | help: consider dereferencing the borrow: `*b` + +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0308`. From e603f994b127881961b53bea988f87a7c7632f25 Mon Sep 17 00:00:00 2001 From: mibac138 <5672750+mibac138@users.noreply.github.com> Date: Thu, 17 Dec 2020 13:24:51 +0100 Subject: [PATCH 288/370] Address review comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Léo Lanteri Thauvin --- compiler/rustc_typeck/src/check/demand.rs | 18 +++++------------- src/test/ui/deref-suggestion.rs | 8 ++++++++ src/test/ui/deref-suggestion.stderr | 11 ++++++++++- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index 8107cfbf32d..2d84e7830c2 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -366,16 +366,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { false } - crate fn hir_id_sole_block_element( - &self, - hir_id: hir::HirId, - ) -> Option<&'tcx rustc_hir::Expr<'tcx>> { - let node: Option> = self.tcx.hir().find(hir_id); - match node { - Some(Node::Expr(rustc_hir::Expr { - kind: rustc_hir::ExprKind::Block(block, ..), - .. - })) if block.stmts.len() == 0 => block.expr, + /// If the given `HirId` corresponds to a block with a trailing expression, return that expression + crate fn maybe_get_block_expr(&self, hir_id: hir::HirId) -> Option<&'tcx hir::Expr<'tcx>> { + match self.tcx.hir().find(hir_id)? { + Node::Expr(hir::Expr { kind: hir::ExprKind::Block(block, ..), .. }) => block.expr, _ => None, } } @@ -666,9 +660,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let suggestion = if is_struct_pat_shorthand_field { format!("{}: *{}", code, code) - } else if let Some(expr) = - self.hir_id_sole_block_element(expr.hir_id) - { + } else if let Some(expr) = self.maybe_get_block_expr(expr.hir_id) { if let Ok(inner_code) = sm.span_to_snippet(expr.span) { format!("*{}", inner_code) } else { diff --git a/src/test/ui/deref-suggestion.rs b/src/test/ui/deref-suggestion.rs index 5cb680541dd..e62e8467bd2 100644 --- a/src/test/ui/deref-suggestion.rs +++ b/src/test/ui/deref-suggestion.rs @@ -55,4 +55,12 @@ fn main() { b //~^ ERROR mismatched types }; + let val: i32 = if true { + let _ = 2; + a + 1 + } else { + let _ = 2; + b + //~^ ERROR mismatched types + }; } diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr index 6eef06b68cb..0de125695e6 100644 --- a/src/test/ui/deref-suggestion.stderr +++ b/src/test/ui/deref-suggestion.stderr @@ -98,6 +98,15 @@ LL | b | expected `i32`, found `&{integer}` | help: consider dereferencing the borrow: `*b` -error: aborting due to 11 previous errors +error[E0308]: mismatched types + --> $DIR/deref-suggestion.rs:63:9 + | +LL | b + | ^ + | | + | expected `i32`, found `&{integer}` + | help: consider dereferencing the borrow: `*b` + +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0308`. From 08879449c645c224d3628bebb3e5b5a50a88cc3f Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Thu, 25 Mar 2021 21:53:56 +0100 Subject: [PATCH 289/370] Add additional test Co-authored-by: Camelid --- src/test/ui/deref-suggestion.rs | 8 ++++++++ src/test/ui/deref-suggestion.stderr | 31 ++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/test/ui/deref-suggestion.rs b/src/test/ui/deref-suggestion.rs index e62e8467bd2..4fd695585ba 100644 --- a/src/test/ui/deref-suggestion.rs +++ b/src/test/ui/deref-suggestion.rs @@ -63,4 +63,12 @@ fn main() { b //~^ ERROR mismatched types }; + let val = if true { + *a + } else if true { + //~^ ERROR incompatible types + b + } else { + &0 + }; } diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr index 0de125695e6..1720421c7f6 100644 --- a/src/test/ui/deref-suggestion.stderr +++ b/src/test/ui/deref-suggestion.stderr @@ -107,6 +107,35 @@ LL | b | expected `i32`, found `&{integer}` | help: consider dereferencing the borrow: `*b` -error: aborting due to 12 previous errors +error[E0308]: `if` and `else` have incompatible types + --> $DIR/deref-suggestion.rs:68:12 + | +LL | let val = if true { + | _______________- +LL | | *a + | | -- expected because of this +LL | | } else if true { + | |____________^ +LL | || +LL | || b +LL | || } else { +LL | || &0 +LL | || }; + | || ^ + | ||_____| + | |______`if` and `else` have incompatible types + | expected `i32`, found `&{integer}` + | +help: consider dereferencing the borrow + | +LL | } else *if true { +LL | +LL | b +LL | } else { +LL | &0 +LL | }; + | + +error: aborting due to 13 previous errors For more information about this error, try `rustc --explain E0308`. From 5547d927467ef3398c3f509f0212ba26645a18da Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 2 Apr 2021 15:11:49 +0300 Subject: [PATCH 290/370] Document "standard" conventions for error messages These are currently documented in the API guidelines: https://rust-lang.github.io/api-guidelines/interoperability.html#error-types-are-meaningful-and-well-behaved-c-good-err I think it makes sense to uplift this guideline (in a milder form) into std docs. Printing and producing errors is something that even non-expert users do frequently, so it is useful to give at least some indication of what a typical error message looks like. --- library/std/src/error.rs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 80c35307d52..14c2f961d32 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -33,15 +33,22 @@ use crate::string; use crate::sync::Arc; /// `Error` is a trait representing the basic expectations for error values, -/// i.e., values of type `E` in [`Result`]. Errors must describe -/// themselves through the [`Display`] and [`Debug`] traits, and may provide -/// cause chain information: +/// i.e., values of type `E` in [`Result`]. /// -/// [`Error::source()`] is generally used when errors cross -/// "abstraction boundaries". If one module must report an error that is caused -/// by an error from a lower-level module, it can allow accessing that error -/// via [`Error::source()`]. This makes it possible for the high-level -/// module to provide its own errors while also revealing some of the +/// Errors must describe themselves through the [`Display`] and [`Debug`] +/// traits. Error messages are typically concise lowercase sentences without +/// trailing punctuation: +/// +/// ``` +/// let err = "NaN".parse::().unwrap_err(); +/// assert_eq!(err.to_string(), "invalid digit found in string"); +/// ``` +/// +/// Errors may provide cause chain information. [`Error::source()`] is generally +/// used when errors cross "abstraction boundaries". If one module must report +/// an error that is caused by an error from a lower-level module, it can allow +/// accessing that error via [`Error::source()`]. This makes it possible for the +/// high-level module to provide its own errors while also revealing some of the /// implementation for debugging via `source` chains. #[stable(feature = "rust1", since = "1.0.0")] pub trait Error: Debug + Display { From c86e0985f91d4b824370d3c4e015cd51460bf7dc Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Fri, 2 Apr 2021 17:37:52 +0200 Subject: [PATCH 291/370] Introduce `get_process_heap` and fix atomic ordering. --- library/std/src/sys/windows/alloc.rs | 35 +++++++++++++++++----------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/library/std/src/sys/windows/alloc.rs b/library/std/src/sys/windows/alloc.rs index bc4725dfc7b..182743998d6 100644 --- a/library/std/src/sys/windows/alloc.rs +++ b/library/std/src/sys/windows/alloc.rs @@ -89,10 +89,10 @@ extern "system" { static HEAP: AtomicPtr = AtomicPtr::new(ptr::null_mut()); // Get a handle to the default heap of the current process, or null if the operation fails. -// SAFETY: If this operation is successful, `HEAP` will be successfully initialized and contain +// If this operation is successful, `HEAP` will be successfully initialized and contain // a non-null handle returned by `GetProcessHeap`. #[inline] -unsafe fn init_or_get_process_heap() -> c::HANDLE { +fn init_or_get_process_heap() -> c::HANDLE { let heap = HEAP.load(Ordering::Relaxed); if heap.is_null() { // `HEAP` has not yet been successfully initialized @@ -100,7 +100,7 @@ unsafe fn init_or_get_process_heap() -> c::HANDLE { if !heap.is_null() { // SAFETY: No locking is needed because within the same process, // successful calls to `GetProcessHeap` will always return the same value, even on different threads. - HEAP.store(heap, Ordering::Relaxed); + HEAP.store(heap, Ordering::Release); // SAFETY: `HEAP` contains a non-null handle returned by `GetProcessHeap` heap @@ -114,16 +114,25 @@ unsafe fn init_or_get_process_heap() -> c::HANDLE { } } +// Get a non-null handle to the default heap of the current process. +// SAFETY: `HEAP` must have been successfully initialized. +#[inline] +unsafe fn get_process_heap() -> c::HANDLE { + HEAP.load(Ordering::Acquire) +} + // Header containing a pointer to the start of an allocated block. // SAFETY: Size and alignment must be <= `MIN_ALIGN`. #[repr(C)] struct Header(*mut u8); // Allocate a block of optionally zeroed memory for a given `layout`. -// SAFETY: Returns a pointer satisfying the guarantees of `System` about allocated pointers. +// SAFETY: Returns a pointer satisfying the guarantees of `System` about allocated pointers, +// or null if the operation fails. If this returns non-null `HEAP` will have been successfully +// initialized. #[inline] unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 { - let heap = unsafe { init_or_get_process_heap() }; + let heap = init_or_get_process_heap(); if heap.is_null() { // Allocation has failed, could not get the current process heap. return ptr::null_mut(); @@ -209,11 +218,11 @@ unsafe impl GlobalAlloc for System { }; // SAFETY: because `ptr` has been successfully allocated with this allocator, - // `HEAP` must have been successfully initialized and contain a non-null handle - // returned by `GetProcessHeap`. - let heap = HEAP.load(Ordering::Relaxed); + // `HEAP` must have been successfully initialized. + let heap = unsafe { get_process_heap() }; - // SAFETY: `block` is a pointer to the start of an allocated block. + // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`, + // `block` is a pointer to the start of an allocated block. unsafe { let err = HeapFree(heap, 0, block as c::LPVOID); debug_assert!(err != 0, "Failed to free heap memory: {}", c::GetLastError()); @@ -224,11 +233,11 @@ unsafe impl GlobalAlloc for System { unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { if layout.align() <= MIN_ALIGN { // SAFETY: because `ptr` has been successfully allocated with this allocator, - // `HEAP` must have been successfully initialized and contain a non-null handle - // returned by `GetProcessHeap`. - let heap = HEAP.load(Ordering::Relaxed); + // `HEAP` must have been successfully initialized. + let heap = unsafe { get_process_heap() }; - // SAFETY: `ptr` is a pointer to the start of an allocated block. + // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`, + // `ptr` is a pointer to the start of an allocated block. // The returned pointer points to the start of an allocated block. unsafe { HeapReAlloc(heap, 0, ptr as c::LPVOID, new_size) as *mut u8 } } else { From db1d003de1657e31174fac2bfa016000294ea266 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Fri, 2 Apr 2021 17:50:23 +0200 Subject: [PATCH 292/370] Remove `debug_assert` --- library/std/src/sys/windows/alloc.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library/std/src/sys/windows/alloc.rs b/library/std/src/sys/windows/alloc.rs index 182743998d6..af93cd7a3e2 100644 --- a/library/std/src/sys/windows/alloc.rs +++ b/library/std/src/sys/windows/alloc.rs @@ -223,10 +223,7 @@ unsafe impl GlobalAlloc for System { // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`, // `block` is a pointer to the start of an allocated block. - unsafe { - let err = HeapFree(heap, 0, block as c::LPVOID); - debug_assert!(err != 0, "Failed to free heap memory: {}", c::GetLastError()); - } + unsafe { HeapFree(heap, 0, block as c::LPVOID) }; } #[inline] From 3166e0857defd02d78f5afe1a64380a429967cc7 Mon Sep 17 00:00:00 2001 From: Mario Carneiro Date: Fri, 2 Apr 2021 09:33:34 -0700 Subject: [PATCH 293/370] Monomorphization doc fix Only public items are monomorphization roots. This can be confirmed by noting that this program compiles: ```rust fn foo() { if true { foo::>() } } fn bar() { foo::<()>() } ``` --- compiler/rustc_mir/src/monomorphize/collector.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index fd5dbfb186e..cadfc85a858 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -59,9 +59,9 @@ //! //! ### Discovering roots //! -//! The roots of the mono item graph correspond to the non-generic +//! The roots of the mono item graph correspond to the public non-generic //! syntactic items in the source code. We find them by walking the HIR of the -//! crate, and whenever we hit upon a function, method, or static item, we +//! crate, and whenever we hit upon a public function, method, or static item, we //! create a mono item consisting of the items DefId and, since we only //! consider non-generic items, an empty type-substitution set. //! From e01c3b82110a3338eab2e2d9cffbb74dc7039bc7 Mon Sep 17 00:00:00 2001 From: Mario Carneiro Date: Fri, 2 Apr 2021 09:55:23 -0700 Subject: [PATCH 294/370] clarify wording --- compiler/rustc_mir/src/monomorphize/collector.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index cadfc85a858..8ecb0a7cdc5 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -61,9 +61,12 @@ //! //! The roots of the mono item graph correspond to the public non-generic //! syntactic items in the source code. We find them by walking the HIR of the -//! crate, and whenever we hit upon a public function, method, or static item, we -//! create a mono item consisting of the items DefId and, since we only -//! consider non-generic items, an empty type-substitution set. +//! crate, and whenever we hit upon a public function, method, or static item, +//! we create a mono item consisting of the items DefId and, since we only +//! consider non-generic items, an empty type-substitution set. (In eager +//! collection mode, during incremental compilation, all non-generic functions +//! are considered as roots, as well as when the `-Clink-dead-code` option is +//! specified. Functions marked `#[no_mangle]` also always act as roots.) //! //! ### Finding neighbor nodes //! Given a mono item node, we can discover neighbors by inspecting its From 99f3e889b1dd3fca8a6ac8d32b6bdcc444dd333a Mon Sep 17 00:00:00 2001 From: Mario Carneiro Date: Fri, 2 Apr 2021 10:21:23 -0700 Subject: [PATCH 295/370] fix --- compiler/rustc_mir/src/monomorphize/collector.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index 8ecb0a7cdc5..1fda71d74bb 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -66,7 +66,8 @@ //! consider non-generic items, an empty type-substitution set. (In eager //! collection mode, during incremental compilation, all non-generic functions //! are considered as roots, as well as when the `-Clink-dead-code` option is -//! specified. Functions marked `#[no_mangle]` also always act as roots.) +//! specified. Functions marked `#[no_mangle]` and functions called by inlinable +//! functions also always act as roots.) //! //! ### Finding neighbor nodes //! Given a mono item node, we can discover neighbors by inspecting its From fb7cf0982b6cba2a77e40ef6b5919e7584a07a95 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Fri, 2 Apr 2021 00:07:16 +0200 Subject: [PATCH 296/370] Don't suggest dereferencing an `else if` expression --- compiler/rustc_typeck/src/check/demand.rs | 24 ++++++++++++++++++----- src/test/ui/deref-suggestion.stderr | 10 ---------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index 2d84e7830c2..d879b6e97dc 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -374,6 +374,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// Returns whether the given expression is an `else if`. + crate fn is_else_if_block(&self, expr: &hir::Expr<'_>) -> bool { + if let hir::ExprKind::If(..) = expr.kind { + let parent_id = self.tcx.hir().get_parent_node(expr.hir_id); + if let Some(Node::Expr(hir::Expr { + kind: hir::ExprKind::If(_, _, Some(else_expr)), + .. + })) = self.tcx.hir().find(parent_id) + { + return else_expr.hir_id == expr.hir_id; + } + } + false + } + /// This function is used to determine potential "simple" improvements or users' errors and /// provide them useful help. For example: /// @@ -660,12 +675,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let suggestion = if is_struct_pat_shorthand_field { format!("{}: *{}", code, code) + } else if self.is_else_if_block(expr) { + // Don't suggest nonsense like `else *if` + return None; } else if let Some(expr) = self.maybe_get_block_expr(expr.hir_id) { - if let Ok(inner_code) = sm.span_to_snippet(expr.span) { - format!("*{}", inner_code) - } else { - format!("*{}", code) - } + format!("*{}", sm.span_to_snippet(expr.span).unwrap_or(code)) } else { format!("*{}", code) }; diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr index 1720421c7f6..632a279d796 100644 --- a/src/test/ui/deref-suggestion.stderr +++ b/src/test/ui/deref-suggestion.stderr @@ -125,16 +125,6 @@ LL | || }; | ||_____| | |______`if` and `else` have incompatible types | expected `i32`, found `&{integer}` - | -help: consider dereferencing the borrow - | -LL | } else *if true { -LL | -LL | b -LL | } else { -LL | &0 -LL | }; - | error: aborting due to 13 previous errors From 5f96c48de26a029727483b6f14f0ca2e5067da19 Mon Sep 17 00:00:00 2001 From: Camelid Date: Thu, 1 Apr 2021 13:26:29 -0700 Subject: [PATCH 297/370] rustdoc: Rename internal uses of `spotlight` I didn't make these renames in #80965 because I didn't want the PR to conflict with #80914. --- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/core.rs | 7 +++---- src/librustdoc/formats/cache.rs | 4 ++-- src/librustdoc/html/render/mod.rs | 14 ++++++++------ src/librustdoc/html/render/print_item.rs | 10 +++++----- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 1e9a7d1b4b9..277ec91f15e 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -624,7 +624,7 @@ crate fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) { let trait_ = clean::TraitWithExtraInfo { trait_, - is_spotlight: clean::utils::has_doc_flag(cx.tcx.get_attrs(did), sym::notable_trait), + is_notable: clean::utils::has_doc_flag(cx.tcx.get_attrs(did), sym::notable_trait), }; cx.external_traits.borrow_mut().insert(did, trait_); cx.active_extern_traits.remove(&did); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 4132e187c72..95d9ff98aed 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -65,7 +65,7 @@ crate struct Crate { #[derive(Clone, Debug)] crate struct TraitWithExtraInfo { crate trait_: Trait, - crate is_spotlight: bool, + crate is_notable: bool, } #[derive(Clone, Debug)] diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5a022b2d40c..dae7980130c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -464,10 +464,9 @@ crate fn run_global_ctxt( if let Some(sized_trait_did) = ctxt.tcx.lang_items().sized_trait() { let mut sized_trait = build_external_trait(&mut ctxt, sized_trait_did); sized_trait.is_auto = true; - ctxt.external_traits.borrow_mut().insert( - sized_trait_did, - TraitWithExtraInfo { trait_: sized_trait, is_spotlight: false }, - ); + ctxt.external_traits + .borrow_mut() + .insert(sized_trait_did, TraitWithExtraInfo { trait_: sized_trait, is_notable: false }); } debug!("crate: {:?}", tcx.hir().krate()); diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 01bceb1d910..0e405d6ae02 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -116,7 +116,7 @@ crate struct Cache { // even though the trait itself is not exported. This can happen if a trait // was defined in function/expression scope, since the impl will be picked // up by `collect-trait-impls` but the trait won't be scraped out in the HIR - // crawl. In order to prevent crashes when looking for spotlight traits or + // crawl. In order to prevent crashes when looking for notable traits or // when gathering trait documentation on a type, hold impls here while // folding and add them to the cache later on if we find the trait. orphan_trait_impls: Vec<(DefId, FxHashSet, Impl)>, @@ -227,7 +227,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { if let clean::TraitItem(ref t) = *item.kind { self.cache.traits.entry(item.def_id).or_insert_with(|| clean::TraitWithExtraInfo { trait_: t.clone(), - is_spotlight: item.attrs.has_doc_flag(sym::notable_trait), + is_notable: item.attrs.has_doc_flag(sym::notable_trait), }); } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 07bd26a4c5e..a8a08fb23e0 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1045,7 +1045,7 @@ fn render_assoc_item( write!( w, "{}{}{}{}{}{}{}fn {name}\ - {generics}{decl}{spotlight}{where_clause}", + {generics}{decl}{notable_traits}{where_clause}", if parent == ItemType::Trait { " " } else { "" }, vis, constness, @@ -1057,7 +1057,7 @@ fn render_assoc_item( name = name, generics = g.print(cache, tcx), decl = d.full_print(cache, tcx, header_len, indent, header.asyncness), - spotlight = spotlight_decl(&d, cache, tcx), + notable_traits = notable_traits_decl(&d, cache, tcx), where_clause = print_where_clause(g, cache, tcx, indent, end_newline), ) } @@ -1341,7 +1341,7 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, cache: &Cache) -> bo } } -fn spotlight_decl(decl: &clean::FnDecl, cache: &Cache, tcx: TyCtxt<'_>) -> String { +fn notable_traits_decl(decl: &clean::FnDecl, cache: &Cache, tcx: TyCtxt<'_>) -> String { let mut out = Buffer::html(); let mut trait_ = String::new(); @@ -1349,9 +1349,11 @@ fn spotlight_decl(decl: &clean::FnDecl, cache: &Cache, tcx: TyCtxt<'_>) -> Strin if let Some(impls) = cache.impls.get(&did) { for i in impls { let impl_ = i.inner_impl(); - if impl_.trait_.def_id().map_or(false, |d| { - cache.traits.get(&d).map(|t| t.is_spotlight).unwrap_or(false) - }) { + if impl_ + .trait_ + .def_id() + .map_or(false, |d| cache.traits.get(&d).map(|t| t.is_notable).unwrap_or(false)) + { if out.is_empty() { write!( &mut out, diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 25314f87eb5..0cdfe435b9c 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -10,9 +10,9 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use super::{ - collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_strs, render_assoc_item, - render_assoc_items, render_attributes, render_impl, render_stability_since_raw, spotlight_decl, - write_srclink, AssocItemLink, Context, + collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_strs, notable_traits_decl, + render_assoc_item, render_assoc_items, render_attributes, render_impl, + render_stability_since_raw, write_srclink, AssocItemLink, Context, }; use crate::clean::{self, GetDefId}; use crate::formats::cache::Cache; @@ -381,7 +381,7 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: write!( w, "{vis}{constness}{asyncness}{unsafety}{abi}fn \ - {name}{generics}{decl}{spotlight}{where_clause}", + {name}{generics}{decl}{notable_traits}{where_clause}", vis = it.visibility.print_with_space(cx.tcx(), it.def_id, cx.cache()), constness = f.header.constness.print_with_space(), asyncness = f.header.asyncness.print_with_space(), @@ -391,7 +391,7 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: generics = f.generics.print(cx.cache(), cx.tcx()), where_clause = print_where_clause(&f.generics, cx.cache(), cx.tcx(), 0, true), decl = f.decl.full_print(cx.cache(), cx.tcx(), header_len, 0, f.header.asyncness), - spotlight = spotlight_decl(&f.decl, cx.cache(), cx.tcx()), + notable_traits = notable_traits_decl(&f.decl, cx.cache(), cx.tcx()), ); document(w, cx, it, None) } From 1fe0fe47fcd88c67887b45293351a653b548e86a Mon Sep 17 00:00:00 2001 From: Camelid Date: Thu, 1 Apr 2021 13:31:55 -0700 Subject: [PATCH 298/370] rustdoc: Remove unused `spotlight` CSS I couldn't find any uses of this CSS. I think it was superseded by the `.notable-traits` CSS class and other similarly-named CSS classes. --- src/librustdoc/html/static/rustdoc.css | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 07dfb7f5cf0..f3ddd8ec6fa 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -173,13 +173,10 @@ code, pre, a.test-arrow { border-radius: 3px; padding: 0 0.1em; } -.docblock pre code, .docblock-short pre code, .docblock code.spotlight { +.docblock pre code, .docblock-short pre code { padding: 0; padding-right: 1ex; } -.docblock code.spotlight :last-child { - padding-bottom: 0.6em; -} pre { padding: 14px; } From 617e13548fded5d8b1deafc73c60db8677dc4886 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 15 Mar 2021 15:44:07 -0700 Subject: [PATCH 299/370] rustdoc: highlight macros more efficiently Instead of producing `assert_eq!`, just produce `assert_eq!`. --- src/librustdoc/html/highlight.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 7e50d72e60f..3a4319d5d9a 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -189,7 +189,9 @@ impl<'a> Classifier<'a> { // leading identifier. TokenKind::Bang if self.in_macro => { self.in_macro = false; - Class::Macro + sink(Highlight::Token { text, class: None }); + sink(Highlight::ExitSpan); + return; } // Assume that '&' or '*' is the reference or dereference operator @@ -298,7 +300,9 @@ impl<'a> Classifier<'a> { }, TokenKind::Ident | TokenKind::RawIdent if lookahead == Some(TokenKind::Bang) => { self.in_macro = true; - Class::Macro + sink(Highlight::EnterSpan { class: Class::Macro }); + sink(Highlight::Token { text, class: None }); + return; } TokenKind::Ident => match text { "ref" | "mut" => Class::RefKeyWord, From e4244e37103d83b2cd54637ca2ac4f1c76c35a43 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 31 Mar 2021 22:33:07 -0400 Subject: [PATCH 300/370] Don't load all extern crates unconditionally Instead, only load the crates that are linked to with intra-doc links. This doesn't help very much with any of rustdoc's fundamental issues with freezing the resolver, but it at least fixes a stable-to-stable regression, and makes the crate loading model somewhat more consistent with rustc's. --- src/librustdoc/core.rs | 84 ++++++++++++------- src/librustdoc/lib.rs | 4 +- .../passes/collect_intra_doc_links.rs | 4 +- src/librustdoc/passes/mod.rs | 2 +- src/test/rustdoc-ui/auxiliary/panic-item.rs | 17 ++++ src/test/rustdoc-ui/unused-extern-crate.rs | 3 + .../auxiliary/issue-66159-1.rs | 0 .../extern-crate-only-used-in-link.rs | 8 ++ src/test/rustdoc/issue-66159.rs | 10 --- src/tools/compiletest/src/header.rs | 4 +- 10 files changed, 89 insertions(+), 47 deletions(-) create mode 100644 src/test/rustdoc-ui/auxiliary/panic-item.rs create mode 100644 src/test/rustdoc-ui/unused-extern-crate.rs rename src/test/rustdoc/{ => intra-doc}/auxiliary/issue-66159-1.rs (100%) create mode 100644 src/test/rustdoc/intra-doc/extern-crate-only-used-in-link.rs delete mode 100644 src/test/rustdoc/issue-66159.rs diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5a022b2d40c..3d216534357 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -1,3 +1,4 @@ +use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{self, Lrc}; use rustc_driver::abort_on_err; @@ -22,7 +23,7 @@ use rustc_session::DiagnosticOutput; use rustc_session::Session; use rustc_span::source_map; use rustc_span::symbol::sym; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::Span; use std::cell::RefCell; use std::collections::hash_map::Entry; @@ -348,42 +349,65 @@ crate fn create_config( } crate fn create_resolver<'a>( - externs: config::Externs, queries: &Queries<'a>, sess: &Session, ) -> Rc> { - let extern_names: Vec = externs - .iter() - .filter(|(_, entry)| entry.add_prelude) - .map(|(name, _)| name) - .cloned() - .collect(); - let parts = abort_on_err(queries.expansion(), sess).peek(); - let resolver = parts.1.borrow(); + let (krate, resolver, _) = &*parts; + let resolver = resolver.borrow().clone(); - // Before we actually clone it, let's force all the extern'd crates to - // actually be loaded, just in case they're only referred to inside - // intra-doc links - resolver.borrow_mut().access(|resolver| { - sess.time("load_extern_crates", || { - for extern_name in &extern_names { - debug!("loading extern crate {}", extern_name); - if let Err(()) = resolver - .resolve_str_path_error( - DUMMY_SP, - extern_name, - TypeNS, - LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(), - ) { - warn!("unable to resolve external crate {} (do you have an unused `--extern` crate?)", extern_name) - } + // Letting the resolver escape at the end of the function leads to inconsistencies between the + // crates the TyCtxt sees and the resolver sees (because the resolver could load more crates + // after escaping). Hopefully `IntraLinkCrateLoader` gets all the crates we need ... + struct IntraLinkCrateLoader { + current_mod: DefId, + resolver: Rc>, + } + impl ast::visit::Visitor<'_> for IntraLinkCrateLoader { + fn visit_attribute(&mut self, attr: &ast::Attribute) { + use crate::html::markdown::{markdown_links, MarkdownLink}; + use crate::passes::collect_intra_doc_links::Disambiguator; + + if let Some(doc) = attr.doc_str() { + for MarkdownLink { link, .. } in markdown_links(&doc.as_str()) { + // FIXME: this misses a *lot* of the preprocessing done in collect_intra_doc_links + // I think most of it shouldn't be necessary since we only need the crate prefix? + let path_str = match Disambiguator::from_str(&link) { + Ok(x) => x.map_or(link.as_str(), |(_, p)| p), + Err(_) => continue, + }; + self.resolver.borrow_mut().access(|resolver| { + let _ = resolver.resolve_str_path_error( + attr.span, + path_str, + TypeNS, + self.current_mod, + ); + }); + } } - }); - }); + ast::visit::walk_attribute(self, attr); + } - // Now we're good to clone the resolver because everything should be loaded - resolver.clone() + fn visit_item(&mut self, item: &ast::Item) { + use rustc_ast_lowering::ResolverAstLowering; + + if let ast::ItemKind::Mod(..) = item.kind { + let new_mod = + self.resolver.borrow_mut().access(|resolver| resolver.local_def_id(item.id)); + let old_mod = mem::replace(&mut self.current_mod, new_mod.to_def_id()); + ast::visit::walk_item(self, item); + self.current_mod = old_mod; + } else { + ast::visit::walk_item(self, item); + } + } + } + let crate_id = LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(); + let mut loader = IntraLinkCrateLoader { current_mod: crate_id, resolver }; + ast::visit::walk_crate(&mut loader, krate); + + loader.resolver } crate fn run_global_ctxt( diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index dabc21e3a44..a3b83b9701f 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -31,6 +31,7 @@ extern crate tracing; // // Dependencies listed in Cargo.toml do not need `extern crate`. extern crate rustc_ast; +extern crate rustc_ast_lowering; extern crate rustc_ast_pretty; extern crate rustc_attr; extern crate rustc_data_structures; @@ -637,7 +638,6 @@ fn main_options(options: config::Options) -> MainResult { let default_passes = options.default_passes; let output_format = options.output_format; // FIXME: fix this clone (especially render_options) - let externs = options.externs.clone(); let manual_passes = options.manual_passes.clone(); let render_options = options.render_options.clone(); let config = core::create_config(options); @@ -649,7 +649,7 @@ fn main_options(options: config::Options) -> MainResult { // We need to hold on to the complete resolver, so we cause everything to be // cloned for the analysis passes to use. Suboptimal, but necessary in the // current architecture. - let resolver = core::create_resolver(externs, queries, &sess); + let resolver = core::create_resolver(queries, &sess); if sess.has_errors() { sess.fatal("Compilation failed, aborting rustdoc"); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 55978ca551b..437f42b26dd 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1517,7 +1517,7 @@ fn range_between_backticks(ori_link: &MarkdownLink) -> Range { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] /// Disambiguators for a link. -enum Disambiguator { +crate enum Disambiguator { /// `prim@` /// /// This is buggy, see @@ -1546,7 +1546,7 @@ impl Disambiguator { /// This returns `Ok(Some(...))` if a disambiguator was found, /// `Ok(None)` if no disambiguator was found, or `Err(...)` /// if there was a problem with the disambiguator. - fn from_str(link: &str) -> Result, (String, Range)> { + crate fn from_str(link: &str) -> Result, (String, Range)> { use Disambiguator::{Kind, Namespace as NS, Primitive}; if let Some(idx) = link.find('@') { diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 4c639c8496d..755217a4629 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -30,7 +30,7 @@ crate use self::unindent_comments::UNINDENT_COMMENTS; mod propagate_doc_cfg; crate use self::propagate_doc_cfg::PROPAGATE_DOC_CFG; -mod collect_intra_doc_links; +crate mod collect_intra_doc_links; crate use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS; mod doc_test_lints; diff --git a/src/test/rustdoc-ui/auxiliary/panic-item.rs b/src/test/rustdoc-ui/auxiliary/panic-item.rs new file mode 100644 index 00000000000..17b26850d4d --- /dev/null +++ b/src/test/rustdoc-ui/auxiliary/panic-item.rs @@ -0,0 +1,17 @@ +// no-prefer-dynamic +#![crate_type = "lib"] +#![no_std] +#![feature(lang_items)] + +use core::panic::PanicInfo; +use core::sync::atomic::{self, Ordering}; + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + loop { + atomic::compiler_fence(Ordering::SeqCst); + } +} + +#[lang = "eh_personality"] +fn foo() {} diff --git a/src/test/rustdoc-ui/unused-extern-crate.rs b/src/test/rustdoc-ui/unused-extern-crate.rs new file mode 100644 index 00000000000..f703a183790 --- /dev/null +++ b/src/test/rustdoc-ui/unused-extern-crate.rs @@ -0,0 +1,3 @@ +// check-pass +// aux-crate:panic_item=panic-item.rs +// @has unused_extern_crate/index.html diff --git a/src/test/rustdoc/auxiliary/issue-66159-1.rs b/src/test/rustdoc/intra-doc/auxiliary/issue-66159-1.rs similarity index 100% rename from src/test/rustdoc/auxiliary/issue-66159-1.rs rename to src/test/rustdoc/intra-doc/auxiliary/issue-66159-1.rs diff --git a/src/test/rustdoc/intra-doc/extern-crate-only-used-in-link.rs b/src/test/rustdoc/intra-doc/extern-crate-only-used-in-link.rs new file mode 100644 index 00000000000..0964c79de06 --- /dev/null +++ b/src/test/rustdoc/intra-doc/extern-crate-only-used-in-link.rs @@ -0,0 +1,8 @@ +// aux-build:issue-66159-1.rs +// aux-crate:priv:issue_66159_1=issue-66159-1.rs +// build-aux-docs +// compile-flags:-Z unstable-options + +// @has extern_crate_only_used_in_link/index.html +// @has - '//a[@href="../issue_66159_1/struct.Something.html"]' 'issue_66159_1::Something' +//! [issue_66159_1::Something] diff --git a/src/test/rustdoc/issue-66159.rs b/src/test/rustdoc/issue-66159.rs deleted file mode 100644 index 003d079a470..00000000000 --- a/src/test/rustdoc/issue-66159.rs +++ /dev/null @@ -1,10 +0,0 @@ -// aux-crate:priv:issue_66159_1=issue-66159-1.rs -// compile-flags:-Z unstable-options - -// The issue was an ICE which meant that we never actually generated the docs -// so if we have generated the docs, we're okay. -// Since we don't generate the docs for the auxiliary files, we can't actually -// verify that the struct is linked correctly. - -// @has issue_66159/index.html -//! [issue_66159_1::Something] diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 83ea676e8f4..531a23d76a2 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -708,8 +708,8 @@ impl Config { self.parse_name_value_directive(line, "aux-crate").map(|r| { let mut parts = r.trim().splitn(2, '='); ( - parts.next().expect("aux-crate name").to_string(), - parts.next().expect("aux-crate value").to_string(), + parts.next().expect("missing aux-crate name (e.g. log=log.rs)").to_string(), + parts.next().expect("missing aux-crate value (e.g. log=log.rs)").to_string(), ) }) } From 2f000a78bf615b35c4837f920fb6adcad4848351 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sun, 28 Mar 2021 00:11:24 +0200 Subject: [PATCH 301/370] Manually set dso_local when its valid to do so This should have no real effect in most cases, as e.g. `hidden` visibility already implies `dso_local` (or at least LLVM IR does not preserve the `dso_local` setting if the item is already `hidden`), but it should fix `-Crelocation-model=static` and improve codegen in executables. Note that this PR does not exhaustively port the logic in [clang]. Only the obviously correct portion and what is necessary to fix a regression from LLVM 12 that relates to `-Crelocation_model=static`. Fixes #83335 [clang]: https://github.com/llvm/llvm-project/blob/3001d080c813da20b329303bf8f45451480e5905/clang/lib/CodeGen/CodeGenModule.cpp#L945-L1039 --- compiler/rustc_codegen_llvm/src/attributes.rs | 1 + compiler/rustc_codegen_llvm/src/callee.rs | 19 ++++---- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_codegen_llvm/src/mono_item.rs | 41 +++++++++++++++++ .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 4 ++ src/test/assembly/static-relocation-model.rs | 44 +++++++++++++++++++ src/test/codegen/abi-efiapi.rs | 6 +-- src/test/codegen/abi-repr-ext.rs | 2 +- src/test/codegen/abi-sysv64.rs | 18 +++++--- src/test/codegen/abi-x86-interrupt.rs | 17 ++++--- .../codegen/cdylib-external-inline-fns.rs | 16 +++---- src/test/codegen/dealloc-no-unwind.rs | 3 +- src/test/codegen/external-no-mangle-fns.rs | 24 +++++----- src/test/codegen/fewer-names.rs | 4 +- src/test/codegen/ffi-const.rs | 2 +- src/test/codegen/ffi-pure.rs | 2 +- src/test/codegen/ffi-returns-twice.rs | 5 +-- src/test/codegen/intrinsics/nontemporal.rs | 2 +- src/test/codegen/issue-32031.rs | 4 +- src/test/codegen/lto-removes-invokes.rs | 2 +- src/test/codegen/naked-functions.rs | 8 ++-- src/test/codegen/optimize-attr-1.rs | 6 +-- .../codegen/repr-transparent-aggregates-1.rs | 16 +++---- src/test/codegen/repr-transparent.rs | 34 +++++++------- src/test/codegen/sanitizer-recover.rs | 10 ++--- src/test/codegen/scalar-pair-bool.rs | 10 ++--- .../codegen/staticlib-external-inline-fns.rs | 16 +++---- src/test/codegen/transmute-scalar.rs | 12 ++--- src/test/codegen/unwind-extern-imports.rs | 12 ++--- src/test/codegen/var-names.rs | 2 +- 30 files changed, 221 insertions(+), 122 deletions(-) create mode 100644 src/test/assembly/static-relocation-model.rs diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 64ebe585dd8..a0bd677fb9f 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -254,6 +254,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: attributes::emit_uwtable(llfn, true); } + // FIXME: none of these three functions interact with source level attributes. set_frame_pointer_elimination(cx, llfn); set_instrument_function(cx, llfn); set_probestack(cx, llfn); diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index 367c1f4811c..b26969a5012 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -14,6 +14,7 @@ use tracing::debug; use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt}; use rustc_middle::ty::{self, Instance, TypeFoldable}; +use rustc_target::spec::RelocModel; /// Codegens a reference to a fn/method item, monomorphizing and /// inlining as it goes. @@ -170,17 +171,19 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value } } } - } - // MinGW: For backward compatibility we rely on the linker to decide whether it - // should use dllimport for functions. - if cx.use_dll_storage_attrs - && tcx.is_dllimport_foreign_item(instance_def_id) - && tcx.sess.target.env != "gnu" - { - unsafe { + // MinGW: For backward compatibility we rely on the linker to decide whether it + // should use dllimport for functions. + if cx.use_dll_storage_attrs + && tcx.is_dllimport_foreign_item(instance_def_id) + && tcx.sess.target.env != "gnu" + { llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); } + + if cx.tcx.sess.relocation_model() == RelocModel::Static { + llvm::LLVMRustSetDSOLocal(llfn, true); + } } llfn diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 82cd1be3b3b..84d4fbdec34 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1031,6 +1031,7 @@ extern "C" { pub fn LLVMSetSection(Global: &Value, Section: *const c_char); pub fn LLVMRustGetVisibility(Global: &Value) -> Visibility; pub fn LLVMRustSetVisibility(Global: &Value, Viz: Visibility); + pub fn LLVMRustSetDSOLocal(Global: &Value, is_dso_local: bool); pub fn LLVMGetAlignment(Global: &Value) -> c_uint; pub fn LLVMSetAlignment(Global: &Value, Bytes: c_uint); pub fn LLVMSetDLLStorageClass(V: &Value, C: DLLStorageClass); diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 992e83d08fc..fc1f364e9c6 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -10,7 +10,9 @@ pub use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::{Linkage, Visibility}; use rustc_middle::ty::layout::FnAbiExt; use rustc_middle::ty::{self, Instance, TypeFoldable}; +use rustc_session::config::CrateType; use rustc_target::abi::LayoutOf; +use rustc_target::spec::RelocModel; use tracing::debug; impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> { @@ -35,6 +37,9 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> { unsafe { llvm::LLVMRustSetLinkage(g, base::linkage_to_llvm(linkage)); llvm::LLVMRustSetVisibility(g, base::visibility_to_llvm(visibility)); + if self.should_assume_dso_local(linkage, visibility) { + llvm::LLVMRustSetDSOLocal(g, true); + } } self.instances.borrow_mut().insert(instance, g); @@ -79,6 +84,42 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> { attributes::from_fn_attrs(self, lldecl, instance); + unsafe { + if self.should_assume_dso_local(linkage, visibility) { + llvm::LLVMRustSetDSOLocal(lldecl, true); + } + } + self.instances.borrow_mut().insert(instance, lldecl); } } + +impl CodegenCx<'ll, 'tcx> { + /// Whether a definition (NB: not declaration!) can be assumed to be local to a group of + /// libraries that form a single DSO or executable. + pub(crate) unsafe fn should_assume_dso_local( + &self, + linkage: Linkage, + visibility: Visibility, + ) -> bool { + if matches!(linkage, Linkage::Internal | Linkage::Private) { + return true; + } + + if visibility != Visibility::Default && linkage != Linkage::ExternalWeak { + return true; + } + + // Static relocation model should force copy relocations everywhere. + if self.tcx.sess.relocation_model() == RelocModel::Static { + return true; + } + + // Symbols from executables can't really be imported any further. + if self.tcx.sess.crate_types().iter().all(|ty| *ty == CrateType::Executable) { + return true; + } + + return false; + } +} diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 2bb22fd4447..d6db69c748f 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1636,6 +1636,10 @@ extern "C" void LLVMRustSetVisibility(LLVMValueRef V, LLVMSetVisibility(V, fromRust(RustVisibility)); } +extern "C" void LLVMRustSetDSOLocal(LLVMValueRef Global, bool is_dso_local) { + unwrap(Global)->setDSOLocal(is_dso_local); +} + struct LLVMRustModuleBuffer { std::string data; }; diff --git a/src/test/assembly/static-relocation-model.rs b/src/test/assembly/static-relocation-model.rs new file mode 100644 index 00000000000..0463045c156 --- /dev/null +++ b/src/test/assembly/static-relocation-model.rs @@ -0,0 +1,44 @@ +// min-llvm-version: 12.0.0 +// needs-llvm-components: aarch64 x86 +// revisions:X64 A64 +// assembly-output: emit-asm +// [X64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=static +// [A64] compile-flags: --target aarch64-unknown-linux-gnu -Crelocation-model=static + +#![feature(no_core, lang_items)] +#![no_core] +#![crate_type="rlib"] + +#[lang="sized"] +trait Sized {} + +#[lang="copy"] +trait Copy {} + +impl Copy for u8 {} + +extern "C" { + fn chaenomeles(); +} + +// CHECK-LABEL: banana: +// x64: movb chaenomeles, %{{[a,z]+}} +// A64: adrp [[REG:[a-z0-9]+]], chaenomeles +// A64-NEXT: ldrb {{[a-z0-9]+}}, {{\[}}[[REG]], :lo12:chaenomeles] +#[no_mangle] +pub fn banana() -> u8 { + unsafe { + *(chaenomeles as *mut u8) + } +} + +// CHECK-LABEL: peach: +// x64: movb banana, %{{[a,z]+}} +// A64: adrp [[REG2:[a-z0-9]+]], banana +// A64-NEXT: ldrb {{[a-z0-9]+}}, {{\[}}[[REG2]], :lo12:banana] +#[no_mangle] +pub fn peach() -> u8 { + unsafe { + *(banana as *mut u8) + } +} diff --git a/src/test/codegen/abi-efiapi.rs b/src/test/codegen/abi-efiapi.rs index 6cb2728359b..613b0bf50e5 100644 --- a/src/test/codegen/abi-efiapi.rs +++ b/src/test/codegen/abi-efiapi.rs @@ -23,8 +23,8 @@ trait Copy { } //x86_64: define win64cc void @has_efiapi //i686: define void @has_efiapi -//aarch64: define void @has_efiapi -//arm: define void @has_efiapi -//riscv: define void @has_efiapi +//aarch64: define dso_local void @has_efiapi +//arm: define dso_local void @has_efiapi +//riscv: define dso_local void @has_efiapi #[no_mangle] pub extern "efiapi" fn has_efiapi() {} diff --git a/src/test/codegen/abi-repr-ext.rs b/src/test/codegen/abi-repr-ext.rs index f93ccd79411..9dba1718acd 100644 --- a/src/test/codegen/abi-repr-ext.rs +++ b/src/test/codegen/abi-repr-ext.rs @@ -6,7 +6,7 @@ pub enum Type { Type2 = 1 } -// CHECK: define signext i8 @test() +// CHECK: define{{( dso_local)?}} signext i8 @test() #[no_mangle] pub extern "C" fn test() -> Type { Type::Type1 diff --git a/src/test/codegen/abi-sysv64.rs b/src/test/codegen/abi-sysv64.rs index 89c9bcee052..bb910d573b3 100644 --- a/src/test/codegen/abi-sysv64.rs +++ b/src/test/codegen/abi-sysv64.rs @@ -1,17 +1,21 @@ // Checks if the correct annotation for the sysv64 ABI is passed to // llvm. Also checks that the abi-sysv64 feature gate allows usage // of the sysv64 abi. - -// ignore-arm -// ignore-aarch64 -// ignore-riscv64 sysv64 not supported - -// compile-flags: -C no-prepopulate-passes +// +// needs-llvm-components: x86 +// compile-flags: -C no-prepopulate-passes --target=x86_64-unknown-linux-gnu #![crate_type = "lib"] +#![no_core] +#![feature(abi_x86_interrupt, no_core, lang_items)] + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} // CHECK: define x86_64_sysvcc i64 @has_sysv64_abi #[no_mangle] pub extern "sysv64" fn has_sysv64_abi(a: i64) -> i64 { - a * 2 + a } diff --git a/src/test/codegen/abi-x86-interrupt.rs b/src/test/codegen/abi-x86-interrupt.rs index 25c155c949d..119004d261d 100644 --- a/src/test/codegen/abi-x86-interrupt.rs +++ b/src/test/codegen/abi-x86-interrupt.rs @@ -2,17 +2,20 @@ // llvm. Also checks that the abi_x86_interrupt feature gate allows usage // of the x86-interrupt abi. -// ignore-arm -// ignore-aarch64 -// ignore-riscv64 x86-interrupt is not supported - -// compile-flags: -C no-prepopulate-passes +// needs-llvm-components: x86 +// compile-flags: -C no-prepopulate-passes --target=x86_64-unknown-linux-gnu #![crate_type = "lib"] -#![feature(abi_x86_interrupt)] +#![no_core] +#![feature(abi_x86_interrupt, no_core, lang_items)] + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} // CHECK: define x86_intrcc i64 @has_x86_interrupt_abi #[no_mangle] pub extern "x86-interrupt" fn has_x86_interrupt_abi(a: i64) -> i64 { - a * 2 + a } diff --git a/src/test/codegen/cdylib-external-inline-fns.rs b/src/test/codegen/cdylib-external-inline-fns.rs index 519be6b6a99..9118afd43d8 100644 --- a/src/test/codegen/cdylib-external-inline-fns.rs +++ b/src/test/codegen/cdylib-external-inline-fns.rs @@ -2,42 +2,42 @@ #![crate_type = "cdylib"] -// CHECK: define void @a() +// CHECK: define{{( dso_local)?}} void @a() #[no_mangle] #[inline] pub extern "C" fn a() {} -// CHECK: define void @b() +// CHECK: define{{( dso_local)?}} void @b() #[export_name = "b"] #[inline] pub extern "C" fn b() {} -// CHECK: define void @c() +// CHECK: define{{( dso_local)?}} void @c() #[no_mangle] #[inline] extern "C" fn c() {} -// CHECK: define void @d() +// CHECK: define{{( dso_local)?}} void @d() #[export_name = "d"] #[inline] extern "C" fn d() {} -// CHECK: define void @e() +// CHECK: define{{( dso_local)?}} void @e() #[no_mangle] #[inline(always)] pub extern "C" fn e() {} -// CHECK: define void @f() +// CHECK: define{{( dso_local)?}} void @f() #[export_name = "f"] #[inline(always)] pub extern "C" fn f() {} -// CHECK: define void @g() +// CHECK: define{{( dso_local)?}} void @g() #[no_mangle] #[inline(always)] extern "C" fn g() {} -// CHECK: define void @h() +// CHECK: define{{( dso_local)?}} void @h() #[export_name = "h"] #[inline(always)] extern "C" fn h() {} diff --git a/src/test/codegen/dealloc-no-unwind.rs b/src/test/codegen/dealloc-no-unwind.rs index f047c7a180c..3812ef44ff2 100644 --- a/src/test/codegen/dealloc-no-unwind.rs +++ b/src/test/codegen/dealloc-no-unwind.rs @@ -1,4 +1,3 @@ -// // no-system-llvm // compile-flags: -O @@ -15,7 +14,7 @@ impl Drop for A { #[no_mangle] pub fn a(a: Box) { - // CHECK-LABEL: define void @a + // CHECK-LABEL: define{{.*}}void @a // CHECK: call void @__rust_dealloc // CHECK-NEXT: call void @foo let _a = A; diff --git a/src/test/codegen/external-no-mangle-fns.rs b/src/test/codegen/external-no-mangle-fns.rs index 41820b057f1..70349b2ec4f 100644 --- a/src/test/codegen/external-no-mangle-fns.rs +++ b/src/test/codegen/external-no-mangle-fns.rs @@ -4,30 +4,30 @@ #![crate_type = "lib"] #![no_std] -// CHECK: define void @a() +// CHECK: define{{( dso_local)?}} void @a() #[no_mangle] fn a() {} -// CHECK: define void @b() +// CHECK: define{{( dso_local)?}} void @b() #[no_mangle] pub fn b() {} mod private { - // CHECK: define void @c() + // CHECK: define{{( dso_local)?}} void @c() #[no_mangle] fn c() {} - // CHECK: define void @d() + // CHECK: define{{( dso_local)?}} void @d() #[no_mangle] pub fn d() {} } const HIDDEN: () = { - // CHECK: define void @e() + // CHECK: define{{( dso_local)?}} void @e() #[no_mangle] fn e() {} - // CHECK: define void @f() + // CHECK: define{{( dso_local)?}} void @f() #[no_mangle] pub fn f() {} }; @@ -38,13 +38,13 @@ const HIDDEN: () = { // CHECK-NEXT: define internal #[inline(never)] fn x() { - // CHECK: define void @g() + // CHECK: define{{( dso_local)?}} void @g() #[no_mangle] fn g() { x(); } - // CHECK: define void @h() + // CHECK: define{{( dso_local)?}} void @h() #[no_mangle] pub fn h() {} @@ -54,22 +54,22 @@ fn x() { } } -// CHECK: define void @i() +// CHECK: define{{( dso_local)?}} void @i() #[no_mangle] #[inline] fn i() {} -// CHECK: define void @j() +// CHECK: define{{( dso_local)?}} void @j() #[no_mangle] #[inline] pub fn j() {} -// CHECK: define void @k() +// CHECK: define{{( dso_local)?}} void @k() #[no_mangle] #[inline(always)] fn k() {} -// CHECK: define void @l() +// CHECK: define{{( dso_local)?}} void @l() #[no_mangle] #[inline(always)] pub fn l() {} diff --git a/src/test/codegen/fewer-names.rs b/src/test/codegen/fewer-names.rs index 53a926d49ef..7307e0379df 100644 --- a/src/test/codegen/fewer-names.rs +++ b/src/test/codegen/fewer-names.rs @@ -7,11 +7,11 @@ #[no_mangle] pub fn sum(x: u32, y: u32) -> u32 { -// YES-LABEL: define i32 @sum(i32 %0, i32 %1) +// YES-LABEL: define{{.*}}i32 @sum(i32 %0, i32 %1) // YES-NEXT: %3 = add i32 %1, %0 // YES-NEXT: ret i32 %3 -// NO-LABEL: define i32 @sum(i32 %x, i32 %y) +// NO-LABEL: define{{.*}}i32 @sum(i32 %x, i32 %y) // NO-NEXT: start: // NO-NEXT: %z = add i32 %y, %x // NO-NEXT: ret i32 %z diff --git a/src/test/codegen/ffi-const.rs b/src/test/codegen/ffi-const.rs index 67baf6fdd3e..d9cfa5429b5 100644 --- a/src/test/codegen/ffi-const.rs +++ b/src/test/codegen/ffi-const.rs @@ -5,7 +5,7 @@ pub fn bar() { unsafe { foo() } } extern "C" { - // CHECK-LABEL: declare void @foo() + // CHECK-LABEL: declare{{.*}}void @foo() // CHECK-SAME: [[ATTRS:#[0-9]+]] // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readnone{{.*}} } #[ffi_const] pub fn foo(); diff --git a/src/test/codegen/ffi-pure.rs b/src/test/codegen/ffi-pure.rs index 3afb0856c9d..5bdb2ee912a 100644 --- a/src/test/codegen/ffi-pure.rs +++ b/src/test/codegen/ffi-pure.rs @@ -5,7 +5,7 @@ pub fn bar() { unsafe { foo() } } extern "C" { - // CHECK-LABEL: declare void @foo() + // CHECK-LABEL: declare{{.*}}void @foo() // CHECK-SAME: [[ATTRS:#[0-9]+]] // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readonly{{.*}} } #[ffi_pure] pub fn foo(); diff --git a/src/test/codegen/ffi-returns-twice.rs b/src/test/codegen/ffi-returns-twice.rs index 75301dfd346..0fbe03f0bb6 100644 --- a/src/test/codegen/ffi-returns-twice.rs +++ b/src/test/codegen/ffi-returns-twice.rs @@ -5,8 +5,7 @@ pub fn bar() { unsafe { foo() } } extern "C" { - // CHECK-LABEL: declare void @foo() - // CHECK-SAME: [[ATTRS:#[0-9]+]] - // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}returns_twice{{.*}} } + // CHECK: declare{{( dso_local)?}} void @foo(){{.*}}[[ATTRS:#[0-9]+]] + // CHECK: attributes [[ATTRS]] = { {{.*}}returns_twice{{.*}} } #[ffi_returns_twice] pub fn foo(); } diff --git a/src/test/codegen/intrinsics/nontemporal.rs b/src/test/codegen/intrinsics/nontemporal.rs index 3a41fb4fab3..d13f3e51ba4 100644 --- a/src/test/codegen/intrinsics/nontemporal.rs +++ b/src/test/codegen/intrinsics/nontemporal.rs @@ -5,7 +5,7 @@ #[no_mangle] pub fn a(a: &mut u32, b: u32) { - // CHECK-LABEL: define void @a + // CHECK-LABEL: define{{.*}}void @a // CHECK: store i32 %b, i32* %a, align 4, !nontemporal unsafe { std::intrinsics::nontemporal_store(a, b); diff --git a/src/test/codegen/issue-32031.rs b/src/test/codegen/issue-32031.rs index cf672266bc7..82ba325572a 100644 --- a/src/test/codegen/issue-32031.rs +++ b/src/test/codegen/issue-32031.rs @@ -5,7 +5,7 @@ #[no_mangle] pub struct F32(f32); -// CHECK: define float @add_newtype_f32(float %a, float %b) +// CHECK: define{{.*}}float @add_newtype_f32(float %a, float %b) #[inline(never)] #[no_mangle] pub fn add_newtype_f32(a: F32, b: F32) -> F32 { @@ -15,7 +15,7 @@ pub fn add_newtype_f32(a: F32, b: F32) -> F32 { #[no_mangle] pub struct F64(f64); -// CHECK: define double @add_newtype_f64(double %a, double %b) +// CHECK: define{{.*}}double @add_newtype_f64(double %a, double %b) #[inline(never)] #[no_mangle] pub fn add_newtype_f64(a: F64, b: F64) -> F64 { diff --git a/src/test/codegen/lto-removes-invokes.rs b/src/test/codegen/lto-removes-invokes.rs index b8f9f36c8e7..3979a97dc01 100644 --- a/src/test/codegen/lto-removes-invokes.rs +++ b/src/test/codegen/lto-removes-invokes.rs @@ -10,7 +10,7 @@ fn main() { fn foo() { let _a = Box::new(3); bar(); -// CHECK-LABEL: define void @foo +// CHECK-LABEL: define dso_local void @foo // CHECK: call void @bar } diff --git a/src/test/codegen/naked-functions.rs b/src/test/codegen/naked-functions.rs index 43a6be465bc..c8cd6923282 100644 --- a/src/test/codegen/naked-functions.rs +++ b/src/test/codegen/naked-functions.rs @@ -4,7 +4,7 @@ #![feature(naked_functions)] // CHECK: Function Attrs: naked -// CHECK-NEXT: define void @naked_empty() +// CHECK-NEXT: define{{.*}}void @naked_empty() #[no_mangle] #[naked] pub fn naked_empty() { @@ -15,14 +15,14 @@ pub fn naked_empty() { // CHECK: Function Attrs: naked #[no_mangle] #[naked] -// CHECK-NEXT: define void @naked_with_args(i{{[0-9]+( %a)?}}) +// CHECK-NEXT: define{{.*}}void @naked_with_args(i{{[0-9]+( %a)?}}) pub fn naked_with_args(a: isize) { // CHECK-NEXT: {{.+}}: // CHECK: ret void } // CHECK: Function Attrs: naked -// CHECK-NEXT: define i{{[0-9]+}} @naked_with_return() +// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_return() #[no_mangle] #[naked] pub fn naked_with_return() -> isize { @@ -32,7 +32,7 @@ pub fn naked_with_return() -> isize { } // CHECK: Function Attrs: naked -// CHECK-NEXT: define i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+( %a)?}}) +// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+( %a)?}}) #[no_mangle] #[naked] pub fn naked_with_args_and_return(a: isize) -> isize { diff --git a/src/test/codegen/optimize-attr-1.rs b/src/test/codegen/optimize-attr-1.rs index a8be10ba3ce..22abe06e7a9 100644 --- a/src/test/codegen/optimize-attr-1.rs +++ b/src/test/codegen/optimize-attr-1.rs @@ -6,7 +6,7 @@ #![feature(optimize_attribute)] #![crate_type="rlib"] -// CHECK-LABEL: define i32 @nothing +// CHECK-LABEL: define{{.*}}i32 @nothing // CHECK-SAME: [[NOTHING_ATTRS:#[0-9]+]] // NO-OPT: ret i32 4 // SIZE-OPT: ret i32 4 @@ -16,7 +16,7 @@ pub fn nothing() -> i32 { 2 + 2 } -// CHECK-LABEL: define i32 @size +// CHECK-LABEL: define{{.*}}i32 @size // CHECK-SAME: [[SIZE_ATTRS:#[0-9]+]] // NO-OPT: ret i32 6 // SIZE-OPT: ret i32 6 @@ -27,7 +27,7 @@ pub fn size() -> i32 { 3 + 3 } -// CHECK-LABEL: define i32 @speed +// CHECK-LABEL: define{{.*}}i32 @speed // NO-OPT-SAME: [[NOTHING_ATTRS]] // SPEED-OPT-SAME: [[NOTHING_ATTRS]] // SIZE-OPT-SAME: [[SPEED_ATTRS:#[0-9]+]] diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs index 847b94fac78..4ac637dc6f1 100644 --- a/src/test/codegen/repr-transparent-aggregates-1.rs +++ b/src/test/codegen/repr-transparent-aggregates-1.rs @@ -34,19 +34,19 @@ pub enum TeBigS { Variant(BigS), } -// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], %BigS* [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]]) +// CHECK: define{{.*}}void @test_BigS(%BigS* [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], %BigS* [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]]) #[no_mangle] pub extern "C" fn test_BigS(_: BigS) -> BigS { loop {} } -// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], %TsBigS* [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]]) +// CHECK: define{{.*}}void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], %TsBigS* [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]]) #[no_mangle] pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} } -// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], %TuBigS* [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]]) +// CHECK: define{{.*}}void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], %TuBigS* [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]]) #[no_mangle] pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} } -// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], %"TeBigS::Variant"* [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]]) +// CHECK: define{{.*}}void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], %"TeBigS::Variant"* [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]]) #[no_mangle] pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} } @@ -70,18 +70,18 @@ pub enum TeBigU { Variant(BigU), } -// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], %BigU* [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]]) +// CHECK: define{{.*}}void @test_BigU(%BigU* [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], %BigU* [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]]) #[no_mangle] pub extern "C" fn test_BigU(_: BigU) -> BigU { loop {} } -// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS1:.*]] sret(%TsBigU) [[BIGU_RET_ATTRS2:.*]], %TsBigU* [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]]) +// CHECK: define{{.*}}void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS1:.*]] sret(%TsBigU) [[BIGU_RET_ATTRS2:.*]], %TsBigU* [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]]) #[no_mangle] pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} } -// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2:.*]], %TuBigU* [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]]) +// CHECK: define{{.*}}void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2:.*]], %TuBigU* [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]]) #[no_mangle] pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} } -// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2:.*]], %"TeBigU::Variant"* [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]]) +// CHECK: define{{.*}}void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2:.*]], %"TeBigU::Variant"* [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]]) #[no_mangle] pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} } diff --git a/src/test/codegen/repr-transparent.rs b/src/test/codegen/repr-transparent.rs index 29997313511..7add522c158 100644 --- a/src/test/codegen/repr-transparent.rs +++ b/src/test/codegen/repr-transparent.rs @@ -17,21 +17,21 @@ pub struct Zst2(()); #[repr(transparent)] pub struct F32(f32); -// CHECK: define float @test_F32(float %_1) +// CHECK: define{{.*}}float @test_F32(float %_1) #[no_mangle] pub extern "C" fn test_F32(_: F32) -> F32 { loop {} } #[repr(transparent)] pub struct Ptr(*mut u8); -// CHECK: define i8* @test_Ptr(i8* %_1) +// CHECK: define{{.*}}i8* @test_Ptr(i8* %_1) #[no_mangle] pub extern "C" fn test_Ptr(_: Ptr) -> Ptr { loop {} } #[repr(transparent)] pub struct WithZst(u64, Zst1); -// CHECK: define i64 @test_WithZst(i64 %_1) +// CHECK: define{{.*}}i64 @test_WithZst(i64 %_1) #[no_mangle] pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} } @@ -39,14 +39,14 @@ pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} } pub struct WithZeroSizedArray(*const f32, [i8; 0]); // Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever. -// CHECK: define i32* @test_WithZeroSizedArray(i32* %_1) +// CHECK: define{{.*}}i32* @test_WithZeroSizedArray(i32* %_1) #[no_mangle] pub extern "C" fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} } #[repr(transparent)] pub struct Generic(T); -// CHECK: define double @test_Generic(double %_1) +// CHECK: define{{.*}}double @test_Generic(double %_1) #[no_mangle] pub extern "C" fn test_Generic(_: Generic) -> Generic { loop {} } @@ -56,14 +56,14 @@ pub struct GenericPlusZst(T, Zst2); #[repr(u8)] pub enum Bool { True, False, FileNotFound } -// CHECK: define{{( zeroext)?}} i8 @test_Gpz(i8{{( zeroext)?}} %_1) +// CHECK: define{{( dso_local)?}}{{( zeroext)?}} i8 @test_Gpz(i8{{( zeroext)?}} %_1) #[no_mangle] pub extern "C" fn test_Gpz(_: GenericPlusZst) -> GenericPlusZst { loop {} } #[repr(transparent)] pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>); -// CHECK: define i16* @test_LifetimePhantom(i16* %_1) +// CHECK: define{{.*}}i16* @test_LifetimePhantom(i16* %_1) #[no_mangle] pub extern "C" fn test_LifetimePhantom(_: LifetimePhantom) -> LifetimePhantom { loop {} } @@ -73,28 +73,28 @@ pub struct UnitPhantom { val: T, unit: PhantomData } pub struct Px; -// CHECK: define float @test_UnitPhantom(float %_1) +// CHECK: define{{.*}}float @test_UnitPhantom(float %_1) #[no_mangle] pub extern "C" fn test_UnitPhantom(_: UnitPhantom) -> UnitPhantom { loop {} } #[repr(transparent)] pub struct TwoZsts(Zst1, i8, Zst2); -// CHECK: define{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %_1) +// CHECK: define{{( dso_local)?}}{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %_1) #[no_mangle] pub extern "C" fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} } #[repr(transparent)] pub struct Nested1(Zst2, Generic); -// CHECK: define double @test_Nested1(double %_1) +// CHECK: define{{.*}}double @test_Nested1(double %_1) #[no_mangle] pub extern "C" fn test_Nested1(_: Nested1) -> Nested1 { loop {} } #[repr(transparent)] pub struct Nested2(Nested1, Zst1); -// CHECK: define double @test_Nested2(double %_1) +// CHECK: define{{.*}}double @test_Nested2(double %_1) #[no_mangle] pub extern "C" fn test_Nested2(_: Nested2) -> Nested2 { loop {} } @@ -104,7 +104,7 @@ struct f32x4(f32, f32, f32, f32); #[repr(transparent)] pub struct Vector(f32x4); -// CHECK: define <4 x float> @test_Vector(<4 x float> %_1) +// CHECK: define{{.*}}<4 x float> @test_Vector(<4 x float> %_1) #[no_mangle] pub extern "C" fn test_Vector(_: Vector) -> Vector { loop {} } @@ -114,7 +114,7 @@ impl Mirror for T { type It = Self; } #[repr(transparent)] pub struct StructWithProjection(::It); -// CHECK: define float @test_Projection(float %_1) +// CHECK: define{{.*}}float @test_Projection(float %_1) #[no_mangle] pub extern "C" fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} } @@ -123,7 +123,7 @@ pub enum EnumF32 { Variant(F32) } -// CHECK: define float @test_EnumF32(float %_1) +// CHECK: define{{.*}}float @test_EnumF32(float %_1) #[no_mangle] pub extern "C" fn test_EnumF32(_: EnumF32) -> EnumF32 { loop {} } @@ -132,7 +132,7 @@ pub enum EnumF32WithZsts { Variant(Zst1, F32, Zst2) } -// CHECK: define float @test_EnumF32WithZsts(float %_1) +// CHECK: define{{.*}}float @test_EnumF32WithZsts(float %_1) #[no_mangle] pub extern "C" fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { loop {} } @@ -141,7 +141,7 @@ pub union UnionF32 { field: F32, } -// CHECK: define float @test_UnionF32(float %_1) +// CHECK: define{{.*}}float @test_UnionF32(float %_1) #[no_mangle] pub extern "C" fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} } @@ -152,7 +152,7 @@ pub union UnionF32WithZsts { zst2: Zst2, } -// CHECK: define float @test_UnionF32WithZsts(float %_1) +// CHECK: define{{.*}}float @test_UnionF32WithZsts(float %_1) #[no_mangle] pub extern "C" fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts { loop {} } diff --git a/src/test/codegen/sanitizer-recover.rs b/src/test/codegen/sanitizer-recover.rs index 433d32abd37..7ce0fa0a20f 100644 --- a/src/test/codegen/sanitizer-recover.rs +++ b/src/test/codegen/sanitizer-recover.rs @@ -16,27 +16,27 @@ // MSAN-RECOVER: @__msan_keep_going = weak_odr {{.*}}constant i32 1 // MSAN-RECOVER-LTO: @__msan_keep_going = weak_odr {{.*}}constant i32 1 -// ASAN-LABEL: define i32 @penguin( +// ASAN-LABEL: define dso_local i32 @penguin( // ASAN: call void @__asan_report_load4(i64 %0) // ASAN: unreachable // ASAN: } // -// ASAN-RECOVER-LABEL: define i32 @penguin( +// ASAN-RECOVER-LABEL: define dso_local i32 @penguin( // ASAN-RECOVER: call void @__asan_report_load4_noabort( // ASAN-RECOVER-NOT: unreachable // ASAN: } // -// MSAN-LABEL: define i32 @penguin( +// MSAN-LABEL: define dso_local i32 @penguin( // MSAN: call void @__msan_warning{{(_with_origin_noreturn\(i32 0\)|_noreturn\(\))}} // MSAN: unreachable // MSAN: } // -// MSAN-RECOVER-LABEL: define i32 @penguin( +// MSAN-RECOVER-LABEL: define dso_local i32 @penguin( // MSAN-RECOVER: call void @__msan_warning{{(_with_origin\(i32 0\)|\(\))}} // MSAN-RECOVER-NOT: unreachable // MSAN-RECOVER: } // -// MSAN-RECOVER-LTO-LABEL: define i32 @penguin( +// MSAN-RECOVER-LTO-LABEL: define dso_local i32 @penguin( // MSAN-RECOVER-LTO: call void @__msan_warning{{(_with_origin\(i32 0\)|\(\))}} // MSAN-RECOVER-LTO-NOT: unreachable // MSAN-RECOVER-LTO: } diff --git a/src/test/codegen/scalar-pair-bool.rs b/src/test/codegen/scalar-pair-bool.rs index 4704c8ad797..473272158d0 100644 --- a/src/test/codegen/scalar-pair-bool.rs +++ b/src/test/codegen/scalar-pair-bool.rs @@ -2,25 +2,25 @@ #![crate_type = "lib"] -// CHECK: define { i8, i8 } @pair_bool_bool(i1 zeroext %pair.0, i1 zeroext %pair.1) +// CHECK: define{{.*}}{ i8, i8 } @pair_bool_bool(i1 zeroext %pair.0, i1 zeroext %pair.1) #[no_mangle] pub fn pair_bool_bool(pair: (bool, bool)) -> (bool, bool) { pair } -// CHECK: define { i8, i32 } @pair_bool_i32(i1 zeroext %pair.0, i32 %pair.1) +// CHECK: define{{.*}}{ i8, i32 } @pair_bool_i32(i1 zeroext %pair.0, i32 %pair.1) #[no_mangle] pub fn pair_bool_i32(pair: (bool, i32)) -> (bool, i32) { pair } -// CHECK: define { i32, i8 } @pair_i32_bool(i32 %pair.0, i1 zeroext %pair.1) +// CHECK: define{{.*}}{ i32, i8 } @pair_i32_bool(i32 %pair.0, i1 zeroext %pair.1) #[no_mangle] pub fn pair_i32_bool(pair: (i32, bool)) -> (i32, bool) { pair } -// CHECK: define { i8, i8 } @pair_and_or(i1 zeroext %_1.0, i1 zeroext %_1.1) +// CHECK: define{{.*}}{ i8, i8 } @pair_and_or(i1 zeroext %_1.0, i1 zeroext %_1.1) #[no_mangle] pub fn pair_and_or((a, b): (bool, bool)) -> (bool, bool) { // Make sure it can operate directly on the unpacked args @@ -30,7 +30,7 @@ pub fn pair_and_or((a, b): (bool, bool)) -> (bool, bool) { (a && b, a || b) } -// CHECK: define void @pair_branches(i1 zeroext %_1.0, i1 zeroext %_1.1) +// CHECK: define{{.*}}void @pair_branches(i1 zeroext %_1.0, i1 zeroext %_1.1) #[no_mangle] pub fn pair_branches((a, b): (bool, bool)) { // Make sure it can branch directly on the unpacked bool args diff --git a/src/test/codegen/staticlib-external-inline-fns.rs b/src/test/codegen/staticlib-external-inline-fns.rs index 8876ab7376a..432c063e826 100644 --- a/src/test/codegen/staticlib-external-inline-fns.rs +++ b/src/test/codegen/staticlib-external-inline-fns.rs @@ -2,42 +2,42 @@ #![crate_type = "staticlib"] -// CHECK: define void @a() +// CHECK: define{{.*}}void @a() #[no_mangle] #[inline] pub extern "C" fn a() {} -// CHECK: define void @b() +// CHECK: define{{.*}}void @b() #[export_name = "b"] #[inline] pub extern "C" fn b() {} -// CHECK: define void @c() +// CHECK: define{{.*}}void @c() #[no_mangle] #[inline] extern "C" fn c() {} -// CHECK: define void @d() +// CHECK: define{{.*}}void @d() #[export_name = "d"] #[inline] extern "C" fn d() {} -// CHECK: define void @e() +// CHECK: define{{.*}}void @e() #[no_mangle] #[inline(always)] pub extern "C" fn e() {} -// CHECK: define void @f() +// CHECK: define{{.*}}void @f() #[export_name = "f"] #[inline(always)] pub extern "C" fn f() {} -// CHECK: define void @g() +// CHECK: define{{.*}}void @g() #[no_mangle] #[inline(always)] extern "C" fn g() {} -// CHECK: define void @h() +// CHECK: define{{.*}}void @h() #[export_name = "h"] #[inline(always)] extern "C" fn h() {} diff --git a/src/test/codegen/transmute-scalar.rs b/src/test/codegen/transmute-scalar.rs index 78b4aa3fb88..e9584929f3a 100644 --- a/src/test/codegen/transmute-scalar.rs +++ b/src/test/codegen/transmute-scalar.rs @@ -5,7 +5,7 @@ // FIXME(eddyb) all of these tests show memory stores and loads, even after a // scalar `bitcast`, more special-casing is required to remove `alloca` usage. -// CHECK: define i32 @f32_to_bits(float %x) +// CHECK-LABEL: define{{.*}}i32 @f32_to_bits(float %x) // CHECK: %2 = bitcast float %x to i32 // CHECK-NEXT: store i32 %2, i32* %0 // CHECK-NEXT: %3 = load i32, i32* %0 @@ -15,7 +15,7 @@ pub fn f32_to_bits(x: f32) -> u32 { unsafe { std::mem::transmute(x) } } -// CHECK: define i8 @bool_to_byte(i1 zeroext %b) +// CHECK-LABEL: define{{.*}}i8 @bool_to_byte(i1 zeroext %b) // CHECK: %1 = zext i1 %b to i8 // CHECK-NEXT: store i8 %1, i8* %0 // CHECK-NEXT: %2 = load i8, i8* %0 @@ -25,7 +25,7 @@ pub fn bool_to_byte(b: bool) -> u8 { unsafe { std::mem::transmute(b) } } -// CHECK: define zeroext i1 @byte_to_bool(i8 %byte) +// CHECK-LABEL: define{{.*}}zeroext i1 @byte_to_bool(i8 %byte) // CHECK: %1 = trunc i8 %byte to i1 // CHECK-NEXT: %2 = zext i1 %1 to i8 // CHECK-NEXT: store i8 %2, i8* %0 @@ -37,7 +37,7 @@ pub unsafe fn byte_to_bool(byte: u8) -> bool { std::mem::transmute(byte) } -// CHECK: define i8* @ptr_to_ptr(i16* %p) +// CHECK-LABEL: define{{.*}}i8* @ptr_to_ptr(i16* %p) // CHECK: %2 = bitcast i16* %p to i8* // CHECK-NEXT: store i8* %2, i8** %0 // CHECK-NEXT: %3 = load i8*, i8** %0 @@ -54,7 +54,7 @@ pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 { // Tests below show the non-special-cased behavior (with the possible // future special-cased instructions in the "NOTE(eddyb)" comments). -// CHECK: define [[USIZE:i[0-9]+]] @ptr_to_int(i16* %p) +// CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int(i16* %p) // NOTE(eddyb) see above, the following two CHECK lines should ideally be this: // %2 = ptrtoint i16* %p to [[USIZE]] @@ -69,7 +69,7 @@ pub fn ptr_to_int(p: *mut u16) -> usize { unsafe { std::mem::transmute(p) } } -// CHECK: define i16* @int_to_ptr([[USIZE]] %i) +// CHECK: define{{.*}}i16* @int_to_ptr([[USIZE]] %i) // NOTE(eddyb) see above, the following two CHECK lines should ideally be this: // %2 = inttoptr [[USIZE]] %i to i16* diff --git a/src/test/codegen/unwind-extern-imports.rs b/src/test/codegen/unwind-extern-imports.rs index a2ba24aca25..e28397eb139 100644 --- a/src/test/codegen/unwind-extern-imports.rs +++ b/src/test/codegen/unwind-extern-imports.rs @@ -6,28 +6,28 @@ extern "C" { // CHECK: Function Attrs:{{.*}}nounwind -// CHECK-NEXT: declare void @extern_fn +// CHECK-NEXT: declare{{.*}}void @extern_fn fn extern_fn(); // CHECK-NOT: Function Attrs:{{.*}}nounwind -// CHECK: declare void @unwinding_extern_fn +// CHECK: declare{{.*}}void @unwinding_extern_fn #[unwind(allowed)] fn unwinding_extern_fn(); // CHECK-NOT: nounwind -// CHECK: declare void @aborting_extern_fn +// CHECK: declare{{.*}}void @aborting_extern_fn #[unwind(aborts)] fn aborting_extern_fn(); // FIXME: we want to have the attribute here } extern "Rust" { // CHECK-NOT: nounwind -// CHECK: declare void @rust_extern_fn +// CHECK: declare{{.*}}void @rust_extern_fn fn rust_extern_fn(); // CHECK-NOT: nounwind -// CHECK: declare void @rust_unwinding_extern_fn +// CHECK: declare{{.*}}void @rust_unwinding_extern_fn #[unwind(allowed)] fn rust_unwinding_extern_fn(); // CHECK-NOT: nounwind -// CHECK: declare void @rust_aborting_extern_fn +// CHECK: declare{{.*}}void @rust_aborting_extern_fn #[unwind(aborts)] fn rust_aborting_extern_fn(); // FIXME: we want to have the attribute here } diff --git a/src/test/codegen/var-names.rs b/src/test/codegen/var-names.rs index 3140a7c6b6c..8f1b038708e 100644 --- a/src/test/codegen/var-names.rs +++ b/src/test/codegen/var-names.rs @@ -2,7 +2,7 @@ #![crate_type = "lib"] -// CHECK-LABEL: define i32 @test(i32 %a, i32 %b) +// CHECK-LABEL: define{{.*}}i32 @test(i32 %a, i32 %b) #[no_mangle] pub fn test(a: u32, b: u32) -> u32 { let c = a + b; From 64af7eae1ea25102c8197f9f190ee65ddc4f8a10 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sun, 7 Feb 2021 23:47:03 +0200 Subject: [PATCH 302/370] Move SanitizerSet to rustc_target --- compiler/rustc_codegen_llvm/src/attributes.rs | 4 +- compiler/rustc_codegen_llvm/src/back/write.rs | 4 +- compiler/rustc_codegen_llvm/src/base.rs | 3 +- compiler/rustc_codegen_ssa/src/back/link.rs | 4 +- .../src/back/symbol_export.rs | 3 +- compiler/rustc_codegen_ssa/src/back/write.rs | 4 +- compiler/rustc_interface/src/tests.rs | 4 +- .../src/middle/codegen_fn_attrs.rs | 2 +- compiler/rustc_session/src/config.rs | 67 +--------- compiler/rustc_session/src/lib.rs | 2 - compiler/rustc_session/src/options.rs | 2 +- compiler/rustc_session/src/session.rs | 4 +- compiler/rustc_target/src/spec/mod.rs | 119 +++++++++++++----- compiler/rustc_typeck/src/collect.rs | 3 +- 14 files changed, 109 insertions(+), 116 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 64ebe585dd8..594d42c9366 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -11,9 +11,9 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt}; -use rustc_session::config::{OptLevel, SanitizerSet}; +use rustc_session::config::OptLevel; use rustc_session::Session; -use rustc_target::spec::StackProbeType; +use rustc_target::spec::{SanitizerSet, StackProbeType}; use crate::attributes; use crate::llvm::AttributePlace::Function; diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 085935b94df..b3551177323 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -23,11 +23,11 @@ use rustc_fs_util::{link_or_copy, path_to_c_string}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; -use rustc_session::config::{self, Lto, OutputType, Passes, SanitizerSet, SwitchWithOptPath}; +use rustc_session::config::{self, Lto, OutputType, Passes, SwitchWithOptPath}; use rustc_session::Session; use rustc_span::symbol::sym; use rustc_span::InnerSpan; -use rustc_target::spec::{CodeModel, RelocModel, SplitDebuginfo}; +use rustc_target::spec::{CodeModel, RelocModel, SanitizerSet, SplitDebuginfo}; use tracing::debug; use libc::{c_char, c_int, c_uint, c_void, size_t}; diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index db8abdd9b13..6f6c649bb0b 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -32,8 +32,9 @@ use rustc_middle::middle::cstore::EncodedMetadata; use rustc_middle::middle::exported_symbols; use rustc_middle::mir::mono::{Linkage, Visibility}; use rustc_middle::ty::TyCtxt; -use rustc_session::config::{DebugInfo, SanitizerSet}; +use rustc_session::config::DebugInfo; use rustc_span::symbol::Symbol; +use rustc_target::spec::SanitizerSet; use std::ffi::CString; use std::time::Instant; diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 686ebc13ea3..9eaabfe04a9 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -6,7 +6,7 @@ use rustc_hir::def_id::CrateNum; use rustc_middle::middle::cstore::{EncodedMetadata, LibSource}; use rustc_middle::middle::dependency_format::Linkage; use rustc_session::config::{self, CFGuard, CrateType, DebugInfo}; -use rustc_session::config::{OutputFilenames, OutputType, PrintRequest, SanitizerSet}; +use rustc_session::config::{OutputFilenames, OutputType, PrintRequest}; use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename}; use rustc_session::search_paths::PathKind; use rustc_session::utils::NativeLibKind; @@ -16,7 +16,7 @@ use rustc_session::{filesearch, Session}; use rustc_span::symbol::Symbol; use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback}; use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo}; -use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, Target}; +use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target}; use super::archive::ArchiveBuilder; use super::command::Command; diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index abad8281d3a..b8f277c8ff5 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -15,7 +15,8 @@ use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::Instance; use rustc_middle::ty::{SymbolName, TyCtxt}; -use rustc_session::config::{CrateType, SanitizerSet}; +use rustc_session::config::CrateType; +use rustc_target::spec::SanitizerSet; pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { crates_export_threshold(&tcx.sess.crate_types()) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 7a8d8fb1304..b0324236373 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -27,12 +27,12 @@ use rustc_middle::middle::exported_symbols::SymbolExportLevel; use rustc_middle::ty::TyCtxt; use rustc_session::cgu_reuse_tracker::CguReuseTracker; use rustc_session::config::{self, CrateType, Lto, OutputFilenames, OutputType}; -use rustc_session::config::{Passes, SanitizerSet, SwitchWithOptPath}; +use rustc_session::config::{Passes, SwitchWithOptPath}; use rustc_session::Session; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{BytePos, FileName, InnerSpan, Pos, Span}; -use rustc_target::spec::{MergeFunctions, PanicStrategy}; +use rustc_target::spec::{MergeFunctions, PanicStrategy, SanitizerSet}; use std::any::Any; use std::fs; diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 1653d3bdba1..2270b2b33e2 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -8,7 +8,7 @@ use rustc_session::config::{build_configuration, build_session_options, to_crate use rustc_session::config::{rustc_optgroups, ErrorOutputType, ExternLocation, Options, Passes}; use rustc_session::config::{CFGuard, ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath}; use rustc_session::config::{ - Externs, OutputType, OutputTypes, SanitizerSet, SymbolManglingVersion, WasiExecModel, + Externs, OutputType, OutputTypes, SymbolManglingVersion, WasiExecModel, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; @@ -18,7 +18,7 @@ use rustc_span::edition::{Edition, DEFAULT_EDITION}; use rustc_span::symbol::sym; use rustc_span::SourceFileHashAlgorithm; use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy}; -use rustc_target::spec::{RelocModel, RelroLevel, SplitDebuginfo, TlsModel}; +use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, TlsModel}; use std::collections::{BTreeMap, BTreeSet}; use std::iter::FromIterator; use std::num::NonZeroUsize; diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 5f2ffda642c..bfca6a5f574 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -1,7 +1,7 @@ use crate::mir::mono::Linkage; use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr}; -use rustc_session::config::SanitizerSet; use rustc_span::symbol::Symbol; +use rustc_target::spec::SanitizerSet; #[derive(Clone, TyEncodable, TyDecodable, HashStable, Debug)] pub struct CodegenFnAttrs { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 3692219cb6d..e39b9b9b33e 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -10,7 +10,6 @@ use crate::{early_error, early_warn, Session}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::impl_stable_hash_via_hash; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_target::abi::{Align, TargetDataLayout}; use rustc_target::spec::{SplitDebuginfo, Target, TargetTriple}; @@ -36,66 +35,6 @@ use std::iter::{self, FromIterator}; use std::path::{Path, PathBuf}; use std::str::{self, FromStr}; -bitflags! { - #[derive(Default, Encodable, Decodable)] - pub struct SanitizerSet: u8 { - const ADDRESS = 1 << 0; - const LEAK = 1 << 1; - const MEMORY = 1 << 2; - const THREAD = 1 << 3; - const HWADDRESS = 1 << 4; - } -} - -/// Formats a sanitizer set as a comma separated list of sanitizers' names. -impl fmt::Display for SanitizerSet { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut first = true; - for s in *self { - let name = match s { - SanitizerSet::ADDRESS => "address", - SanitizerSet::LEAK => "leak", - SanitizerSet::MEMORY => "memory", - SanitizerSet::THREAD => "thread", - SanitizerSet::HWADDRESS => "hwaddress", - _ => panic!("unrecognized sanitizer {:?}", s), - }; - if !first { - f.write_str(",")?; - } - f.write_str(name)?; - first = false; - } - Ok(()) - } -} - -impl IntoIterator for SanitizerSet { - type Item = SanitizerSet; - type IntoIter = std::vec::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - [ - SanitizerSet::ADDRESS, - SanitizerSet::LEAK, - SanitizerSet::MEMORY, - SanitizerSet::THREAD, - SanitizerSet::HWADDRESS, - ] - .iter() - .copied() - .filter(|&s| self.contains(s)) - .collect::>() - .into_iter() - } -} - -impl HashStable for SanitizerSet { - fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - self.bits().hash_stable(ctx, hasher); - } -} - /// The different settings that the `-Z strip` flag can have. #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub enum Strip { @@ -2308,8 +2247,8 @@ impl PpMode { crate mod dep_tracking { use super::{ CFGuard, CrateType, DebugInfo, ErrorOutputType, InstrumentCoverage, LinkerPluginLto, - LtoCli, OptLevel, OutputTypes, Passes, SanitizerSet, SourceFileHashAlgorithm, - SwitchWithOptPath, SymbolManglingVersion, TrimmedDefPaths, + LtoCli, OptLevel, OutputTypes, Passes, SourceFileHashAlgorithm, SwitchWithOptPath, + SymbolManglingVersion, TrimmedDefPaths, }; use crate::lint; use crate::options::WasiExecModel; @@ -2317,7 +2256,7 @@ crate mod dep_tracking { use rustc_feature::UnstableFeatures; use rustc_span::edition::Edition; use rustc_target::spec::{CodeModel, MergeFunctions, PanicStrategy, RelocModel}; - use rustc_target::spec::{RelroLevel, SplitDebuginfo, TargetTriple, TlsModel}; + use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, TargetTriple, TlsModel}; use std::collections::hash_map::DefaultHasher; use std::collections::BTreeMap; use std::hash::Hash; diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 95d17125a11..7971f7ef9ef 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -3,8 +3,6 @@ #![cfg_attr(bootstrap, feature(or_patterns))] #![recursion_limit = "256"] -#[macro_use] -extern crate bitflags; #[macro_use] extern crate rustc_macros; diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index e50972e59a7..623062dd569 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -5,7 +5,7 @@ use crate::lint; use crate::search_paths::SearchPath; use crate::utils::NativeLibKind; -use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy}; +use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy, SanitizerSet}; use rustc_target::spec::{RelocModel, RelroLevel, SplitDebuginfo, TargetTriple, TlsModel}; use rustc_feature::UnstableFeatures; diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 693f427d7af..fce34cf7247 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1,7 +1,7 @@ use crate::cgu_reuse_tracker::CguReuseTracker; use crate::code_stats::CodeStats; pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo}; -use crate::config::{self, CrateType, OutputType, PrintRequest, SanitizerSet, SwitchWithOptPath}; +use crate::config::{self, CrateType, OutputType, PrintRequest, SwitchWithOptPath}; use crate::filesearch; use crate::lint::{self, LintId}; use crate::parse::ParseSess; @@ -28,7 +28,7 @@ use rustc_span::source_map::{FileLoader, MultiSpan, RealFileLoader, SourceMap, S use rustc_span::{sym, SourceFileHashAlgorithm, Symbol}; use rustc_target::asm::InlineAsmArch; use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel}; -use rustc_target::spec::{SplitDebuginfo, Target, TargetTriple, TlsModel}; +use rustc_target::spec::{SanitizerSet, SplitDebuginfo, Target, TargetTriple, TlsModel}; use std::cell::{self, RefCell}; use std::env; diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index ddfd8262522..b68369b4434 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -37,6 +37,7 @@ use crate::abi::Endian; use crate::spec::abi::{lookup as lookup_abi, Abi}; use crate::spec::crt_objects::{CrtObjects, CrtObjectsFallback}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_serialize::json::{Json, ToJson}; use rustc_span::symbol::{sym, Symbol}; use std::collections::BTreeMap; @@ -511,38 +512,6 @@ impl fmt::Display for SplitDebuginfo { } } -macro_rules! supported_targets { - ( $(($( $triple:literal, )+ $module:ident ),)+ ) => { - $(mod $module;)+ - - /// List of supported targets - pub const TARGETS: &[&str] = &[$($($triple),+),+]; - - fn load_builtin(target: &str) -> Option { - let mut t = match target { - $( $($triple)|+ => $module::target(), )+ - _ => return None, - }; - t.is_builtin = true; - debug!("got builtin target: {:?}", t); - Some(t) - } - - #[cfg(test)] - mod tests { - mod tests_impl; - - // Cannot put this into a separate file without duplication, make an exception. - $( - #[test] // `#[test]` - fn $module() { - tests_impl::test_target(super::$module::target()); - } - )+ - } - }; -} - #[derive(Clone, Debug, PartialEq, Eq)] pub enum StackProbeType { /// Don't emit any stack probes. @@ -620,6 +589,92 @@ impl ToJson for StackProbeType { } } +bitflags::bitflags! { + #[derive(Default, Encodable, Decodable)] + pub struct SanitizerSet: u8 { + const ADDRESS = 1 << 0; + const LEAK = 1 << 1; + const MEMORY = 1 << 2; + const THREAD = 1 << 3; + const HWADDRESS = 1 << 4; + } +} + +/// Formats a sanitizer set as a comma separated list of sanitizers' names. +impl fmt::Display for SanitizerSet { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut first = true; + for s in *self { + let name = match s { + SanitizerSet::ADDRESS => "address", + SanitizerSet::LEAK => "leak", + SanitizerSet::MEMORY => "memory", + SanitizerSet::THREAD => "thread", + SanitizerSet::HWADDRESS => "hwaddress", + _ => panic!("unrecognized sanitizer {:?}", s), + }; + if !first { + f.write_str(",")?; + } + f.write_str(name)?; + first = false; + } + Ok(()) + } +} + +impl IntoIterator for SanitizerSet { + type Item = SanitizerSet; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + [SanitizerSet::ADDRESS, SanitizerSet::LEAK, SanitizerSet::MEMORY, SanitizerSet::THREAD, SanitizerSet::HWADDRESS] + .iter() + .copied() + .filter(|&s| self.contains(s)) + .collect::>() + .into_iter() + } +} + +impl HashStable for SanitizerSet { + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + self.bits().hash_stable(ctx, hasher); + } +} + +macro_rules! supported_targets { + ( $(($( $triple:literal, )+ $module:ident ),)+ ) => { + $(mod $module;)+ + + /// List of supported targets + pub const TARGETS: &[&str] = &[$($($triple),+),+]; + + fn load_builtin(target: &str) -> Option { + let mut t = match target { + $( $($triple)|+ => $module::target(), )+ + _ => return None, + }; + t.is_builtin = true; + debug!("got builtin target: {:?}", t); + Some(t) + } + + #[cfg(test)] + mod tests { + mod tests_impl; + + // Cannot put this into a separate file without duplication, make an exception. + $( + #[test] // `#[test]` + fn $module() { + tests_impl::test_target(super::$module::target()); + } + )+ + } + }; +} + supported_targets! { ("x86_64-unknown-linux-gnu", x86_64_unknown_linux_gnu), ("x86_64-unknown-linux-gnux32", x86_64_unknown_linux_gnux32), diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index afe52c97733..05ba8811cc2 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -43,12 +43,11 @@ use rustc_middle::ty::util::Discr; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt}; use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness}; -use rustc_session::config::SanitizerSet; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::spec::abi; +use rustc_target::spec::{abi, SanitizerSet}; use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName; use std::iter; From 16c1d0ae0656a5aa929fb0a9ab5c0c740c950ded Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Mon, 8 Feb 2021 00:49:00 +0200 Subject: [PATCH 303/370] Maintain supported sanitizers as a target property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds an additional target property – `supported_sanitizers`, and replaces the hardcoded allowlists in argument parsing to use this new property. Fixes #81802 --- compiler/rustc_session/src/session.rs | 69 +++++-------------- .../src/spec/aarch64_apple_darwin.rs | 5 +- .../rustc_target/src/spec/aarch64_fuchsia.rs | 3 +- .../src/spec/aarch64_linux_android.rs | 3 +- .../src/spec/aarch64_unknown_linux_gnu.rs | 7 +- compiler/rustc_target/src/spec/mod.rs | 10 ++- .../src/spec/x86_64_apple_darwin.rs | 3 +- .../rustc_target/src/spec/x86_64_fuchsia.rs | 3 +- .../src/spec/x86_64_unknown_freebsd.rs | 3 +- .../src/spec/x86_64_unknown_linux_gnu.rs | 4 +- src/test/ui/sanitize/unsupported-target.rs | 3 +- .../ui/sanitize/unsupported-target.stderr | 2 +- 12 files changed, 49 insertions(+), 66 deletions(-) diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index fce34cf7247..3488efacd11 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1517,59 +1517,22 @@ fn validate_commandline_args_with_session_available(sess: &Session) { ); } - const ASAN_SUPPORTED_TARGETS: &[&str] = &[ - "aarch64-apple-darwin", - "aarch64-fuchsia", - "aarch64-unknown-linux-gnu", - "x86_64-apple-darwin", - "x86_64-fuchsia", - "x86_64-unknown-freebsd", - "x86_64-unknown-linux-gnu", - ]; - const LSAN_SUPPORTED_TARGETS: &[&str] = &[ - "aarch64-apple-darwin", - "aarch64-unknown-linux-gnu", - "x86_64-apple-darwin", - "x86_64-unknown-linux-gnu", - ]; - const MSAN_SUPPORTED_TARGETS: &[&str] = - &["aarch64-unknown-linux-gnu", "x86_64-unknown-freebsd", "x86_64-unknown-linux-gnu"]; - const TSAN_SUPPORTED_TARGETS: &[&str] = &[ - "aarch64-apple-darwin", - "aarch64-unknown-linux-gnu", - "x86_64-apple-darwin", - "x86_64-unknown-freebsd", - "x86_64-unknown-linux-gnu", - ]; - const HWASAN_SUPPORTED_TARGETS: &[&str] = - &["aarch64-linux-android", "aarch64-unknown-linux-gnu"]; - - // Sanitizers can only be used on some tested platforms. - for s in sess.opts.debugging_opts.sanitizer { - let supported_targets = match s { - SanitizerSet::ADDRESS => ASAN_SUPPORTED_TARGETS, - SanitizerSet::LEAK => LSAN_SUPPORTED_TARGETS, - SanitizerSet::MEMORY => MSAN_SUPPORTED_TARGETS, - SanitizerSet::THREAD => TSAN_SUPPORTED_TARGETS, - SanitizerSet::HWADDRESS => HWASAN_SUPPORTED_TARGETS, - _ => panic!("unrecognized sanitizer {}", s), - }; - if !supported_targets.contains(&&*sess.opts.target_triple.triple()) { - sess.err(&format!( - "`-Zsanitizer={}` only works with targets: {}", - s, - supported_targets.join(", ") - )); - } - let conflicting = sess.opts.debugging_opts.sanitizer - s; - if !conflicting.is_empty() { - sess.err(&format!( - "`-Zsanitizer={}` is incompatible with `-Zsanitizer={}`", - s, conflicting, - )); - // Don't report additional errors. - break; - } + // Sanitizers can only be used on platforms that we know have working sanitizer codegen. + let supported_sanitizers = sess.target.options.supported_sanitizers; + let unsupported_sanitizers = sess.opts.debugging_opts.sanitizer - supported_sanitizers; + match unsupported_sanitizers.into_iter().count() { + 0 => {} + 1 => sess + .err(&format!("{} sanitizer is not supported for this target", unsupported_sanitizers)), + _ => sess.err(&format!( + "{} sanitizers are not supported for this target", + unsupported_sanitizers + )), + } + // Cannot mix and match sanitizers. + let mut sanitizer_iter = sess.opts.debugging_opts.sanitizer.into_iter(); + if let (Some(first), Some(second)) = (sanitizer_iter.next(), sanitizer_iter.next()) { + sess.err(&format!("`-Zsanitizer={}` is incompatible with `-Zsanitizer={}`", first, second)); } } diff --git a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs index 7de809f7622..feadd4e891c 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs @@ -1,11 +1,12 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::apple_base::opts("macos"); base.cpu = "apple-a12".to_string(); base.max_atomic_width = Some(128); - base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]); + base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD; + base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]); base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); // Clang automatically chooses a more specific target based on diff --git a/compiler/rustc_target/src/spec/aarch64_fuchsia.rs b/compiler/rustc_target/src/spec/aarch64_fuchsia.rs index 1252741f979..c9cb21f1eb1 100644 --- a/compiler/rustc_target/src/spec/aarch64_fuchsia.rs +++ b/compiler/rustc_target/src/spec/aarch64_fuchsia.rs @@ -1,8 +1,9 @@ -use crate::spec::{Target, TargetOptions}; +use crate::spec::{SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::fuchsia_base::opts(); base.max_atomic_width = Some(128); + base.supported_sanitizers = SanitizerSet::ADDRESS; Target { llvm_target: "aarch64-fuchsia".to_string(), diff --git a/compiler/rustc_target/src/spec/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/aarch64_linux_android.rs index fa6108df206..eaf3a2dbcf8 100644 --- a/compiler/rustc_target/src/spec/aarch64_linux_android.rs +++ b/compiler/rustc_target/src/spec/aarch64_linux_android.rs @@ -1,4 +1,4 @@ -use crate::spec::{Target, TargetOptions}; +use crate::spec::{SanitizerSet, Target, TargetOptions}; // See https://developer.android.com/ndk/guides/abis.html#arm64-v8a // for target ABI requirements. @@ -9,6 +9,7 @@ pub fn target() -> Target { // As documented in http://developer.android.com/ndk/guides/cpu-features.html // the neon (ASIMD) and FP must exist on all android aarch64 targets. base.features = "+neon,+fp-armv8".to_string(); + base.supported_sanitizers = SanitizerSet::HWADDRESS; Target { llvm_target: "aarch64-linux-android".to_string(), pointer_width: 64, diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs index 58c72af4e76..a07cd7db889 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs @@ -1,8 +1,13 @@ -use crate::spec::{Target, TargetOptions}; +use crate::spec::{SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.max_atomic_width = Some(128); + base.supported_sanitizers = SanitizerSet::ADDRESS + | SanitizerSet::LEAK + | SanitizerSet::MEMORY + | SanitizerSet::THREAD + | SanitizerSet::HWADDRESS; Target { llvm_target: "aarch64-unknown-linux-gnu".to_string(), diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index b68369b4434..390e5332c00 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -614,7 +614,7 @@ impl fmt::Display for SanitizerSet { _ => panic!("unrecognized sanitizer {:?}", s), }; if !first { - f.write_str(",")?; + f.write_str(", ")?; } f.write_str(name)?; first = false; @@ -1219,6 +1219,13 @@ pub struct TargetOptions { /// How to handle split debug information, if at all. Specifying `None` has /// target-specific meaning. pub split_debuginfo: SplitDebuginfo, + + /// The sanitizers supported by this target + /// + /// Note that the support here is at a codegen level. If the machine code with sanitizer + /// enabled can generated on this target, but the necessary supporting libraries are not + /// distributed with the target, the sanitizer should still appear in this list for the target. + pub supported_sanitizers: SanitizerSet, } impl Default for TargetOptions { @@ -1320,6 +1327,7 @@ impl Default for TargetOptions { eh_frame_header: true, has_thumb_interworking: false, split_debuginfo: SplitDebuginfo::Off, + supported_sanitizers: SanitizerSet::empty(), } } } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs index 8c40baccda8..c82359223da 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::apple_base::opts("macos"); @@ -11,6 +11,7 @@ pub fn target() -> Target { ); base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD; // Clang automatically chooses a more specific target based on // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work diff --git a/compiler/rustc_target/src/spec/x86_64_fuchsia.rs b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs index a39e7f8c341..99acc7c207b 100644 --- a/compiler/rustc_target/src/spec/x86_64_fuchsia.rs +++ b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs @@ -1,10 +1,11 @@ -use crate::spec::{StackProbeType, Target}; +use crate::spec::{SanitizerSet, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::fuchsia_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + base.supported_sanitizers = SanitizerSet::ADDRESS; Target { llvm_target: "x86_64-fuchsia".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs index aac01445917..ca3556fc48e 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::freebsd_base::opts(); @@ -6,6 +6,7 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::MEMORY | SanitizerSet::THREAD; Target { llvm_target: "x86_64-unknown-freebsd".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs index dfda49b9c33..9569e98ed59 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); @@ -6,6 +6,8 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string()); base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; + base.supported_sanitizers = + SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD; Target { llvm_target: "x86_64-unknown-linux-gnu".to_string(), diff --git a/src/test/ui/sanitize/unsupported-target.rs b/src/test/ui/sanitize/unsupported-target.rs index 6ccc9988cde..3fb749815f7 100644 --- a/src/test/ui/sanitize/unsupported-target.rs +++ b/src/test/ui/sanitize/unsupported-target.rs @@ -1,6 +1,5 @@ // compile-flags: -Z sanitizer=leak --target i686-unknown-linux-gnu -// error-pattern: error: `-Zsanitizer=leak` only works with targets: - +// error-pattern: error: leak sanitizer is not supported for this target #![feature(no_core)] #![no_core] #![no_main] diff --git a/src/test/ui/sanitize/unsupported-target.stderr b/src/test/ui/sanitize/unsupported-target.stderr index 093678707fb..9bb8405020d 100644 --- a/src/test/ui/sanitize/unsupported-target.stderr +++ b/src/test/ui/sanitize/unsupported-target.stderr @@ -1,4 +1,4 @@ -error: `-Zsanitizer=leak` only works with targets: aarch64-apple-darwin, aarch64-unknown-linux-gnu, x86_64-apple-darwin, x86_64-unknown-linux-gnu +error: leak sanitizer is not supported for this target error: aborting due to previous error From a3c0f0a3dfccf75bd7df55b2806788489f7831cd Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sat, 13 Feb 2021 22:00:07 +0200 Subject: [PATCH 304/370] (De-)serialize the supported_sanitizers --- compiler/rustc_target/src/spec/mod.rs | 73 ++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 390e5332c00..89052ef390b 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -600,19 +600,28 @@ bitflags::bitflags! { } } +impl SanitizerSet { + /// Return sanitizer's name + /// + /// Returns none if the flags is a set of sanitizers numbering not exactly one. + fn as_str(self) -> Option<&'static str> { + Some(match self { + SanitizerSet::ADDRESS => "address", + SanitizerSet::LEAK => "leak", + SanitizerSet::MEMORY => "memory", + SanitizerSet::THREAD => "thread", + SanitizerSet::HWADDRESS => "hwaddress", + _ => return None, + }) + } +} + /// Formats a sanitizer set as a comma separated list of sanitizers' names. impl fmt::Display for SanitizerSet { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut first = true; for s in *self { - let name = match s { - SanitizerSet::ADDRESS => "address", - SanitizerSet::LEAK => "leak", - SanitizerSet::MEMORY => "memory", - SanitizerSet::THREAD => "thread", - SanitizerSet::HWADDRESS => "hwaddress", - _ => panic!("unrecognized sanitizer {:?}", s), - }; + let name = s.as_str().unwrap_or_else(|| panic!("unrecognized sanitizer {:?}", s)); if !first { f.write_str(", ")?; } @@ -628,12 +637,18 @@ impl IntoIterator for SanitizerSet { type IntoIter = std::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { - [SanitizerSet::ADDRESS, SanitizerSet::LEAK, SanitizerSet::MEMORY, SanitizerSet::THREAD, SanitizerSet::HWADDRESS] - .iter() - .copied() - .filter(|&s| self.contains(s)) - .collect::>() - .into_iter() + [ + SanitizerSet::ADDRESS, + SanitizerSet::LEAK, + SanitizerSet::MEMORY, + SanitizerSet::THREAD, + SanitizerSet::HWADDRESS, + ] + .iter() + .copied() + .filter(|&s| self.contains(s)) + .collect::>() + .into_iter() } } @@ -643,6 +658,16 @@ impl HashStable for SanitizerSet { } } +impl ToJson for SanitizerSet { + fn to_json(&self) -> Json { + self.into_iter() + .map(|v| Some(v.as_str()?.to_json())) + .collect::>>() + .unwrap_or(Vec::new()) + .to_json() + } +} + macro_rules! supported_targets { ( $(($( $triple:literal, )+ $module:ident ),)+ ) => { $(mod $module;)+ @@ -1614,6 +1639,24 @@ impl Target { )), }).unwrap_or(Ok(())) } ); + ($key_name:ident, SanitizerSet) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.find(&name[..]).and_then(|o| o.as_array()).and_then(|a| { + for s in a { + base.$key_name |= match s.as_string() { + Some("address") => SanitizerSet::ADDRESS, + Some("leak") => SanitizerSet::LEAK, + Some("memory") => SanitizerSet::MEMORY, + Some("thread") => SanitizerSet::THREAD, + Some("hwaddress") => SanitizerSet::HWADDRESS, + Some(s) => return Some(Err(format!("unknown sanitizer {}", s))), + _ => return Some(Err(format!("not a string: {:?}", s))), + }; + } + Some(Ok(())) + }).unwrap_or(Ok(())) + } ); + ($key_name:ident, crt_objects_fallback) => ( { let name = (stringify!($key_name)).replace("_", "-"); obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| { @@ -1792,6 +1835,7 @@ impl Target { key!(eh_frame_header, bool); key!(has_thumb_interworking, bool); key!(split_debuginfo, SplitDebuginfo)?; + key!(supported_sanitizers, SanitizerSet)?; // NB: The old name is deprecated, but support for it is retained for // compatibility. @@ -2029,6 +2073,7 @@ impl ToJson for Target { target_option_val!(eh_frame_header); target_option_val!(has_thumb_interworking); target_option_val!(split_debuginfo); + target_option_val!(supported_sanitizers); if default.unsupported_abis != self.unsupported_abis { d.insert( From 41875c82c7858735b1d028b04156c328715ca454 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Mon, 15 Feb 2021 03:17:50 +0200 Subject: [PATCH 305/370] rm target specific logic in link_sanitizer_runtime --- compiler/rustc_codegen_ssa/src/back/link.rs | 36 ++++++++------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 9eaabfe04a9..217b8f43229 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -922,28 +922,20 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) { .map(|channel| format!("-{}", channel)) .unwrap_or_default(); - match sess.opts.target_triple.triple() { - "aarch64-apple-darwin" | "x86_64-apple-darwin" => { - // On Apple platforms, the sanitizer is always built as a dylib, and - // LLVM will link to `@rpath/*.dylib`, so we need to specify an - // rpath to the library as well (the rpath should be absolute, see - // PR #41352 for details). - let filename = format!("rustc{}_rt.{}", channel, name); - let path = find_sanitizer_runtime(&sess, &filename); - let rpath = path.to_str().expect("non-utf8 component in path"); - linker.args(&["-Wl,-rpath", "-Xlinker", rpath]); - linker.link_dylib(Symbol::intern(&filename)); - } - "aarch64-fuchsia" - | "aarch64-unknown-linux-gnu" - | "x86_64-fuchsia" - | "x86_64-unknown-freebsd" - | "x86_64-unknown-linux-gnu" => { - let filename = format!("librustc{}_rt.{}.a", channel, name); - let path = find_sanitizer_runtime(&sess, &filename).join(&filename); - linker.link_whole_rlib(&path); - } - _ => {} + if sess.target.is_like_osx { + // On Apple platforms, the sanitizer is always built as a dylib, and + // LLVM will link to `@rpath/*.dylib`, so we need to specify an + // rpath to the library as well (the rpath should be absolute, see + // PR #41352 for details). + let filename = format!("rustc{}_rt.{}", channel, name); + let path = find_sanitizer_runtime(&sess, &filename); + let rpath = path.to_str().expect("non-utf8 component in path"); + linker.args(&["-Wl,-rpath", "-Xlinker", rpath]); + linker.link_dylib(Symbol::intern(&filename)); + } else { + let filename = format!("librustc{}_rt.{}.a", channel, name); + let path = find_sanitizer_runtime(&sess, &filename).join(&filename); + linker.link_whole_rlib(&path); } } From 2fb1fb7634b79d93d48749ee1f84d4ba552b186f Mon Sep 17 00:00:00 2001 From: Roxane Date: Thu, 25 Mar 2021 23:03:12 -0400 Subject: [PATCH 306/370] Fix diagnostic issue when using FakeReads in closures --- compiler/rustc_middle/src/mir/mod.rs | 16 ++++++++-- .../diagnostics/explain_borrow.rs | 2 +- .../src/borrow_check/diagnostics/mod.rs | 22 ++++++++++++-- .../src/build/expr/as_rvalue.rs | 30 ++++++++----------- .../rustc_mir_build/src/build/matches/mod.rs | 6 ++-- compiler/rustc_typeck/src/expr_use_visitor.rs | 21 +++++++++++-- ..._of_reborrow.SimplifyCfg-initial.after.mir | 28 ++++++++--------- ...row_and_cast.SimplifyCfg-initial.after.mir | 6 ++-- ...ignment.main.SimplifyCfg-initial.after.mir | 4 +-- ....match_tuple.SimplifyCfg-initial.after.mir | 2 +- ...e_38669.main.SimplifyCfg-initial.after.mir | 2 +- .../mir-opt/issue_49232.main.mir_map.0.mir | 4 +-- .../issue_72181.main.mir_map.0.32bit.mir | 2 +- .../issue_72181.main.mir_map.0.64bit.mir | 2 +- .../mir-opt/issue_72181_1.f.mir_map.0.mir | 2 +- .../mir-opt/issue_72181_1.main.mir_map.0.mir | 2 +- ....main.SimplifyCfg-promote-consts.after.mir | 2 +- ...fg-initial.after-ElaborateDrops.after.diff | 2 +- ...s.full_tested_match.PromoteTemps.after.mir | 2 +- ...full_tested_match2.PromoteTemps.before.mir | 2 +- ...h_false_edges.main.PromoteTemps.before.mir | 2 +- ...ch_test.main.SimplifyCfg-initial.after.mir | 6 ++-- ...egion_subtyping_basic.main.nll.0.32bit.mir | 6 ++-- ...egion_subtyping_basic.main.nll.0.64bit.mir | 6 ++-- ...receiver_ptr_mutability.main.mir_map.0.mir | 4 +-- ...tch_guard.CleanupNonCodegenStatements.diff | 2 +- ...imple_match.match_bool.mir_map.0.32bit.mir | 2 +- ...imple_match.match_bool.mir_map.0.64bit.mir | 2 +- .../mir-opt/storage_ranges.main.nll.0.mir | 6 ++-- ...ove_out.move_out_by_subslice.mir_map.0.mir | 2 +- ...y_move_out.move_out_from_end.mir_map.0.mir | 2 +- 31 files changed, 119 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index b2cf1aab112..1f7e12db47a 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1452,7 +1452,7 @@ pub struct Statement<'tcx> { // `Statement` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(Statement<'_>, 32); +static_assert_size!(Statement<'_>, 40); impl Statement<'_> { /// Changes a statement to a nop. This is both faster than deleting instructions and avoids @@ -1575,7 +1575,12 @@ pub enum FakeReadCause { /// `let x: !; match x {}` doesn't generate any read of x so we need to /// generate a read of x to check that it is initialized and safe. - ForMatchedPlace, + /// + /// If a closure pattern matches a Place starting with an Upvar, then we introduce a + /// FakeRead for that Place outside the closure, in such a case this option would be + /// Some(closure_def_id). + /// Otherwise, the value of the optional DefId will be None. + ForMatchedPlace(Option), /// A fake read of the RefWithinGuard version of a bind-by-value variable /// in a match guard to ensure that it's value hasn't change by the time @@ -1594,7 +1599,12 @@ pub enum FakeReadCause { /// but in some cases it can affect the borrow checker, as in #53695. /// Therefore, we insert a "fake read" here to ensure that we get /// appropriate errors. - ForLet, + /// + /// If a closure pattern matches a Place starting with an Upvar, then we introduce a + /// FakeRead for that Place outside the closure, in such a case this option would be + /// Some(closure_def_id). + /// Otherwise, the value of the optional DefId will be None. + ForLet(Option), /// If we have an index expression like /// diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs index 06e3f4b91f6..4ab0fe08259 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs @@ -515,7 +515,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let block = &self.body.basic_blocks()[location.block]; let kind = if let Some(&Statement { - kind: StatementKind::FakeRead(FakeReadCause::ForLet, _), + kind: StatementKind::FakeRead(FakeReadCause::ForLet(_), _), .. }) = block.statements.get(location.statement_index) { diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs index 6ea0ba0a8e1..6a457487348 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs @@ -7,8 +7,8 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItemGroup; use rustc_hir::GeneratorKind; use rustc_middle::mir::{ - AggregateKind, Constant, Field, Local, LocalInfo, LocalKind, Location, Operand, Place, - PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, + AggregateKind, Constant, FakeReadCause, Field, Local, LocalInfo, LocalKind, Location, Operand, + Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty::print::Print; use rustc_middle::ty::{self, DefIdTree, Instance, Ty, TyCtxt}; @@ -795,6 +795,24 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } + // StatementKind::FakeRead only contains a def_id if they are introduced as a result + // of pattern matching within a closure. + if let StatementKind::FakeRead(cause, box ref place) = stmt.kind { + match cause { + FakeReadCause::ForMatchedPlace(Some(closure_def_id)) + | FakeReadCause::ForLet(Some(closure_def_id)) => { + debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place); + let places = &[Operand::Move(*place)]; + if let Some((args_span, generator_kind, var_span)) = + self.closure_span(closure_def_id, moved_place, places) + { + return ClosureUse { generator_kind, args_span, var_span }; + } + } + _ => {} + } + } + let normal_ret = if moved_place.projection.iter().any(|p| matches!(p, ProjectionElem::Downcast(..))) { PatUse(stmt.source_info.span) 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 7f24a41b00b..822fbd91c94 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -179,24 +179,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // match x { _ => () } // fake read of `x` // }; // ``` - // FIXME(RFC2229): Remove feature gate once diagnostics are improved - if this.tcx.features().capture_disjoint_fields { - for (thir_place, cause, hir_id) in fake_reads.into_iter() { - let place_builder = - unpack!(block = this.as_place_builder(block, thir_place)); + for (thir_place, cause, hir_id) in fake_reads.into_iter() { + let place_builder = unpack!(block = this.as_place_builder(block, thir_place)); - if let Ok(place_builder_resolved) = - place_builder.try_upvars_resolved(this.tcx, this.typeck_results) - { - let mir_place = - place_builder_resolved.into_place(this.tcx, this.typeck_results); - this.cfg.push_fake_read( - block, - this.source_info(this.tcx.hir().span(*hir_id)), - *cause, - mir_place, - ); - } + if let Ok(place_builder_resolved) = + place_builder.try_upvars_resolved(this.tcx, this.typeck_results) + { + let mir_place = + place_builder_resolved.into_place(this.tcx, this.typeck_results); + this.cfg.push_fake_read( + block, + this.source_info(this.tcx.hir().span(*hir_id)), + *cause, + mir_place, + ); } } diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 73fd3f0feb5..0e422dc3c63 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -139,7 +139,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // uninhabited value. If we get never patterns, those will check that // the place is initialized, and so this read would only be used to // check safety. - let cause_matched_place = FakeReadCause::ForMatchedPlace; + let cause_matched_place = FakeReadCause::ForMatchedPlace(None); let source_info = self.source_info(scrutinee_span); if let Ok(scrutinee_builder) = @@ -400,7 +400,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Inject a fake read, see comments on `FakeReadCause::ForLet`. let source_info = self.source_info(irrefutable_pat.span); - self.cfg.push_fake_read(block, source_info, FakeReadCause::ForLet, place); + self.cfg.push_fake_read(block, source_info, FakeReadCause::ForLet(None), place); self.schedule_drop_for_binding(var, irrefutable_pat.span, OutsideGuard); block.unit() @@ -435,7 +435,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Inject a fake read, see comments on `FakeReadCause::ForLet`. let pattern_source_info = self.source_info(irrefutable_pat.span); - let cause_let = FakeReadCause::ForLet; + let cause_let = FakeReadCause::ForLet(None); self.cfg.push_fake_read(block, pattern_source_info, cause_let, place); let ty_source_info = self.source_info(user_ty_span); diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index ab286bacd81..02510cb6a44 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -280,9 +280,14 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { if needs_to_be_read { self.borrow_expr(&discr, ty::ImmBorrow); } else { + let closure_def_id = match discr_place.place.base { + PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id.to_def_id()), + _ => None, + }; + self.delegate.fake_read( discr_place.place.clone(), - FakeReadCause::ForMatchedPlace, + FakeReadCause::ForMatchedPlace(closure_def_id), discr_place.hir_id, ); @@ -578,9 +583,14 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } fn walk_arm(&mut self, discr_place: &PlaceWithHirId<'tcx>, arm: &hir::Arm<'_>) { + let closure_def_id = match discr_place.place.base { + PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id.to_def_id()), + _ => None, + }; + self.delegate.fake_read( discr_place.place.clone(), - FakeReadCause::ForMatchedPlace, + FakeReadCause::ForMatchedPlace(closure_def_id), discr_place.hir_id, ); self.walk_pat(discr_place, &arm.pat); @@ -595,9 +605,14 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { /// Walks a pat that occurs in isolation (i.e., top-level of fn argument or /// let binding, and *not* a match arm or nested pat.) fn walk_irrefutable_pat(&mut self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>) { + let closure_def_id = match discr_place.place.base { + PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id.to_def_id()), + _ => None, + }; + self.delegate.fake_read( discr_place.place.clone(), - FakeReadCause::ForLet, + FakeReadCause::ForLet(closure_def_id), discr_place.hir_id, ); self.walk_pat(discr_place, pat); diff --git a/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir index a9568112620..9fa478f8a82 100644 --- a/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir @@ -130,12 +130,12 @@ fn address_of_reborrow() -> () { StorageLive(_2); // scope 0 at $DIR/address-of.rs:4:14: 4:21 _2 = [const 0_i32; 10]; // scope 0 at $DIR/address-of.rs:4:14: 4:21 _1 = &_2; // scope 0 at $DIR/address-of.rs:4:13: 4:21 - FakeRead(ForLet, _1); // scope 0 at $DIR/address-of.rs:4:9: 4:10 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/address-of.rs:4:9: 4:10 StorageLive(_3); // scope 1 at $DIR/address-of.rs:5:9: 5:14 StorageLive(_4); // scope 1 at $DIR/address-of.rs:5:22: 5:29 _4 = [const 0_i32; 10]; // scope 1 at $DIR/address-of.rs:5:22: 5:29 _3 = &mut _4; // scope 1 at $DIR/address-of.rs:5:17: 5:29 - FakeRead(ForLet, _3); // scope 1 at $DIR/address-of.rs:5:9: 5:14 + FakeRead(ForLet(None), _3); // scope 1 at $DIR/address-of.rs:5:9: 5:14 StorageLive(_5); // scope 2 at $DIR/address-of.rs:7:5: 7:18 StorageLive(_6); // scope 2 at $DIR/address-of.rs:7:5: 7:18 _6 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:7:5: 7:6 @@ -170,25 +170,25 @@ fn address_of_reborrow() -> () { StorageDead(_13); // scope 2 at $DIR/address-of.rs:11:20: 11:21 StorageLive(_15); // scope 2 at $DIR/address-of.rs:13:9: 13:10 _15 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:13:23: 13:24 - FakeRead(ForLet, _15); // scope 2 at $DIR/address-of.rs:13:9: 13:10 + FakeRead(ForLet(None), _15); // scope 2 at $DIR/address-of.rs:13:9: 13:10 AscribeUserType(_15, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 2 at $DIR/address-of.rs:13:12: 13:20 StorageLive(_16); // scope 3 at $DIR/address-of.rs:14:9: 14:10 _16 = &raw const (*_1); // scope 3 at $DIR/address-of.rs:14:31: 14:32 - FakeRead(ForLet, _16); // scope 3 at $DIR/address-of.rs:14:9: 14:10 + FakeRead(ForLet(None), _16); // scope 3 at $DIR/address-of.rs:14:9: 14:10 AscribeUserType(_16, o, UserTypeProjection { base: UserType(5), projs: [] }); // scope 3 at $DIR/address-of.rs:14:12: 14:28 StorageLive(_17); // scope 4 at $DIR/address-of.rs:15:9: 15:10 StorageLive(_18); // scope 4 at $DIR/address-of.rs:15:30: 15:31 _18 = &raw const (*_1); // scope 4 at $DIR/address-of.rs:15:30: 15:31 _17 = move _18 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 4 at $DIR/address-of.rs:15:30: 15:31 StorageDead(_18); // scope 4 at $DIR/address-of.rs:15:30: 15:31 - FakeRead(ForLet, _17); // scope 4 at $DIR/address-of.rs:15:9: 15:10 + FakeRead(ForLet(None), _17); // scope 4 at $DIR/address-of.rs:15:9: 15:10 AscribeUserType(_17, o, UserTypeProjection { base: UserType(7), projs: [] }); // scope 4 at $DIR/address-of.rs:15:12: 15:27 StorageLive(_19); // scope 5 at $DIR/address-of.rs:16:9: 16:10 StorageLive(_20); // scope 5 at $DIR/address-of.rs:16:27: 16:28 _20 = &raw const (*_1); // scope 5 at $DIR/address-of.rs:16:27: 16:28 _19 = move _20 as *const [i32] (Pointer(Unsize)); // scope 5 at $DIR/address-of.rs:16:27: 16:28 StorageDead(_20); // scope 5 at $DIR/address-of.rs:16:27: 16:28 - FakeRead(ForLet, _19); // scope 5 at $DIR/address-of.rs:16:9: 16:10 + FakeRead(ForLet(None), _19); // scope 5 at $DIR/address-of.rs:16:9: 16:10 AscribeUserType(_19, o, UserTypeProjection { base: UserType(9), projs: [] }); // scope 5 at $DIR/address-of.rs:16:12: 16:24 StorageLive(_21); // scope 6 at $DIR/address-of.rs:18:5: 18:18 StorageLive(_22); // scope 6 at $DIR/address-of.rs:18:5: 18:18 @@ -218,25 +218,25 @@ fn address_of_reborrow() -> () { StorageDead(_27); // scope 6 at $DIR/address-of.rs:21:22: 21:23 StorageLive(_29); // scope 6 at $DIR/address-of.rs:23:9: 23:10 _29 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:23:23: 23:24 - FakeRead(ForLet, _29); // scope 6 at $DIR/address-of.rs:23:9: 23:10 + FakeRead(ForLet(None), _29); // scope 6 at $DIR/address-of.rs:23:9: 23:10 AscribeUserType(_29, o, UserTypeProjection { base: UserType(13), projs: [] }); // scope 6 at $DIR/address-of.rs:23:12: 23:20 StorageLive(_30); // scope 7 at $DIR/address-of.rs:24:9: 24:10 _30 = &raw const (*_3); // scope 7 at $DIR/address-of.rs:24:31: 24:32 - FakeRead(ForLet, _30); // scope 7 at $DIR/address-of.rs:24:9: 24:10 + FakeRead(ForLet(None), _30); // scope 7 at $DIR/address-of.rs:24:9: 24:10 AscribeUserType(_30, o, UserTypeProjection { base: UserType(15), projs: [] }); // scope 7 at $DIR/address-of.rs:24:12: 24:28 StorageLive(_31); // scope 8 at $DIR/address-of.rs:25:9: 25:10 StorageLive(_32); // scope 8 at $DIR/address-of.rs:25:30: 25:31 _32 = &raw const (*_3); // scope 8 at $DIR/address-of.rs:25:30: 25:31 _31 = move _32 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 8 at $DIR/address-of.rs:25:30: 25:31 StorageDead(_32); // scope 8 at $DIR/address-of.rs:25:30: 25:31 - FakeRead(ForLet, _31); // scope 8 at $DIR/address-of.rs:25:9: 25:10 + FakeRead(ForLet(None), _31); // scope 8 at $DIR/address-of.rs:25:9: 25:10 AscribeUserType(_31, o, UserTypeProjection { base: UserType(17), projs: [] }); // scope 8 at $DIR/address-of.rs:25:12: 25:27 StorageLive(_33); // scope 9 at $DIR/address-of.rs:26:9: 26:10 StorageLive(_34); // scope 9 at $DIR/address-of.rs:26:27: 26:28 _34 = &raw const (*_3); // scope 9 at $DIR/address-of.rs:26:27: 26:28 _33 = move _34 as *const [i32] (Pointer(Unsize)); // scope 9 at $DIR/address-of.rs:26:27: 26:28 StorageDead(_34); // scope 9 at $DIR/address-of.rs:26:27: 26:28 - FakeRead(ForLet, _33); // scope 9 at $DIR/address-of.rs:26:9: 26:10 + FakeRead(ForLet(None), _33); // scope 9 at $DIR/address-of.rs:26:9: 26:10 AscribeUserType(_33, o, UserTypeProjection { base: UserType(19), projs: [] }); // scope 9 at $DIR/address-of.rs:26:12: 26:24 StorageLive(_35); // scope 10 at $DIR/address-of.rs:28:5: 28:16 StorageLive(_36); // scope 10 at $DIR/address-of.rs:28:5: 28:16 @@ -266,25 +266,25 @@ fn address_of_reborrow() -> () { StorageDead(_41); // scope 10 at $DIR/address-of.rs:31:20: 31:21 StorageLive(_43); // scope 10 at $DIR/address-of.rs:33:9: 33:10 _43 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:33:21: 33:22 - FakeRead(ForLet, _43); // scope 10 at $DIR/address-of.rs:33:9: 33:10 + FakeRead(ForLet(None), _43); // scope 10 at $DIR/address-of.rs:33:9: 33:10 AscribeUserType(_43, o, UserTypeProjection { base: UserType(23), projs: [] }); // scope 10 at $DIR/address-of.rs:33:12: 33:18 StorageLive(_44); // scope 11 at $DIR/address-of.rs:34:9: 34:10 _44 = &raw mut (*_3); // scope 11 at $DIR/address-of.rs:34:29: 34:30 - FakeRead(ForLet, _44); // scope 11 at $DIR/address-of.rs:34:9: 34:10 + FakeRead(ForLet(None), _44); // scope 11 at $DIR/address-of.rs:34:9: 34:10 AscribeUserType(_44, o, UserTypeProjection { base: UserType(25), projs: [] }); // scope 11 at $DIR/address-of.rs:34:12: 34:26 StorageLive(_45); // scope 12 at $DIR/address-of.rs:35:9: 35:10 StorageLive(_46); // scope 12 at $DIR/address-of.rs:35:28: 35:29 _46 = &raw mut (*_3); // scope 12 at $DIR/address-of.rs:35:28: 35:29 _45 = move _46 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 12 at $DIR/address-of.rs:35:28: 35:29 StorageDead(_46); // scope 12 at $DIR/address-of.rs:35:28: 35:29 - FakeRead(ForLet, _45); // scope 12 at $DIR/address-of.rs:35:9: 35:10 + FakeRead(ForLet(None), _45); // scope 12 at $DIR/address-of.rs:35:9: 35:10 AscribeUserType(_45, o, UserTypeProjection { base: UserType(27), projs: [] }); // scope 12 at $DIR/address-of.rs:35:12: 35:25 StorageLive(_47); // scope 13 at $DIR/address-of.rs:36:9: 36:10 StorageLive(_48); // scope 13 at $DIR/address-of.rs:36:25: 36:26 _48 = &raw mut (*_3); // scope 13 at $DIR/address-of.rs:36:25: 36:26 _47 = move _48 as *mut [i32] (Pointer(Unsize)); // scope 13 at $DIR/address-of.rs:36:25: 36:26 StorageDead(_48); // scope 13 at $DIR/address-of.rs:36:25: 36:26 - FakeRead(ForLet, _47); // scope 13 at $DIR/address-of.rs:36:9: 36:10 + FakeRead(ForLet(None), _47); // scope 13 at $DIR/address-of.rs:36:9: 36:10 AscribeUserType(_47, o, UserTypeProjection { base: UserType(29), projs: [] }); // scope 13 at $DIR/address-of.rs:36:12: 36:22 _0 = const (); // scope 0 at $DIR/address-of.rs:3:26: 37:2 StorageDead(_47); // scope 13 at $DIR/address-of.rs:37:1: 37:2 diff --git a/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir index e058b0aaa8f..195f3e2e65c 100644 --- a/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir @@ -24,19 +24,19 @@ fn borrow_and_cast(_1: i32) -> () { StorageLive(_3); // scope 0 at $DIR/address-of.rs:42:13: 42:15 _3 = &_1; // scope 0 at $DIR/address-of.rs:42:13: 42:15 _2 = &raw const (*_3); // scope 0 at $DIR/address-of.rs:42:13: 42:15 - FakeRead(ForLet, _2); // scope 0 at $DIR/address-of.rs:42:9: 42:10 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/address-of.rs:42:9: 42:10 StorageDead(_3); // scope 0 at $DIR/address-of.rs:42:29: 42:30 StorageLive(_4); // scope 1 at $DIR/address-of.rs:43:9: 43:10 StorageLive(_5); // scope 1 at $DIR/address-of.rs:43:13: 43:19 _5 = &mut _1; // scope 1 at $DIR/address-of.rs:43:13: 43:19 _4 = &raw const (*_5); // scope 1 at $DIR/address-of.rs:43:13: 43:19 - FakeRead(ForLet, _4); // scope 1 at $DIR/address-of.rs:43:9: 43:10 + FakeRead(ForLet(None), _4); // scope 1 at $DIR/address-of.rs:43:9: 43:10 StorageDead(_5); // scope 1 at $DIR/address-of.rs:43:33: 43:34 StorageLive(_6); // scope 2 at $DIR/address-of.rs:44:9: 44:10 StorageLive(_7); // scope 2 at $DIR/address-of.rs:44:13: 44:19 _7 = &mut _1; // scope 2 at $DIR/address-of.rs:44:13: 44:19 _6 = &raw mut (*_7); // scope 2 at $DIR/address-of.rs:44:13: 44:19 - FakeRead(ForLet, _6); // scope 2 at $DIR/address-of.rs:44:9: 44:10 + FakeRead(ForLet(None), _6); // scope 2 at $DIR/address-of.rs:44:9: 44:10 StorageDead(_7); // scope 2 at $DIR/address-of.rs:44:31: 44:32 _0 = const (); // scope 0 at $DIR/address-of.rs:41:32: 45:2 StorageDead(_6); // scope 2 at $DIR/address-of.rs:45:1: 45:2 diff --git a/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir index 7e0ca3dea4b..e751b825c05 100644 --- a/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir @@ -28,7 +28,7 @@ fn main() -> () { bb0: { StorageLive(_1); // scope 0 at $DIR/basic_assignment.rs:11:9: 11:17 _1 = const false; // scope 0 at $DIR/basic_assignment.rs:11:20: 11:25 - FakeRead(ForLet, _1); // scope 0 at $DIR/basic_assignment.rs:11:9: 11:17 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/basic_assignment.rs:11:9: 11:17 StorageLive(_2); // scope 1 at $DIR/basic_assignment.rs:12:9: 12:17 StorageLive(_3); // scope 2 at $DIR/basic_assignment.rs:16:16: 16:24 _3 = _1; // scope 2 at $DIR/basic_assignment.rs:16:16: 16:24 @@ -36,7 +36,7 @@ fn main() -> () { StorageDead(_3); // scope 2 at $DIR/basic_assignment.rs:16:23: 16:24 StorageLive(_4); // scope 2 at $DIR/basic_assignment.rs:18:9: 18:15 _4 = Option::>::None; // scope 2 at $DIR/basic_assignment.rs:18:36: 18:40 - FakeRead(ForLet, _4); // scope 2 at $DIR/basic_assignment.rs:18:9: 18:15 + FakeRead(ForLet(None), _4); // scope 2 at $DIR/basic_assignment.rs:18:9: 18:15 AscribeUserType(_4, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 2 at $DIR/basic_assignment.rs:18:17: 18:33 StorageLive(_5); // scope 3 at $DIR/basic_assignment.rs:19:9: 19:15 StorageLive(_6); // scope 4 at $DIR/basic_assignment.rs:23:14: 23:20 diff --git a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir index aa4f996c4b4..93507879a6f 100644 --- a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir @@ -18,7 +18,7 @@ fn match_tuple(_1: (u32, bool, Option, u32)) -> u32 { } bb0: { - FakeRead(ForMatchedPlace, _1); // scope 0 at $DIR/exponential-or.rs:5:11: 5:12 + FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/exponential-or.rs:5:11: 5:12 switchInt((_1.0: u32)) -> [1_u32: bb2, 4_u32: bb2, otherwise: bb1]; // scope 0 at $DIR/exponential-or.rs:6:15: 6:16 } diff --git a/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir index e9e5a101a64..8355b2d195e 100644 --- a/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir @@ -14,7 +14,7 @@ fn main() -> () { bb0: { StorageLive(_1); // scope 0 at $DIR/issue-38669.rs:5:9: 5:25 _1 = const false; // scope 0 at $DIR/issue-38669.rs:5:28: 5:33 - FakeRead(ForLet, _1); // scope 0 at $DIR/issue-38669.rs:5:9: 5:25 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue-38669.rs:5:9: 5:25 goto -> bb1; // scope 1 at $DIR/issue-38669.rs:6:5: 11:6 } diff --git a/src/test/mir-opt/issue_49232.main.mir_map.0.mir b/src/test/mir-opt/issue_49232.main.mir_map.0.mir index 79f5495c788..06fbbda3d9e 100644 --- a/src/test/mir-opt/issue_49232.main.mir_map.0.mir +++ b/src/test/mir-opt/issue_49232.main.mir_map.0.mir @@ -24,7 +24,7 @@ fn main() -> () { StorageLive(_2); // scope 0 at $DIR/issue-49232.rs:7:13: 7:19 StorageLive(_3); // scope 0 at $DIR/issue-49232.rs:8:19: 8:23 _3 = const true; // scope 0 at $DIR/issue-49232.rs:8:19: 8:23 - FakeRead(ForMatchedPlace, _3); // scope 0 at $DIR/issue-49232.rs:8:19: 8:23 + FakeRead(ForMatchedPlace(None), _3); // scope 0 at $DIR/issue-49232.rs:8:19: 8:23 switchInt(_3) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/issue-49232.rs:9:17: 9:22 } @@ -51,7 +51,7 @@ fn main() -> () { } bb8: { - FakeRead(ForLet, _2); // scope 0 at $DIR/issue-49232.rs:7:13: 7:19 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-49232.rs:7:13: 7:19 StorageDead(_3); // scope 0 at $DIR/issue-49232.rs:12:10: 12:11 StorageLive(_5); // scope 1 at $DIR/issue-49232.rs:13:9: 13:22 StorageLive(_6); // scope 1 at $DIR/issue-49232.rs:13:14: 13:21 diff --git a/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir b/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir index cf66a501e35..2e6783b7f3c 100644 --- a/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir +++ b/src/test/mir-opt/issue_72181.main.mir_map.0.32bit.mir @@ -38,7 +38,7 @@ fn main() -> () { _2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:26:13: 26:43 StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:26:42: 26:43 StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:26:42: 26:43 - FakeRead(ForLet, _2); // scope 1 at $DIR/issue-72181.rs:26:9: 26:10 + FakeRead(ForLet(None), _2); // scope 1 at $DIR/issue-72181.rs:26:9: 26:10 StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:27:13: 27:30 StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:27:24: 27:25 _6 = const 0_usize; // scope 4 at $DIR/issue-72181.rs:27:24: 27:25 diff --git a/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir b/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir index cf66a501e35..2e6783b7f3c 100644 --- a/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir +++ b/src/test/mir-opt/issue_72181.main.mir_map.0.64bit.mir @@ -38,7 +38,7 @@ fn main() -> () { _2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:26:13: 26:43 StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:26:42: 26:43 StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:26:42: 26:43 - FakeRead(ForLet, _2); // scope 1 at $DIR/issue-72181.rs:26:9: 26:10 + FakeRead(ForLet(None), _2); // scope 1 at $DIR/issue-72181.rs:26:9: 26:10 StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:27:13: 27:30 StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:27:24: 27:25 _6 = const 0_usize; // scope 4 at $DIR/issue-72181.rs:27:24: 27:25 diff --git a/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir index 7571d7bb94f..7def08ece22 100644 --- a/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir @@ -9,7 +9,7 @@ fn f(_1: Void) -> ! { bb0: { StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:10:20: 12:2 StorageLive(_3); // scope 0 at $DIR/issue-72181-1.rs:11:5: 11:15 - FakeRead(ForMatchedPlace, _1); // scope 0 at $DIR/issue-72181-1.rs:11:11: 11:12 + FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/issue-72181-1.rs:11:11: 11:12 unreachable; // scope 0 at $DIR/issue-72181-1.rs:11:11: 11:12 } diff --git a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir index 1fd91c2056b..3c26b20c35e 100644 --- a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir @@ -29,7 +29,7 @@ fn main() -> () { bb1: { StorageDead(_3); // scope 2 at $DIR/issue-72181-1.rs:17:43: 17:44 - FakeRead(ForLet, _2); // scope 0 at $DIR/issue-72181-1.rs:16:9: 16:10 + FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-72181-1.rs:16:9: 16:10 AscribeUserType(_2, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue-72181-1.rs:16:12: 16:16 StorageLive(_4); // scope 1 at $DIR/issue-72181-1.rs:20:5: 20:9 StorageLive(_5); // scope 1 at $DIR/issue-72181-1.rs:20:7: 20:8 diff --git a/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir index f109937dbf9..99c7ac8d5b7 100644 --- a/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir +++ b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir @@ -41,7 +41,7 @@ fn main() -> () { bb4: { StorageLive(_6); // scope 0 at $DIR/loop_test.rs:14:13: 14:14 _6 = const 1_i32; // scope 0 at $DIR/loop_test.rs:14:17: 14:18 - FakeRead(ForLet, _6); // scope 0 at $DIR/loop_test.rs:14:13: 14:14 + FakeRead(ForLet(None), _6); // scope 0 at $DIR/loop_test.rs:14:13: 14:14 StorageDead(_6); // scope 0 at $DIR/loop_test.rs:16:5: 16:6 goto -> bb3; // scope 0 at $DIR/loop_test.rs:1:1: 1:1 } diff --git a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff index 95beab2ec9a..3395cbfbdfb 100644 --- a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff +++ b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff @@ -31,7 +31,7 @@ } bb0: { -- FakeRead(ForMatchedPlace, _2); // scope 0 at $DIR/match-arm-scopes.rs:14:11: 14:16 +- FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match-arm-scopes.rs:14:11: 14:16 - switchInt((_2.0: bool)) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/match-arm-scopes.rs:15:10: 15:15 + switchInt((_2.0: bool)) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/match-arm-scopes.rs:15:10: 15:15 } diff --git a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir index 1921b935941..5af242376c9 100644 --- a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir +++ b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir @@ -27,7 +27,7 @@ fn full_tested_match() -> () { StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:15:13: 19:6 StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27 _2 = Option::::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27 - FakeRead(ForMatchedPlace, _2); // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27 + FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27 _3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:16:9: 16:16 switchInt(move _3) -> [0_isize: bb1, 1_isize: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:16:9: 16:16 } diff --git a/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir b/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir index c7b1cce061b..a4ebf8a0246 100644 --- a/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir +++ b/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir @@ -26,7 +26,7 @@ fn full_tested_match2() -> () { StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:26:13: 30:6 StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:26:19: 26:27 _2 = Option::::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:26:19: 26:27 - FakeRead(ForMatchedPlace, _2); // scope 0 at $DIR/match_false_edges.rs:26:19: 26:27 + FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:26:19: 26:27 _3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:27:9: 27:16 switchInt(move _3) -> [0_isize: bb1, 1_isize: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:27:9: 27:16 } diff --git a/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir b/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir index 9b8ce2c1ed0..5de52b324f4 100644 --- a/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir +++ b/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir @@ -37,7 +37,7 @@ fn main() -> () { StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:35:13: 40:6 StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:35:19: 35:26 _2 = Option::::Some(const 1_i32); // scope 0 at $DIR/match_false_edges.rs:35:19: 35:26 - FakeRead(ForMatchedPlace, _2); // scope 0 at $DIR/match_false_edges.rs:35:19: 35:26 + FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:35:19: 35:26 _4 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:36:9: 36:17 switchInt(move _4) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/match_false_edges.rs:36:9: 36:17 } diff --git a/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir index e3bc4f80f27..5bb910947ca 100644 --- a/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir @@ -21,12 +21,12 @@ fn main() -> () { bb0: { StorageLive(_1); // scope 0 at $DIR/match_test.rs:7:9: 7:10 _1 = const 3_i32; // scope 0 at $DIR/match_test.rs:7:13: 7:14 - FakeRead(ForLet, _1); // scope 0 at $DIR/match_test.rs:7:9: 7:10 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/match_test.rs:7:9: 7:10 StorageLive(_2); // scope 1 at $DIR/match_test.rs:8:9: 8:10 _2 = const true; // scope 1 at $DIR/match_test.rs:8:13: 8:17 - FakeRead(ForLet, _2); // scope 1 at $DIR/match_test.rs:8:9: 8:10 + FakeRead(ForLet(None), _2); // scope 1 at $DIR/match_test.rs:8:9: 8:10 StorageLive(_3); // scope 2 at $DIR/match_test.rs:12:5: 17:6 - FakeRead(ForMatchedPlace, _1); // scope 2 at $DIR/match_test.rs:12:11: 12:12 + FakeRead(ForMatchedPlace(None), _1); // scope 2 at $DIR/match_test.rs:12:11: 12:12 _6 = Le(const 0_i32, _1); // scope 2 at $DIR/match_test.rs:13:9: 13:14 switchInt(move _6) -> [false: bb4, otherwise: bb1]; // scope 2 at $DIR/match_test.rs:13:9: 13:14 } diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index 8c939d5fc3d..39e6cee11b4 100644 --- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -46,7 +46,7 @@ fn main() -> () { bb0: { StorageLive(_1); // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14 _1 = [const Const(Value(Scalar(0x00000001)): usize), const Const(Value(Scalar(0x00000002)): usize), const Const(Value(Scalar(0x00000003)): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:17:17: 17:26 - FakeRead(ForLet, _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14 + FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14 StorageLive(_2); // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10 StorageLive(_3); // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17 _3 = const Const(Value(Scalar(0x00000000)): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17 @@ -57,10 +57,10 @@ fn main() -> () { bb1: { _2 = &'_#3r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:18:13: 18:18 - FakeRead(ForLet, _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10 + FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10 StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10 _6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:19:13: 19:14 - FakeRead(ForLet, _6); // bb1[4]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10 + FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10 StorageLive(_7); // bb1[5]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12 _7 = const Const(Value(Scalar(0x01)): bool); // bb1[6]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12 switchInt(move _7) -> [Const(Value(Scalar(0x00)): bool): bb3, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6 diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index 00704baa6c1..6021b6529f9 100644 --- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -46,7 +46,7 @@ fn main() -> () { bb0: { StorageLive(_1); // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14 _1 = [const Const(Value(Scalar(0x0000000000000001)): usize), const Const(Value(Scalar(0x0000000000000002)): usize), const Const(Value(Scalar(0x0000000000000003)): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:17:17: 17:26 - FakeRead(ForLet, _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14 + FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:17:9: 17:14 StorageLive(_2); // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10 StorageLive(_3); // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17 _3 = const Const(Value(Scalar(0x0000000000000000)): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:18:16: 18:17 @@ -57,10 +57,10 @@ fn main() -> () { bb1: { _2 = &'_#3r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:18:13: 18:18 - FakeRead(ForLet, _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10 + FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:18:9: 18:10 StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10 _6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:19:13: 19:14 - FakeRead(ForLet, _6); // bb1[4]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10 + FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region-subtyping-basic.rs:19:9: 19:10 StorageLive(_7); // bb1[5]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12 _7 = const Const(Value(Scalar(0x01)): bool); // bb1[6]: scope 3 at $DIR/region-subtyping-basic.rs:20:8: 20:12 switchInt(move _7) -> [Const(Value(Scalar(0x00)): bool): bb3, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region-subtyping-basic.rs:20:5: 24:6 diff --git a/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir b/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir index d2d96ff468d..f54c8f8ab4a 100644 --- a/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir +++ b/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir @@ -36,7 +36,7 @@ fn main() -> () { } bb1: { - FakeRead(ForLet, _1); // scope 0 at $DIR/receiver-ptr-mutability.rs:14:9: 14:12 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/receiver-ptr-mutability.rs:14:9: 14:12 AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/receiver-ptr-mutability.rs:14:14: 14:23 StorageLive(_2); // scope 1 at $DIR/receiver-ptr-mutability.rs:15:5: 15:12 StorageLive(_3); // scope 1 at $DIR/receiver-ptr-mutability.rs:15:5: 15:8 @@ -63,7 +63,7 @@ fn main() -> () { _7 = &_8; // scope 1 at $DIR/receiver-ptr-mutability.rs:18:35: 18:41 _6 = &_7; // scope 1 at $DIR/receiver-ptr-mutability.rs:18:34: 18:41 _5 = &(*_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:18:34: 18:41 - FakeRead(ForLet, _5); // scope 1 at $DIR/receiver-ptr-mutability.rs:18:9: 18:16 + FakeRead(ForLet(None), _5); // scope 1 at $DIR/receiver-ptr-mutability.rs:18:9: 18:16 AscribeUserType(_5, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 1 at $DIR/receiver-ptr-mutability.rs:18:18: 18:31 StorageDead(_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:18:41: 18:42 StorageLive(_10); // scope 2 at $DIR/receiver-ptr-mutability.rs:19:5: 19:16 diff --git a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff index 47027311b47..4aa388fc67b 100644 --- a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff +++ b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff @@ -13,7 +13,7 @@ let mut _8: bool; // in scope 0 at $DIR/remove_fake_borrows.rs:8:20: 8:21 bb0: { -- FakeRead(ForMatchedPlace, _1); // scope 0 at $DIR/remove_fake_borrows.rs:7:11: 7:12 +- FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/remove_fake_borrows.rs:7:11: 7:12 + nop; // scope 0 at $DIR/remove_fake_borrows.rs:7:11: 7:12 _3 = discriminant(_1); // scope 0 at $DIR/remove_fake_borrows.rs:8:9: 8:16 switchInt(move _3) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:8:9: 8:16 diff --git a/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir b/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir index 5bcb20ca72a..841cca7c381 100644 --- a/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir +++ b/src/test/mir-opt/simple_match.match_bool.mir_map.0.32bit.mir @@ -5,7 +5,7 @@ fn match_bool(_1: bool) -> usize { let mut _0: usize; // return place in scope 0 at $DIR/simple-match.rs:5:27: 5:32 bb0: { - FakeRead(ForMatchedPlace, _1); // scope 0 at $DIR/simple-match.rs:6:11: 6:12 + FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple-match.rs:6:11: 6:12 switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple-match.rs:7:9: 7:13 } diff --git a/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir b/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir index 5bcb20ca72a..841cca7c381 100644 --- a/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir +++ b/src/test/mir-opt/simple_match.match_bool.mir_map.0.64bit.mir @@ -5,7 +5,7 @@ fn match_bool(_1: bool) -> usize { let mut _0: usize; // return place in scope 0 at $DIR/simple-match.rs:5:27: 5:32 bb0: { - FakeRead(ForMatchedPlace, _1); // scope 0 at $DIR/simple-match.rs:6:11: 6:12 + FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple-match.rs:6:11: 6:12 switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple-match.rs:7:9: 7:13 } diff --git a/src/test/mir-opt/storage_ranges.main.nll.0.mir b/src/test/mir-opt/storage_ranges.main.nll.0.mir index 6fa83d3de62..e02580135af 100644 --- a/src/test/mir-opt/storage_ranges.main.nll.0.mir +++ b/src/test/mir-opt/storage_ranges.main.nll.0.mir @@ -39,7 +39,7 @@ fn main() -> () { bb0: { StorageLive(_1); // scope 0 at $DIR/storage_ranges.rs:4:9: 4:10 _1 = const 0_i32; // scope 0 at $DIR/storage_ranges.rs:4:13: 4:14 - FakeRead(ForLet, _1); // scope 0 at $DIR/storage_ranges.rs:4:9: 4:10 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/storage_ranges.rs:4:9: 4:10 StorageLive(_2); // scope 1 at $DIR/storage_ranges.rs:5:5: 7:6 StorageLive(_3); // scope 1 at $DIR/storage_ranges.rs:6:13: 6:14 StorageLive(_4); // scope 1 at $DIR/storage_ranges.rs:6:18: 6:25 @@ -48,14 +48,14 @@ fn main() -> () { _4 = Option::::Some(move _5); // scope 1 at $DIR/storage_ranges.rs:6:18: 6:25 StorageDead(_5); // scope 1 at $DIR/storage_ranges.rs:6:24: 6:25 _3 = &_4; // scope 1 at $DIR/storage_ranges.rs:6:17: 6:25 - FakeRead(ForLet, _3); // scope 1 at $DIR/storage_ranges.rs:6:13: 6:14 + FakeRead(ForLet(None), _3); // scope 1 at $DIR/storage_ranges.rs:6:13: 6:14 _2 = const (); // scope 1 at $DIR/storage_ranges.rs:5:5: 7:6 StorageDead(_4); // scope 1 at $DIR/storage_ranges.rs:7:5: 7:6 StorageDead(_3); // scope 1 at $DIR/storage_ranges.rs:7:5: 7:6 StorageDead(_2); // scope 1 at $DIR/storage_ranges.rs:7:5: 7:6 StorageLive(_6); // scope 1 at $DIR/storage_ranges.rs:8:9: 8:10 _6 = const 1_i32; // scope 1 at $DIR/storage_ranges.rs:8:13: 8:14 - FakeRead(ForLet, _6); // scope 1 at $DIR/storage_ranges.rs:8:9: 8:10 + FakeRead(ForLet(None), _6); // scope 1 at $DIR/storage_ranges.rs:8:9: 8:10 _0 = const (); // scope 0 at $DIR/storage_ranges.rs:3:11: 9:2 StorageDead(_6); // scope 1 at $DIR/storage_ranges.rs:9:1: 9:2 StorageDead(_1); // scope 0 at $DIR/storage_ranges.rs:9:1: 9:2 diff --git a/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir index d18f6308ded..7f81d9fc482 100644 --- a/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir +++ b/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir @@ -48,7 +48,7 @@ fn move_out_by_subslice() -> () { bb4: { StorageDead(_2); // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27 - FakeRead(ForLet, _1); // scope 0 at $DIR/uniform_array_move_out.rs:11:9: 11:10 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/uniform_array_move_out.rs:11:9: 11:10 StorageLive(_6); // scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17 _6 = move _1[0..2]; // scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17 _0 = const (); // scope 0 at $DIR/uniform_array_move_out.rs:10:27: 13:2 diff --git a/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir index eda8e5fd3af..62ab494c066 100644 --- a/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir +++ b/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir @@ -48,7 +48,7 @@ fn move_out_from_end() -> () { bb4: { StorageDead(_2); // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27 - FakeRead(ForLet, _1); // scope 0 at $DIR/uniform_array_move_out.rs:5:9: 5:10 + FakeRead(ForLet(None), _1); // scope 0 at $DIR/uniform_array_move_out.rs:5:9: 5:10 StorageLive(_6); // scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16 _6 = move _1[1 of 2]; // scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16 _0 = const (); // scope 0 at $DIR/uniform_array_move_out.rs:4:24: 7:2 From 0a97eee8df1f4a3182cd92786258ee5cf2baa43f Mon Sep 17 00:00:00 2001 From: Roxane Date: Mon, 29 Mar 2021 22:48:44 -0400 Subject: [PATCH 307/370] Reduce size of statements --- compiler/rustc_middle/src/mir/mod.rs | 8 +++++--- compiler/rustc_middle/src/mir/visit.rs | 2 +- .../src/borrow_check/diagnostics/conflict_errors.rs | 2 +- .../src/borrow_check/diagnostics/explain_borrow.rs | 2 +- compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs | 2 +- compiler/rustc_mir/src/borrow_check/invalidation.rs | 2 +- compiler/rustc_mir/src/borrow_check/mod.rs | 2 +- compiler/rustc_mir/src/dataflow/move_paths/builder.rs | 4 ++-- compiler/rustc_mir/src/transform/coverage/spans.rs | 4 ++-- compiler/rustc_mir_build/src/build/cfg.rs | 2 +- 10 files changed, 16 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 1f7e12db47a..a7e9fc468b4 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1452,7 +1452,7 @@ pub struct Statement<'tcx> { // `Statement` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(Statement<'_>, 40); +static_assert_size!(Statement<'_>, 32); impl Statement<'_> { /// Changes a statement to a nop. This is both faster than deleting instructions and avoids @@ -1482,7 +1482,7 @@ pub enum StatementKind<'tcx> { /// /// Note that this also is emitted for regular `let` bindings to ensure that locals that are /// never accessed still get some sanity checks for, e.g., `let x: ! = ..;` - FakeRead(FakeReadCause, Box>), + FakeRead(Box<(FakeReadCause, Place<'tcx>)>), /// Write the discriminant for a variant to the enum Place. SetDiscriminant { place: Box>, variant_index: VariantIdx }, @@ -1628,7 +1628,9 @@ impl Debug for Statement<'_> { use self::StatementKind::*; match self.kind { Assign(box (ref place, ref rv)) => write!(fmt, "{:?} = {:?}", place, rv), - FakeRead(ref cause, ref place) => write!(fmt, "FakeRead({:?}, {:?})", cause, place), + FakeRead(box (ref cause, ref place)) => { + write!(fmt, "FakeRead({:?}, {:?})", cause, place) + } Retag(ref kind, ref place) => write!( fmt, "Retag({}{:?})", diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 32b4cd665d0..fd504f8c5d5 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -380,7 +380,7 @@ macro_rules! make_mir_visitor { ) => { self.visit_assign(place, rvalue, location); } - StatementKind::FakeRead(_, place) => { + StatementKind::FakeRead(box (_, place)) => { self.visit_place( place, PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect), diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs index eb942b195b2..d5deec82088 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs @@ -1728,7 +1728,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'tcx> { fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) { match statement { - Statement { kind: StatementKind::FakeRead(cause, box place), .. } + Statement { kind: StatementKind::FakeRead(box (cause, place)), .. } if *place == self.place => { self.cause = Some(*cause); diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs index 4ab0fe08259..2a388b8a72b 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs @@ -515,7 +515,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let block = &self.body.basic_blocks()[location.block]; let kind = if let Some(&Statement { - kind: StatementKind::FakeRead(FakeReadCause::ForLet(_), _), + kind: StatementKind::FakeRead(box (FakeReadCause::ForLet(_), _)), .. }) = block.statements.get(location.statement_index) { diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs index 6a457487348..577d7d53814 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs @@ -797,7 +797,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // StatementKind::FakeRead only contains a def_id if they are introduced as a result // of pattern matching within a closure. - if let StatementKind::FakeRead(cause, box ref place) = stmt.kind { + if let StatementKind::FakeRead(box (cause, ref place)) = stmt.kind { match cause { FakeReadCause::ForMatchedPlace(Some(closure_def_id)) | FakeReadCause::ForLet(Some(closure_def_id)) => { diff --git a/compiler/rustc_mir/src/borrow_check/invalidation.rs b/compiler/rustc_mir/src/borrow_check/invalidation.rs index 1055e30a3a4..9374741f837 100644 --- a/compiler/rustc_mir/src/borrow_check/invalidation.rs +++ b/compiler/rustc_mir/src/borrow_check/invalidation.rs @@ -63,7 +63,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { self.mutate_place(location, *lhs, Shallow(None), JustWrite); } - StatementKind::FakeRead(_, _) => { + StatementKind::FakeRead(box (_, _)) => { // Only relevant for initialized/liveness/safety checks. } StatementKind::SetDiscriminant { place, variant_index: _ } => { diff --git a/compiler/rustc_mir/src/borrow_check/mod.rs b/compiler/rustc_mir/src/borrow_check/mod.rs index 583f73d5775..71db6abde43 100644 --- a/compiler/rustc_mir/src/borrow_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/mod.rs @@ -574,7 +574,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc self.mutate_place(location, (*lhs, span), Shallow(None), JustWrite, flow_state); } - StatementKind::FakeRead(_, box ref place) => { + StatementKind::FakeRead(box (_, ref place)) => { // Read for match doesn't access any memory and is used to // assert that a place is safe and live. So we don't have to // do any checks here. diff --git a/compiler/rustc_mir/src/dataflow/move_paths/builder.rs b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs index 52b6e9f3753..538d8921869 100644 --- a/compiler/rustc_mir/src/dataflow/move_paths/builder.rs +++ b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs @@ -293,8 +293,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { } self.gather_rvalue(rval); } - StatementKind::FakeRead(_, place) => { - self.create_move_path(**place); + StatementKind::FakeRead(box (_, place)) => { + self.create_move_path(*place); } StatementKind::LlvmInlineAsm(ref asm) => { for (output, kind) in iter::zip(&*asm.outputs, &asm.asm.outputs) { diff --git a/compiler/rustc_mir/src/transform/coverage/spans.rs b/compiler/rustc_mir/src/transform/coverage/spans.rs index e7097ce8619..324d826b375 100644 --- a/compiler/rustc_mir/src/transform/coverage/spans.rs +++ b/compiler/rustc_mir/src/transform/coverage/spans.rs @@ -683,10 +683,10 @@ pub(super) fn filtered_statement_span( // and `_1` is the `Place` for `somenum`. // // If and when the Issue is resolved, remove this special case match pattern: - StatementKind::FakeRead(cause, _) if cause == FakeReadCause::ForGuardBinding => None, + StatementKind::FakeRead(box (cause, _)) if cause == FakeReadCause::ForGuardBinding => None, // Retain spans from all other statements - StatementKind::FakeRead(_, _) // Not including `ForGuardBinding` + StatementKind::FakeRead(box (_, _)) // Not including `ForGuardBinding` | StatementKind::CopyNonOverlapping(..) | StatementKind::Assign(_) | StatementKind::SetDiscriminant { .. } diff --git a/compiler/rustc_mir_build/src/build/cfg.rs b/compiler/rustc_mir_build/src/build/cfg.rs index e562e52f841..fd4a783d12a 100644 --- a/compiler/rustc_mir_build/src/build/cfg.rs +++ b/compiler/rustc_mir_build/src/build/cfg.rs @@ -80,7 +80,7 @@ impl<'tcx> CFG<'tcx> { cause: FakeReadCause, place: Place<'tcx>, ) { - let kind = StatementKind::FakeRead(cause, box place); + let kind = StatementKind::FakeRead(box (cause, place)); let stmt = Statement { source_info, kind }; self.push(block, stmt); } From c29dc120e5e43a4757d8f7f20db35c61767fe987 Mon Sep 17 00:00:00 2001 From: Roxane Date: Tue, 30 Mar 2021 00:30:20 -0400 Subject: [PATCH 308/370] fix clippy error --- 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 1391f7505e2..dac4d93499d 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 @@ -212,7 +212,7 @@ fn check_statement(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, statemen check_rvalue(tcx, body, def_id, rval, span) } - StatementKind::FakeRead(_, place) | + StatementKind::FakeRead(box (_, place)) => check_place(tcx, *place, span, body), // just an assignment StatementKind::SetDiscriminant { place, .. } => check_place(tcx, **place, span, body), From 7ceff6835abc3ce991e1a8cdcbe2be2730335a65 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Fri, 2 Apr 2021 00:08:48 -0700 Subject: [PATCH 309/370] Translate counters from Rust 1-based to LLVM 0-based counter ids A colleague contacted me and asked why Rust's counters start at 1, when Clangs appear to start at 0. There is a reason why Rust's internal counters start at 1 (see the docs), and I tried to keep them consistent when codegenned to LLVM's coverage mapping format. LLVM should be tolerant of missing counters, but as my colleague pointed out, `llvm-cov` will silently fail to generate a coverage report for a function based on LLVM's assumption that the counters are 0-based. See: https://github.com/llvm/llvm-project/blob/main/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp#L170 Apparently, if, for example, a function has no branches, it would have exactly 1 counter. `CounterValues.size()` would be 1, and (with the 1-based index), the counter ID would be 1. This would fail the check and abort reporting coverage for the function. It turns out that by correcting for this during coverage map generation, by subtracting 1 from the Rust Counter ID (both when generating the counter increment intrinsic call, and when adding counters to the map), some uncovered functions (including in tests) now appear covered! This corrects the coverage for a few tests! --- .../src/coverageinfo/mod.rs | 8 +- .../rustc_codegen_ssa/src/coverageinfo/ffi.rs | 22 +++++- .../rustc_codegen_ssa/src/coverageinfo/map.rs | 77 +++++++++++++++---- .../rustc_codegen_ssa/src/mir/coverageinfo.rs | 2 +- compiler/rustc_middle/src/mir/coverage.rs | 20 ++++- .../expected_show_coverage.async.txt | 27 +++---- .../expected_show_coverage.doctest.txt | 2 +- .../expected_show_coverage.inline.txt | 6 +- .../expected_show_coverage.loops_branches.txt | 70 ++++++++++++----- src/test/run-make-fulldeps/coverage/async.rs | 23 ++---- .../coverage/loops_branches.rs | 51 ++++++++---- 11 files changed, 212 insertions(+), 96 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 32f4fc76b3d..afc2bdbfd52 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -250,13 +250,9 @@ fn add_unused_function_coverage( // Insert at least one real counter so the LLVM CoverageMappingReader will find expected // definitions. function_coverage.add_counter(UNUSED_FUNCTION_COUNTER_ID, code_region.clone()); + } else { + function_coverage.add_unreachable_region(code_region.clone()); } - // Add a Zero Counter for every code region. - // - // Even though the first coverage region already has an actual Counter, `llvm-cov` will not - // always report it. Re-adding an unreachable region (zero counter) for the same region - // seems to help produce the expected coverage. - function_coverage.add_unreachable_region(code_region.clone()); } if let Some(coverage_context) = cx.coverage_context() { diff --git a/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs index af6c476292b..962c01c2ee7 100644 --- a/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs +++ b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs @@ -24,21 +24,39 @@ pub enum CounterKind { pub struct Counter { // Important: The layout (order and types of fields) must match its C++ counterpart. pub kind: CounterKind, - pub id: u32, + id: u32, } impl Counter { + /// Constructs a new `Counter` of kind `Zero`. For this `CounterKind`, the + /// `id` is not used. pub fn zero() -> Self { Self { kind: CounterKind::Zero, id: 0 } } + /// Constructs a new `Counter` of kind `CounterValueReference`, and converts + /// the given 1-based counter_id to the required 0-based equivalent for + /// the `Counter` encoding. pub fn counter_value_reference(counter_id: CounterValueReference) -> Self { - Self { kind: CounterKind::CounterValueReference, id: counter_id.into() } + Self { kind: CounterKind::CounterValueReference, id: counter_id.zero_based_index() } } + /// Constructs a new `Counter` of kind `Expression`. pub fn expression(mapped_expression_index: MappedExpressionIndex) -> Self { Self { kind: CounterKind::Expression, id: mapped_expression_index.into() } } + + /// Returns true if the `Counter` kind is `Zero`. + pub fn is_zero(&self) -> bool { + matches!(self.kind, CounterKind::Zero) + } + + /// An explicitly-named function to get the ID value, making it more obvious + /// that the stored value is now 0-based. + pub fn zero_based_id(&self) -> u32 { + debug_assert!(!self.is_zero(), "`id` is undefined for CounterKind::Zero"); + self.id + } } /// Aligns with [llvm::coverage::CounterExpression::ExprKind](https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L147) diff --git a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs index 7a17bced1c0..4458fd68678 100644 --- a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs +++ b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs @@ -163,9 +163,7 @@ impl<'tcx> FunctionCoverage<'tcx> { self.counters.iter_enumerated().filter_map(|(index, entry)| { // Option::map() will return None to filter out missing counters. This may happen // if, for example, a MIR-instrumented counter is removed during an optimization. - entry.as_ref().map(|region| { - (Counter::counter_value_reference(index as CounterValueReference), region) - }) + entry.as_ref().map(|region| (Counter::counter_value_reference(index), region)) }) } @@ -206,9 +204,15 @@ impl<'tcx> FunctionCoverage<'tcx> { if id == ExpressionOperandId::ZERO { Some(Counter::zero()) } else if id.index() < self.counters.len() { + debug_assert!( + id.index() > 0, + "ExpressionOperandId indexes for counters are 1-based, but this id={}", + id.index() + ); // Note: Some codegen-injected Counters may be only referenced by `Expression`s, // and may not have their own `CodeRegion`s, let index = CounterValueReference::from(id.index()); + // Note, the conversion to LLVM `Counter` adjusts the index to be zero-based. Some(Counter::counter_value_reference(index)) } else { let index = self.expression_index(u32::from(id)); @@ -233,19 +237,60 @@ impl<'tcx> FunctionCoverage<'tcx> { let optional_region = &expression.region; let Expression { lhs, op, rhs, .. } = *expression; - if let Some(Some((lhs_counter, rhs_counter))) = - id_to_counter(&new_indexes, lhs).map(|lhs_counter| { + if let Some(Some((lhs_counter, mut rhs_counter))) = id_to_counter(&new_indexes, lhs) + .map(|lhs_counter| { id_to_counter(&new_indexes, rhs).map(|rhs_counter| (lhs_counter, rhs_counter)) }) { + if lhs_counter.is_zero() && op.is_subtract() { + // The left side of a subtraction was probably optimized out. As an example, + // a branch condition might be evaluated as a constant expression, and the + // branch could be removed, dropping unused counters in the process. + // + // Since counters are unsigned, we must assume the result of the expression + // can be no more and no less than zero. An expression known to evaluate to zero + // does not need to be added to the coverage map. + // + // Coverage test `loops_branches.rs` includes multiple variations of branches + // based on constant conditional (literal `true` or `false`), and demonstrates + // that the expected counts are still correct. + debug!( + "Expression subtracts from zero (assume unreachable): \ + original_index={:?}, lhs={:?}, op={:?}, rhs={:?}, region={:?}", + original_index, lhs, op, rhs, optional_region, + ); + rhs_counter = Counter::zero(); + } debug_assert!( - (lhs_counter.id as usize) - < usize::max(self.counters.len(), self.expressions.len()) + lhs_counter.is_zero() + // Note: with `as usize` the ID _could_ overflow/wrap if `usize = u16` + || ((lhs_counter.zero_based_id() as usize) + <= usize::max(self.counters.len(), self.expressions.len())), + "lhs id={} > both counters.len()={} and expressions.len()={} + ({:?} {:?} {:?})", + lhs_counter.zero_based_id(), + self.counters.len(), + self.expressions.len(), + lhs_counter, + op, + rhs_counter, ); + debug_assert!( - (rhs_counter.id as usize) - < usize::max(self.counters.len(), self.expressions.len()) + rhs_counter.is_zero() + // Note: with `as usize` the ID _could_ overflow/wrap if `usize = u16` + || ((rhs_counter.zero_based_id() as usize) + <= usize::max(self.counters.len(), self.expressions.len())), + "rhs id={} > both counters.len()={} and expressions.len()={} + ({:?} {:?} {:?})", + rhs_counter.zero_based_id(), + self.counters.len(), + self.expressions.len(), + lhs_counter, + op, + rhs_counter, ); + // Both operands exist. `Expression` operands exist in `self.expressions` and have // been assigned a `new_index`. let mapped_expression_index = @@ -268,11 +313,15 @@ impl<'tcx> FunctionCoverage<'tcx> { expression_regions.push((Counter::expression(mapped_expression_index), region)); } } else { - debug!( - "Ignoring expression with one or more missing operands: \ - original_index={:?}, lhs={:?}, op={:?}, rhs={:?}, region={:?}", - original_index, lhs, op, rhs, optional_region, - ) + bug!( + "expression has one or more missing operands \ + original_index={:?}, lhs={:?}, op={:?}, rhs={:?}, region={:?}", + original_index, + lhs, + op, + rhs, + optional_region, + ); } } (counter_expressions, expression_regions.into_iter()) diff --git a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs index e2f75b2e337..621ec0519c9 100644 --- a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs @@ -36,7 +36,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let fn_name = bx.get_pgo_func_name_var(instance); let hash = bx.const_u64(function_source_hash); let num_counters = bx.const_u32(coverageinfo.num_counters); - let index = bx.const_u32(u32::from(id)); + let index = bx.const_u32(id.zero_based_index()); debug!( "codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})", fn_name, hash, num_counters, index, diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index ad48b236a9a..ddb1a84fe7b 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -41,8 +41,16 @@ rustc_index::newtype_index! { } impl CounterValueReference { - // Counters start at 1 to reserve 0 for ExpressionOperandId::ZERO. + /// Counters start at 1 to reserve 0 for ExpressionOperandId::ZERO. pub const START: Self = Self::from_u32(1); + + /// Returns explicitly-requested zero-based version of the counter id, used + /// during codegen. LLVM expects zero-based indexes. + pub fn zero_based_index(&self) -> u32 { + let one_based_index = self.as_u32(); + debug_assert!(one_based_index > 0); + one_based_index - 1 + } } rustc_index::newtype_index! { @@ -175,3 +183,13 @@ pub enum Op { Subtract, Add, } + +impl Op { + pub fn is_add(&self) -> bool { + matches!(self, Self::Add) + } + + pub fn is_subtract(&self) -> bool { + matches!(self, Self::Subtract) + } +} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt index d9097bb50e5..e0a5937c246 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt @@ -10,7 +10,7 @@ 10| | } 11| 1|} 12| | - 13| |async fn d() -> u8 { 1 } // should have a coverage count `0` (see below) + 13| 0|async fn d() -> u8 { 1 } 14| | 15| 0|async fn e() -> u8 { 1 } // unused function; executor does not block on `g()` 16| | @@ -66,7 +66,8 @@ 63| 1| 0 64| 1| } 65| 1| } - 66| 1| fn d() -> u8 { 1 } + 66| 1| fn d() -> u8 { 1 } // inner function is defined in-line, but the function is not executed + ^0 67| 1| fn f() -> u8 { 1 } 68| 1| match x { 69| 1| y if c(x) == y + 1 => { d(); } @@ -115,11 +116,14 @@ 109| | 110| 1| pub fn block_on(mut future: F) -> F::Output { 111| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) }; - 112| 1| + 112| 1| use std::hint::unreachable_unchecked; 113| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new( - 114| 1| |_| unimplemented!("clone"), - 115| 1| |_| unimplemented!("wake"), - 116| 1| |_| unimplemented!("wake_by_ref"), + 114| 1| |_| unsafe { unreachable_unchecked() }, // clone + ^0 + 115| 1| |_| unsafe { unreachable_unchecked() }, // wake + ^0 + 116| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref + ^0 117| 1| |_| (), 118| 1| ); 119| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; @@ -132,15 +136,4 @@ 126| | } 127| 1| } 128| |} - 129| | - 130| |// `llvm-cov show` shows no coverage results for the `d()`, even though the - 131| |// crate's LLVM IR shows the function exists and has an InstrProf PGO counter, - 132| |// and appears to be registered like all other counted functions. - 133| |// - 134| |// `llvm-cov show --debug` output shows there is at least one `Counter` for this - 135| |// line, but counters do not appear in the `Combined regions` section (unlike - 136| |// `f()`, which is similar, but does appear in `Combined regions`, and does show - 137| |// coverage). The only difference is, `f()` is awaited, but the call to await - 138| |// `d()` is not reached. (Note: `d()` will appear in coverage if the test is - 139| |// modified to cause it to be awaited.) diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt index 7d2abe05973..1b6bb9ff889 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt @@ -56,7 +56,7 @@ 46| 1|//! println!("called some_func()"); 47| 1|//! } 48| |//! - 49| |//! #[derive(Debug)] + 49| 0|//! #[derive(Debug)] 50| |//! struct SomeError; 51| |//! 52| |//! extern crate doctest_crate; diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline.txt index 6148d89ed75..31d3ddea8d9 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline.txt @@ -47,7 +47,7 @@ 46| 6|} 47| | 48| |#[inline(always)] - 49| |fn error() { - 50| | panic!("error"); - 51| |} + 49| 0|fn error() { + 50| 0| panic!("error"); + 51| 0|} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loops_branches.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loops_branches.txt index 474f02b7007..81d5c7d9034 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loops_branches.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loops_branches.txt @@ -1,7 +1,7 @@ 1| |#![allow(unused_assignments, unused_variables, while_true)] 2| | - 3| |// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the - 4| |// structure of this `fmt` function. + 3| |// This test confirms that (1) unexecuted infinite loops are handled correctly by the + 4| |// InstrumentCoverage MIR pass; and (2) Counter Expressions that subtract from zero can be dropped. 5| | 6| |struct DebugTest; 7| | @@ -16,23 +16,51 @@ ^0 16| | } else { 17| | } - 18| 1| Ok(()) - 19| 1| } - 20| |} - 21| | - 22| 1|fn main() { - 23| 1| let debug_test = DebugTest; - 24| 1| println!("{:?}", debug_test); - 25| 1|} - 26| | - 27| |/* - 28| | - 29| |This is the error message generated, before the issue was fixed: - 30| | - 31| |error: internal compiler error: compiler/rustc_mir/src/transform/coverage/mod.rs:374:42: - 32| |Error processing: DefId(0:6 ~ bug_incomplete_cov_graph_traversal_simplified[317d]::{impl#0}::fmt): - 33| |Error { message: "`TraverseCoverageGraphWithLoops` missed some `BasicCoverageBlock`s: - 34| |[bcb6, bcb7, bcb9]" } - 35| | - 36| |*/ + 18| | + 19| 10| for i in 0..10 { + 20| 10| if true { + 21| 10| if false { + 22| | while true {} + 23| 10| } + 24| 10| write!(f, "error")?; + ^0 + 25| | } else { + 26| | } + 27| | } + 28| 1| Ok(()) + 29| 1| } + 30| |} + 31| | + 32| |struct DisplayTest; + 33| | + 34| |impl std::fmt::Display for DisplayTest { + 35| 1| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + 36| 1| if false { + 37| | } else { + 38| 1| if false { + 39| | while true {} + 40| 1| } + 41| 1| write!(f, "error")?; + ^0 + 42| | } + 43| 10| for i in 0..10 { + 44| 10| if false { + 45| | } else { + 46| 10| if false { + 47| | while true {} + 48| 10| } + 49| 10| write!(f, "error")?; + ^0 + 50| | } + 51| | } + 52| 1| Ok(()) + 53| 1| } + 54| |} + 55| | + 56| 1|fn main() { + 57| 1| let debug_test = DebugTest; + 58| 1| println!("{:?}", debug_test); + 59| 1| let display_test = DisplayTest; + 60| 1| println!("{}", display_test); + 61| 1|} diff --git a/src/test/run-make-fulldeps/coverage/async.rs b/src/test/run-make-fulldeps/coverage/async.rs index f08a7b44fbd..67bf696d072 100644 --- a/src/test/run-make-fulldeps/coverage/async.rs +++ b/src/test/run-make-fulldeps/coverage/async.rs @@ -10,7 +10,7 @@ async fn c(x: u8) -> u8 { } } -async fn d() -> u8 { 1 } // should have a coverage count `0` (see below) +async fn d() -> u8 { 1 } async fn e() -> u8 { 1 } // unused function; executor does not block on `g()` @@ -63,7 +63,7 @@ fn j(x: u8) { 0 } } - fn d() -> u8 { 1 } + fn d() -> u8 { 1 } // inner function is defined in-line, but the function is not executed fn f() -> u8 { 1 } match x { y if c(x) == y + 1 => { d(); } @@ -109,11 +109,11 @@ mod executor { pub fn block_on(mut future: F) -> F::Output { let mut future = unsafe { Pin::new_unchecked(&mut future) }; - + use std::hint::unreachable_unchecked; static VTABLE: RawWakerVTable = RawWakerVTable::new( - |_| unimplemented!("clone"), - |_| unimplemented!("wake"), - |_| unimplemented!("wake_by_ref"), + |_| unsafe { unreachable_unchecked() }, // clone + |_| unsafe { unreachable_unchecked() }, // wake + |_| unsafe { unreachable_unchecked() }, // wake_by_ref |_| (), ); let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; @@ -126,14 +126,3 @@ mod executor { } } } - -// `llvm-cov show` shows no coverage results for the `d()`, even though the -// crate's LLVM IR shows the function exists and has an InstrProf PGO counter, -// and appears to be registered like all other counted functions. -// -// `llvm-cov show --debug` output shows there is at least one `Counter` for this -// line, but counters do not appear in the `Combined regions` section (unlike -// `f()`, which is similar, but does appear in `Combined regions`, and does show -// coverage). The only difference is, `f()` is awaited, but the call to await -// `d()` is not reached. (Note: `d()` will appear in coverage if the test is -// modified to cause it to be awaited.) diff --git a/src/test/run-make-fulldeps/coverage/loops_branches.rs b/src/test/run-make-fulldeps/coverage/loops_branches.rs index 938421d32e7..4d9bbad3367 100644 --- a/src/test/run-make-fulldeps/coverage/loops_branches.rs +++ b/src/test/run-make-fulldeps/coverage/loops_branches.rs @@ -1,7 +1,7 @@ #![allow(unused_assignments, unused_variables, while_true)] -// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the -// structure of this `fmt` function. +// This test confirms that (1) unexecuted infinite loops are handled correctly by the +// InstrumentCoverage MIR pass; and (2) Counter Expressions that subtract from zero can be dropped. struct DebugTest; @@ -15,6 +15,40 @@ impl std::fmt::Debug for DebugTest { write!(f, "error")?; } else { } + + for i in 0..10 { + if true { + if false { + while true {} + } + write!(f, "error")?; + } else { + } + } + Ok(()) + } +} + +struct DisplayTest; + +impl std::fmt::Display for DisplayTest { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + if false { + } else { + if false { + while true {} + } + write!(f, "error")?; + } + for i in 0..10 { + if false { + } else { + if false { + while true {} + } + write!(f, "error")?; + } + } Ok(()) } } @@ -22,15 +56,6 @@ impl std::fmt::Debug for DebugTest { fn main() { let debug_test = DebugTest; println!("{:?}", debug_test); + let display_test = DisplayTest; + println!("{}", display_test); } - -/* - -This is the error message generated, before the issue was fixed: - -error: internal compiler error: compiler/rustc_mir/src/transform/coverage/mod.rs:374:42: -Error processing: DefId(0:6 ~ bug_incomplete_cov_graph_traversal_simplified[317d]::{impl#0}::fmt): -Error { message: "`TraverseCoverageGraphWithLoops` missed some `BasicCoverageBlock`s: -[bcb6, bcb7, bcb9]" } - -*/ From f64038f9833f1940f64276fcab9bd53f21f9443b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 2 Apr 2021 17:46:12 -0700 Subject: [PATCH 310/370] rustdoc: update macro highlight tests --- src/librustdoc/html/highlight/fixtures/dos_line.html | 2 +- src/librustdoc/html/highlight/fixtures/sample.html | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/highlight/fixtures/dos_line.html b/src/librustdoc/html/highlight/fixtures/dos_line.html index 4400f85681d..1c8dbffe78c 100644 --- a/src/librustdoc/html/highlight/fixtures/dos_line.html +++ b/src/librustdoc/html/highlight/fixtures/dos_line.html @@ -1,3 +1,3 @@ pub fn foo() { -println!("foo"); +println!("foo"); } diff --git a/src/librustdoc/html/highlight/fixtures/sample.html b/src/librustdoc/html/highlight/fixtures/sample.html index d937246f466..4966e0ac6bb 100644 --- a/src/librustdoc/html/highlight/fixtures/sample.html +++ b/src/librustdoc/html/highlight/fixtures/sample.html @@ -17,11 +17,11 @@ let _ = &foo; let _ = &&foo; let _ = *foo; - mac!(foo, &mut bar); - assert!(self.length < N && index <= self.length); + mac!(foo, &mut bar); + assert!(self.length < N && index <= self.length); } -macro_rules! bar { +macro_rules! bar { ($foo:tt) => {}; } From c35a36f9b339af147bc24016543bfec50085ba05 Mon Sep 17 00:00:00 2001 From: Anthony Huang Date: Wed, 14 Oct 2020 21:29:47 -0700 Subject: [PATCH 311/370] tidy: Add ignore-rules for the line length check This is step 1 towards fixing #77548. This commit includes the tidy change from #77675. The "ignoring file length unnecessarily" check is temporarily disabled to simplify landing the ignore-rules. That check will be re-enabled in a follow-up PR. --- src/tools/compiletest/src/runtest.rs | 2 ++ src/tools/tidy/src/style.rs | 36 +++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 7e6c21b824d..a2a53c16b78 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -3650,6 +3650,8 @@ impl<'test> TestCx<'test> { // Remove test annotations like `//~ ERROR text` from the output, // since they duplicate actual errors and make the output hard to read. + // This mirrors the regex in src/tools/tidy/src/style.rs, please update + // both if either are changed. normalized = Regex::new("\\s*//(\\[.*\\])?~.*").unwrap().replace_all(&normalized, "").into_owned(); diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 75c43343023..e99dd453280 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -16,6 +16,7 @@ //! A number of these checks can be opted-out of with various directives of the form: //! `// ignore-tidy-CHECK-NAME`. +use regex::Regex; use std::path::Path; /// Error code markdown is restricted to 80 columns because they can be @@ -41,6 +42,19 @@ C++ code used llvm_unreachable, which triggers undefined behavior when executed when assertions are disabled. Use llvm::report_fatal_error for increased robustness."; +const ANNOTATIONS_TO_IGNORE: &[&str] = &[ + "// @!has", + "// @has", + "// @matches", + "// CHECK", + "// EMIT_MIR", + "// compile-flags", + "// error-pattern", + "// gdb", + "// lldb", + "// normalize-stderr-test", +]; + /// Parser states for `line_is_url`. #[derive(Clone, Copy, PartialEq)] #[allow(non_camel_case_types)] @@ -92,12 +106,20 @@ fn line_is_url(is_error_code: bool, columns: usize, line: &str) -> bool { state == EXP_END } +/// Returns `true` if `line` can be ignored. This is the case when it contains +/// an annotation that is explicitly ignored. +fn should_ignore(line: &str) -> bool { + // Matches test annotations like `//~ ERROR text`. + // This mirrors the regex in src/tools/compiletest/src/runtest.rs, please + // update both if either are changed. + let re = Regex::new("\\s*//(\\[.*\\])?~.*").unwrap(); + re.is_match(line) || ANNOTATIONS_TO_IGNORE.iter().any(|a| line.contains(a)) +} + /// Returns `true` if `line` is allowed to be longer than the normal limit. -/// Currently there is only one exception, for long URLs, but more -/// may be added in the future. fn long_line_is_ok(extension: &str, is_error_code: bool, max_columns: usize, line: &str) -> bool { if extension != "md" || is_error_code { - if line_is_url(is_error_code, max_columns, line) { + if line_is_url(is_error_code, max_columns, line) || should_ignore(line) { return true; } } else if extension == "md" { @@ -357,9 +379,11 @@ pub fn check(path: &Path, bad: &mut bool) { if let Directive::Ignore(false) = skip_tab { tidy_error!(bad, "{}: ignoring tab characters unnecessarily", file.display()); } - if let Directive::Ignore(false) = skip_line_length { - tidy_error!(bad, "{}: ignoring line length unnecessarily", file.display()); - } + // FIXME: Temporarily disabled to simplify landing the ignore-rules for the line + // length check (https://github.com/rust-lang/rust/issues/77548): + //if let Directive::Ignore(false) = skip_line_length { + // tidy_error!(bad, "{}: ignoring line length unnecessarily", file.display()); + //} if let Directive::Ignore(false) = skip_file_length { tidy_error!(bad, "{}: ignoring file length unnecessarily", file.display()); } From 944b53eb75e7b7e64fa8479f06aeaca0fd7e34bb Mon Sep 17 00:00:00 2001 From: surechen Date: Sat, 3 Apr 2021 15:50:59 +0800 Subject: [PATCH 312/370] add fp-armv8 for ARM_ALLOWED_FEATURES --- compiler/rustc_codegen_ssa/src/target_features.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index fd18f42f2dd..a69e6d2b86d 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -26,6 +26,7 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option)] = &[ ("vfp2", Some(sym::arm_target_feature)), ("vfp3", Some(sym::arm_target_feature)), ("vfp4", Some(sym::arm_target_feature)), + ("fp-armv8", Some(sym::arm_target_feature)), // This is needed for inline assembly, but shouldn't be stabilized as-is // since it should be enabled per-function using #[instruction_set], not // #[target_feature]. From 3cfa0a0dff610e228819579709c035c9a1d4310b Mon Sep 17 00:00:00 2001 From: Wilco Kusee Date: Sat, 3 Apr 2021 10:00:09 +0200 Subject: [PATCH 313/370] Remove nightly features in rustc_type_ir --- compiler/rustc_index/src/vec.rs | 4 ++-- compiler/rustc_type_ir/src/lib.rs | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 3882818952c..6b29079109e 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -124,7 +124,7 @@ macro_rules! newtype_index { #[inline] $v const fn from_usize(value: usize) -> Self { - assert!(value <= ($max as usize)); + [()][(value > ($max as usize)) as usize]; unsafe { Self::from_u32_unchecked(value as u32) } @@ -132,7 +132,7 @@ macro_rules! newtype_index { #[inline] $v const fn from_u32(value: u32) -> Self { - assert!(value <= $max); + [()][(value > $max) as usize]; unsafe { Self::from_u32_unchecked(value) } diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index fccd8b795ef..8fcdf813b41 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -1,7 +1,3 @@ -#![feature(never_type)] -#![feature(const_panic)] -#![feature(control_flow_enum)] - #[macro_use] extern crate bitflags; #[macro_use] From 3ea7c90a947132977ddb95024bbf05faea851fd9 Mon Sep 17 00:00:00 2001 From: Wilco Kusee Date: Sat, 3 Apr 2021 13:07:03 +0200 Subject: [PATCH 314/370] Add fixme comment to revert change once const_panic is stable --- compiler/rustc_index/src/vec.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 6b29079109e..1b1a59a254e 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -124,6 +124,7 @@ macro_rules! newtype_index { #[inline] $v const fn from_usize(value: usize) -> Self { + // FIXME: replace with `assert!(value <= ($max as usize));` once `const_panic` is stable [()][(value > ($max as usize)) as usize]; unsafe { Self::from_u32_unchecked(value as u32) @@ -132,6 +133,7 @@ macro_rules! newtype_index { #[inline] $v const fn from_u32(value: u32) -> Self { + // FIXME: replace with `assert!(value <= $max);` once `const_panic` is stable [()][(value > $max) as usize]; unsafe { Self::from_u32_unchecked(value) From bda6d1f158a71efe84d86da2011eac0c45a232c5 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 3 Apr 2021 14:51:05 +0200 Subject: [PATCH 315/370] Add safety comment to StableAddress impl for Mmap --- compiler/rustc_data_structures/src/memmap.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_data_structures/src/memmap.rs b/compiler/rustc_data_structures/src/memmap.rs index 29e999efeb1..26b26415eea 100644 --- a/compiler/rustc_data_structures/src/memmap.rs +++ b/compiler/rustc_data_structures/src/memmap.rs @@ -40,4 +40,8 @@ impl Deref for Mmap { } } +// SAFETY: On architectures other than WASM, mmap is used as backing storage. The address of this +// memory map is stable. On WASM, `Vec` is used as backing storage. The `Mmap` type doesn't +// export any function that can cause the `Vec` to be re-allocated. As such the address of the +// bytes inside this `Vec` is stable. unsafe impl StableAddress for Mmap {} From 7b05cffa185a3ea5f9e0e3308bef8b6043a9a341 Mon Sep 17 00:00:00 2001 From: Ben Mezger Date: Sat, 3 Apr 2021 12:00:28 -0300 Subject: [PATCH 316/370] Fix rustc_lint_defs documentation typo --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index b602490905c..27724b4965c 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -547,7 +547,7 @@ declare_lint! { /// Also consider if you intended to use an _inner attribute_ (with a `!` /// such as `#![allow(unused)]`) which applies to the item the attribute /// is within, or an _outer attribute_ (without a `!` such as - /// `#[allow(unsued)]`) which applies to the item *following* the + /// `#[allow(unused)]`) which applies to the item *following* the /// attribute. /// /// [attributes]: https://doc.rust-lang.org/reference/attributes.html From 8eed8ed9675b264cbacc3e589950368000b2664d Mon Sep 17 00:00:00 2001 From: liudingming Date: Sun, 4 Apr 2021 00:05:17 +0800 Subject: [PATCH 317/370] Move log's short part to first --- compiler/rustc_typeck/src/check/expr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 30d60514063..67714b714c9 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -161,7 +161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, expected: Expectation<'tcx>, ) -> Ty<'tcx> { - debug!(">> type-checking: expr={:?} expected={:?}", expr, expected); + debug!(">> type-checking: expected={:?}, expr={:?} ", expected, expr); // True if `expr` is a `Try::from_ok(())` that is a result of desugaring a try block // without the final expr (e.g. `try { return; }`). We don't want to generate an @@ -224,7 +224,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, expected: Expectation<'tcx>, ) -> Ty<'tcx> { - debug!("check_expr_kind(expr={:?}, expected={:?})", expr, expected); + debug!("check_expr_kind(expected={:?}, expr={:?})", expected, expr); let tcx = self.tcx; match expr.kind { From cd22425990462d55dbd01a432dfd2aa517d5ca9c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 3 Apr 2021 18:46:25 +0300 Subject: [PATCH 318/370] expand: Do not ICE when a legacy AST-based macro attribute produces and empty expression --- compiler/rustc_expand/src/expand.rs | 9 ++++++++- src/test/ui/macros/attr-empty-expr.rs | 11 +++++++++++ src/test/ui/macros/attr-empty-expr.stderr | 20 ++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/macros/attr-empty-expr.rs create mode 100644 src/test/ui/macros/attr-empty-expr.stderr diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 470788a972a..42332adcbab 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -735,7 +735,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }); } }; - fragment_kind.expect_from_annotatables(items) + if fragment_kind == AstFragmentKind::Expr && items.is_empty() { + let msg = + "removing an expression is not supported in this position"; + self.cx.span_err(span, msg); + fragment_kind.dummy(span) + } else { + fragment_kind.expect_from_annotatables(items) + } } Err(mut err) => { err.emit(); diff --git a/src/test/ui/macros/attr-empty-expr.rs b/src/test/ui/macros/attr-empty-expr.rs new file mode 100644 index 00000000000..d4d1a3ee71e --- /dev/null +++ b/src/test/ui/macros/attr-empty-expr.rs @@ -0,0 +1,11 @@ +// AST-based macro attributes expanding to an empty expression produce an error and not ICE. + +#![feature(custom_test_frameworks)] +#![feature(stmt_expr_attributes)] +#![feature(test)] + +fn main() { + let _ = #[test] 0; //~ ERROR removing an expression is not supported in this position + let _ = #[bench] 1; //~ ERROR removing an expression is not supported in this position + let _ = #[test_case] 2; //~ ERROR removing an expression is not supported in this position +} diff --git a/src/test/ui/macros/attr-empty-expr.stderr b/src/test/ui/macros/attr-empty-expr.stderr new file mode 100644 index 00000000000..53721053bcc --- /dev/null +++ b/src/test/ui/macros/attr-empty-expr.stderr @@ -0,0 +1,20 @@ +error: removing an expression is not supported in this position + --> $DIR/attr-empty-expr.rs:8:13 + | +LL | let _ = #[test] 0; + | ^^^^^^^ + +error: removing an expression is not supported in this position + --> $DIR/attr-empty-expr.rs:9:13 + | +LL | let _ = #[bench] 1; + | ^^^^^^^^ + +error: removing an expression is not supported in this position + --> $DIR/attr-empty-expr.rs:10:13 + | +LL | let _ = #[test_case] 2; + | ^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + From a4a6bdd33771ef4cf87fd1ffc6895ec7060ff898 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 3 Apr 2021 19:25:11 +0200 Subject: [PATCH 319/370] addr_of_mut: add example for creating a pointer to uninit data --- library/core/src/mem/maybe_uninit.rs | 2 ++ library/core/src/ptr/mod.rs | 27 ++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 337f0e847bb..64342de6341 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -190,6 +190,8 @@ use crate::ptr; /// let ptr = uninit.as_mut_ptr(); /// /// // Initializing the `name` field +/// // Using `write` instead of assignment via `=` to not call `drop` on the +/// // old, uninitialized value. /// unsafe { addr_of_mut!((*ptr).name).write("Bob".to_string()); } /// /// // Initializing the `list` field diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 6412bd41a8c..f8b124f581c 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1540,6 +1540,12 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L } /// let raw_f2 = ptr::addr_of!(packed.f2); /// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2); /// ``` +/// +/// See [`addr_of_mut`] for how to create a pointer to ininitialized data. +/// Doing that with `addr_of` would not make much sense since one could only +/// read the data, and that would be Undefined Behavior. +/// +/// [`addr_of_mut`]: macro.addr_of_mut.html #[stable(feature = "raw_ref_macros", since = "1.51.0")] #[rustc_macro_transparency = "semitransparent"] #[allow_internal_unstable(raw_ref_op)] @@ -1556,7 +1562,9 @@ pub macro addr_of($place:expr) { /// as all other references. This macro can create a raw pointer *without* creating /// a reference first. /// -/// # Example +/// # Examples +/// +/// **Creating a pointer to unaligned data:** /// /// ``` /// use std::ptr; @@ -1573,6 +1581,23 @@ pub macro addr_of($place:expr) { /// unsafe { raw_f2.write_unaligned(42); } /// assert_eq!({packed.f2}, 42); // `{...}` forces copying the field instead of creating a reference. /// ``` +/// +/// **Creating a pointer to uninitialized data:** +/// +/// ```rust +/// use std::{ptr, mem::MaybeUninit}; +/// +/// struct Demo { +/// field: bool, +/// } +/// +/// let mut uninit = MaybeUninit::::uninit(); +/// // `&uninit.as_mut().field` would create a reference to an uninitialized `bool`, +/// // and thus be Undefined Behavior! +/// let f1_ptr = unsafe { ptr::addr_of_mut!((*uninit.as_mut_ptr()).field) }; +/// unsafe { f1_ptr.write(true); } +/// let init = unsafe { uninit.assume_init() }; +/// ``` #[stable(feature = "raw_ref_macros", since = "1.51.0")] #[rustc_macro_transparency = "semitransparent"] #[allow_internal_unstable(raw_ref_op)] From b93137a24e0de539293a99f6bfce9855cf13679d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 3 Apr 2021 19:26:54 +0200 Subject: [PATCH 320/370] explain that even addr_of cannot deref a NULL ptr --- library/core/src/ptr/mod.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index f8b124f581c..ba14b1abdb2 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1524,6 +1524,10 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L } /// as all other references. This macro can create a raw pointer *without* creating /// a reference first. /// +/// Note, however, that the `expr` in `addr_of!(expr)` is still subject to all +/// the usual rules. In particular, `addr_of!(*ptr::null())` is Undefined +/// Behavior because it dereferences a NULL pointer. +/// /// # Example /// /// ``` @@ -1562,6 +1566,10 @@ pub macro addr_of($place:expr) { /// as all other references. This macro can create a raw pointer *without* creating /// a reference first. /// +/// Note, however, that the `expr` in `addr_of_mut!(expr)` is still subject to all +/// the usual rules. In particular, `addr_of_mut!(*ptr::null_mut())` is Undefined +/// Behavior because it dereferences a NULL pointer. +/// /// # Examples /// /// **Creating a pointer to unaligned data:** From 3982ac22497efda2bddf261021e88aa37b55e47b Mon Sep 17 00:00:00 2001 From: liudingming Date: Sun, 4 Apr 2021 01:40:47 +0800 Subject: [PATCH 321/370] Optimize out unneeded type resolving --- compiler/rustc_typeck/src/check/expectation.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_typeck/src/check/expectation.rs b/compiler/rustc_typeck/src/check/expectation.rs index 22be10a731f..e9e81034477 100644 --- a/compiler/rustc_typeck/src/check/expectation.rs +++ b/compiler/rustc_typeck/src/check/expectation.rs @@ -104,8 +104,8 @@ impl<'a, 'tcx> Expectation<'tcx> { /// for the program to type-check). `only_has_type` will return /// such a constraint, if it exists. pub(super) fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option> { - match self.resolve(fcx) { - ExpectHasType(ty) => Some(ty), + match self { + ExpectHasType(ty) => Some(fcx.resolve_vars_if_possible(ty)), NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) | IsLast(_) => { None } From 5839bff0bac6063147c8905388713a787577208f Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 3 Apr 2021 20:20:18 +0300 Subject: [PATCH 322/370] Remove attribute `#[link_args]` --- compiler/rustc_codegen_ssa/src/back/link.rs | 11 +--- compiler/rustc_codegen_ssa/src/base.rs | 1 - compiler/rustc_codegen_ssa/src/lib.rs | 1 - compiler/rustc_feature/src/active.rs | 3 - compiler/rustc_feature/src/builtin_attrs.rs | 5 -- compiler/rustc_feature/src/removed.rs | 4 ++ compiler/rustc_metadata/src/lib.rs | 1 - compiler/rustc_metadata/src/link_args.rs | 57 ------------------- .../src/rmeta/decoder/cstore_impl.rs | 5 -- compiler/rustc_middle/src/query/mod.rs | 5 -- library/std/src/lib.rs | 1 - .../src/language-features/link-args.md | 32 ----------- src/test/incremental/hashes/extern_mods.rs | 16 ------ .../link-args-order/Makefile | 2 +- .../link-args-order/empty.rs | 5 -- .../feature-gates/feature-gate-link_args.rs | 17 ------ .../feature-gate-link_args.stderr | 30 ---------- src/test/ui/issues/issue-15487.rs | 13 ----- src/test/ui/linkage-attr/invalid-link-args.rs | 14 ----- .../no_std_main_recursion.rs | 4 +- .../clippy/tests/ui/empty_loop_no_std.rs | 4 +- 21 files changed, 12 insertions(+), 219 deletions(-) delete mode 100644 compiler/rustc_metadata/src/link_args.rs delete mode 100644 src/doc/unstable-book/src/language-features/link-args.md delete mode 100644 src/test/ui/feature-gates/feature-gate-link_args.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-link_args.stderr delete mode 100644 src/test/ui/issues/issue-15487.rs delete mode 100644 src/test/ui/linkage-attr/invalid-link-args.rs diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 217b8f43229..ea75943d6f3 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1411,15 +1411,10 @@ fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_ty } } -/// Add arbitrary "user defined" args defined from command line and by `#[link_args]` attributes. +/// Add arbitrary "user defined" args defined from command line. /// FIXME: Determine where exactly these args need to be inserted. -fn add_user_defined_link_args( - cmd: &mut dyn Linker, - sess: &Session, - codegen_results: &CodegenResults, -) { +fn add_user_defined_link_args(cmd: &mut dyn Linker, sess: &Session) { cmd.args(&sess.opts.cg.link_args); - cmd.args(&*codegen_results.crate_info.link_args); } /// Add arbitrary "late link" args defined by the target spec. @@ -1761,7 +1756,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( add_rpath_args(cmd, sess, codegen_results, out_filename); // OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT - add_user_defined_link_args(cmd, sess, codegen_results); + add_user_defined_link_args(cmd, sess); // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER cmd.finalize(); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 08e31c3b37f..318eed76acf 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -754,7 +754,6 @@ impl CrateInfo { is_no_builtins: Default::default(), native_libraries: Default::default(), used_libraries: tcx.native_libraries(LOCAL_CRATE).iter().map(Into::into).collect(), - link_args: tcx.link_args(LOCAL_CRATE), crate_name: Default::default(), used_crates_dynamic: cstore::used_crates(tcx, LinkagePreference::RequireDynamic), used_crates_static: cstore::used_crates(tcx, LinkagePreference::RequireStatic), diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 56b4ef79383..f0f45b067b3 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -139,7 +139,6 @@ pub struct CrateInfo { pub native_libraries: FxHashMap>, pub crate_name: FxHashMap, pub used_libraries: Vec, - pub link_args: Lrc>, pub used_crate_source: FxHashMap>, pub used_crates_static: Vec<(CrateNum, LibSource)>, pub used_crates_dynamic: Vec<(CrateNum, LibSource)>, diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 040260f5cf5..abbeb9554e3 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -258,9 +258,6 @@ declare_features! ( // feature-group-start: actual feature gates // ------------------------------------------------------------------------- - /// Allows using the `#[link_args]` attribute. - (active, link_args, "1.0.0", Some(29596), None), - /// Allows defining identifiers beyond ASCII. (active, non_ascii_idents, "1.0.0", Some(55467), None), diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 072062dd615..7df9b3f0a79 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -279,11 +279,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Linking: gated!(naked, AssumedUsed, template!(Word), naked_functions, experimental!(naked)), - gated!( - link_args, Normal, template!(NameValueStr: "args"), - "the `link_args` attribute is experimental and not portable across platforms, \ - it is recommended to use `#[link(name = \"foo\")] instead", - ), gated!( link_ordinal, AssumedUsed, template!(List: "ordinal"), raw_dylib, experimental!(link_ordinal) diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 8ba67a00f8d..e1491576616 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -128,6 +128,10 @@ declare_features! ( /// Allows comparing raw pointers during const eval. (removed, const_compare_raw_pointers, "1.46.0", Some(53020), None, Some("cannot be allowed in const eval in any meaningful way")), + /// Allows using the `#[link_args]` attribute. + (removed, link_args, "1.53.0", Some(29596), None, + Some("removed in favor of using `-C link-arg=ARG` on command line, \ + which is available from cargo build scripts with `cargo:rustc-link-arg` now")), // ------------------------------------------------------------------------- // feature-group-end: removed features diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index fe93f4230e9..c4d9e3f77f0 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -26,7 +26,6 @@ pub use rmeta::{provide, provide_extern}; mod dependency_format; mod foreign_modules; -mod link_args; mod native_libs; mod rmeta; diff --git a/compiler/rustc_metadata/src/link_args.rs b/compiler/rustc_metadata/src/link_args.rs deleted file mode 100644 index 9e1ac33368c..00000000000 --- a/compiler/rustc_metadata/src/link_args.rs +++ /dev/null @@ -1,57 +0,0 @@ -use rustc_hir as hir; -use rustc_hir::itemlikevisit::ItemLikeVisitor; -use rustc_middle::ty::TyCtxt; -use rustc_span::symbol::{sym, Symbol}; -use rustc_target::spec::abi::Abi; - -crate fn collect(tcx: TyCtxt<'_>) -> Vec { - let mut collector = Collector { tcx, args: Vec::new() }; - tcx.hir().krate().visit_all_item_likes(&mut collector); - - for attr in tcx.hir().attrs(hir::CRATE_HIR_ID).iter() { - if attr.has_name(sym::link_args) { - if let Some(linkarg) = attr.value_str() { - collector.add_link_args(linkarg); - } - } - } - - collector.args -} - -struct Collector<'tcx> { - tcx: TyCtxt<'tcx>, - args: Vec, -} - -impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> { - fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) { - let abi = match it.kind { - hir::ItemKind::ForeignMod { abi, .. } => abi, - _ => return, - }; - if abi == Abi::Rust || abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { - return; - } - - // First, add all of the custom #[link_args] attributes - let sess = &self.tcx.sess; - for m in - self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| sess.check_name(a, sym::link_args)) - { - if let Some(linkarg) = m.value_str() { - self.add_link_args(linkarg); - } - } - } - - fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {} - fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {} - fn visit_foreign_item(&mut self, _it: &'tcx hir::ForeignItem<'tcx>) {} -} - -impl<'tcx> Collector<'tcx> { - fn add_link_args(&mut self, args: Symbol) { - self.args.extend(args.as_str().split(' ').filter(|s| !s.is_empty()).map(|s| s.to_string())) - } -} diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index e10041a2971..bebee9dac3b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -1,6 +1,5 @@ use crate::creader::{CStore, LoadedMacro}; use crate::foreign_modules; -use crate::link_args; use crate::native_libs; use crate::rmeta::{self, encoder}; @@ -295,10 +294,6 @@ pub fn provide(providers: &mut Providers) { foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect(); Lrc::new(modules) }, - link_args: |tcx, cnum| { - assert_eq!(cnum, LOCAL_CRATE); - Lrc::new(link_args::collect(tcx)) - }, // Returns a map from a sufficiently visible external item (i.e., an // external item that is visible from at least one local module) to a diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index bf39b1da8f0..bac69e282a5 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1253,11 +1253,6 @@ rustc_queries! { desc { |tcx| "native_library_kind({})", tcx.def_path_str(def_id) } } - query link_args(_: CrateNum) -> Lrc> { - eval_always - desc { "looking up link arguments for a crate" } - } - /// Does lifetime resolution, but does not descend into trait items. This /// should only be used for resolving lifetimes of on trait definitions, /// and is used to avoid cycles. Importantly, `resolve_lifetimes` still visits diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index d5ba2d36346..147eb65e48b 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -281,7 +281,6 @@ #![feature(intra_doc_pointers)] #![feature(iter_zip)] #![feature(lang_items)] -#![feature(link_args)] #![feature(linkage)] #![feature(llvm_asm)] #![feature(log_syntax)] diff --git a/src/doc/unstable-book/src/language-features/link-args.md b/src/doc/unstable-book/src/language-features/link-args.md deleted file mode 100644 index da36e158001..00000000000 --- a/src/doc/unstable-book/src/language-features/link-args.md +++ /dev/null @@ -1,32 +0,0 @@ -# `link_args` - -The tracking issue for this feature is: [#29596] - -[#29596]: https://github.com/rust-lang/rust/issues/29596 - ------------------------- - -You can tell `rustc` how to customize linking, and that is via the `link_args` -attribute. This attribute is applied to `extern` blocks and specifies raw flags -which need to get passed to the linker when producing an artifact. An example -usage would be: - -```rust,no_run -#![feature(link_args)] - -#[link_args = "-foo -bar -baz"] -extern "C" {} -# fn main() {} -``` - -Note that this feature is currently hidden behind the `feature(link_args)` gate -because this is not a sanctioned way of performing linking. Right now `rustc` -shells out to the system linker (`gcc` on most systems, `link.exe` on MSVC), so -it makes sense to provide extra command line arguments, but this will not -always be the case. In the future `rustc` may use LLVM directly to link native -libraries, in which case `link_args` will have no meaning. You can achieve the -same effect as the `link_args` attribute with the `-C link-args` argument to -`rustc`. - -It is highly recommended to *not* use this attribute, and rather use the more -formal `#[link(...)]` attribute on `extern` blocks instead. diff --git a/src/test/incremental/hashes/extern_mods.rs b/src/test/incremental/hashes/extern_mods.rs index 7a923134331..93e70d3792c 100644 --- a/src/test/incremental/hashes/extern_mods.rs +++ b/src/test/incremental/hashes/extern_mods.rs @@ -12,7 +12,6 @@ #![allow(warnings)] #![feature(rustc_attrs)] #![feature(unboxed_closures)] -#![feature(link_args)] #![crate_type = "rlib"] // Change function name -------------------------------------------------------- @@ -146,21 +145,6 @@ extern "C" { pub fn add_function2(); } -// Change link-args ------------------------------------------------------------ -#[cfg(cfail1)] -#[link_args = "-foo -bar"] -extern "C" { - pub fn change_link_args(c: i32); -} - -#[cfg(not(cfail1))] -#[rustc_dirty(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")] -#[rustc_clean(cfg = "cfail3")] -#[link_args = "-foo -bar -baz"] -extern "C" { - pub fn change_link_args(c: i32); -} - // Change link-name ------------------------------------------------------------ #[cfg(cfail1)] #[link(name = "foo")] diff --git a/src/test/run-make-fulldeps/link-args-order/Makefile b/src/test/run-make-fulldeps/link-args-order/Makefile index 98c1e0eac3b..f94e882ccb6 100644 --- a/src/test/run-make-fulldeps/link-args-order/Makefile +++ b/src/test/run-make-fulldeps/link-args-order/Makefile @@ -6,5 +6,5 @@ RUSTC_FLAGS = -C linker-flavor=ld -C link-arg=a -C link-args="b c" -C link-args= RUSTC_FLAGS_PRE = -C linker-flavor=ld -Z pre-link-arg=a -Z pre-link-args="b c" -Z pre-link-args="d e" -Z pre-link-arg=f all: - $(RUSTC) $(RUSTC_FLAGS) empty.rs 2>&1 | $(CGREP) '"a" "b" "c" "d" "e" "f" "g"' + $(RUSTC) $(RUSTC_FLAGS) empty.rs 2>&1 | $(CGREP) '"a" "b" "c" "d" "e" "f"' $(RUSTC) $(RUSTC_FLAGS_PRE) empty.rs 2>&1 | $(CGREP) '"a" "b" "c" "d" "e" "f"' diff --git a/src/test/run-make-fulldeps/link-args-order/empty.rs b/src/test/run-make-fulldeps/link-args-order/empty.rs index 2439171004b..f328e4d9d04 100644 --- a/src/test/run-make-fulldeps/link-args-order/empty.rs +++ b/src/test/run-make-fulldeps/link-args-order/empty.rs @@ -1,6 +1 @@ -#![feature(link_args)] - -#[link_args = "g"] -extern "C" {} - fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-link_args.rs b/src/test/ui/feature-gates/feature-gate-link_args.rs deleted file mode 100644 index e1c651f46fb..00000000000 --- a/src/test/ui/feature-gates/feature-gate-link_args.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Test that `#[link_args]` attribute is gated by `link_args` -// feature gate, both when it occurs where expected (atop -// `extern { }` blocks) and where unexpected. - -// sidestep warning (which is correct, but misleading for -// purposes of this test) -#![allow(unused_attributes)] -#![link_args = "-l unexpected_use_as_inner_attr_on_mod"] -//~^ ERROR the `link_args` attribute is experimental - -#[link_args = "-l expected_use_case"] -//~^ ERROR the `link_args` attribute is experimental -extern "C" {} - -#[link_args = "-l unexected_use_on_non_extern_item"] -//~^ ERROR: the `link_args` attribute is experimental -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-link_args.stderr b/src/test/ui/feature-gates/feature-gate-link_args.stderr deleted file mode 100644 index ae4918f5c9f..00000000000 --- a/src/test/ui/feature-gates/feature-gate-link_args.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error[E0658]: the `link_args` attribute is experimental and not portable across platforms, it is recommended to use `#[link(name = "foo")] instead - --> $DIR/feature-gate-link_args.rs:11:1 - | -LL | #[link_args = "-l expected_use_case"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #29596 for more information - = help: add `#![feature(link_args)]` to the crate attributes to enable - -error[E0658]: the `link_args` attribute is experimental and not portable across platforms, it is recommended to use `#[link(name = "foo")] instead - --> $DIR/feature-gate-link_args.rs:15:1 - | -LL | #[link_args = "-l unexected_use_on_non_extern_item"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #29596 for more information - = help: add `#![feature(link_args)]` to the crate attributes to enable - -error[E0658]: the `link_args` attribute is experimental and not portable across platforms, it is recommended to use `#[link(name = "foo")] instead - --> $DIR/feature-gate-link_args.rs:8:1 - | -LL | #![link_args = "-l unexpected_use_as_inner_attr_on_mod"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #29596 for more information - = help: add `#![feature(link_args)]` to the crate attributes to enable - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/issues/issue-15487.rs b/src/test/ui/issues/issue-15487.rs deleted file mode 100644 index 34ac53be5be..00000000000 --- a/src/test/ui/issues/issue-15487.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -#![allow(unused_attributes)] -// ignore-windows -// ignore-wasm32-bare no libs to link -// ignore-sgx no libs to link -#![feature(link_args)] - -#[link_args = "-lc -lm"] -#[link_args = " -lc"] -#[link_args = "-lc "] -extern "C" {} - -fn main() {} diff --git a/src/test/ui/linkage-attr/invalid-link-args.rs b/src/test/ui/linkage-attr/invalid-link-args.rs deleted file mode 100644 index 7418691d014..00000000000 --- a/src/test/ui/linkage-attr/invalid-link-args.rs +++ /dev/null @@ -1,14 +0,0 @@ -// build-fail -// dont-check-compiler-stderr -// ignore-msvc due to linker-flavor=ld -// error-pattern:aFdEfSeVEEE -// compile-flags: -C linker-flavor=ld - -/* Make sure invalid link_args are printed to stderr. */ - -#![feature(link_args)] - -#[link_args = "aFdEfSeVEEE"] -extern "C" {} - -fn main() {} diff --git a/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs b/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs index 25b1417be97..be4348e2bb7 100644 --- a/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs +++ b/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs @@ -1,8 +1,8 @@ +// compile-flags: -Clink-arg=-nostartfiles // ignore-macos // ignore-windows -#![feature(lang_items, link_args, start, libc)] -#![link_args = "-nostartfiles"] +#![feature(lang_items, start, libc)] #![no_std] use core::panic::PanicInfo; diff --git a/src/tools/clippy/tests/ui/empty_loop_no_std.rs b/src/tools/clippy/tests/ui/empty_loop_no_std.rs index 4553d3ec505..235e0fc5179 100644 --- a/src/tools/clippy/tests/ui/empty_loop_no_std.rs +++ b/src/tools/clippy/tests/ui/empty_loop_no_std.rs @@ -1,9 +1,9 @@ +// compile-flags: -Clink-arg=-nostartfiles // ignore-macos // ignore-windows #![warn(clippy::empty_loop)] -#![feature(lang_items, link_args, start, libc)] -#![link_args = "-nostartfiles"] +#![feature(lang_items, start, libc)] #![no_std] use core::panic::PanicInfo; From 23325caf43d16e8caf77f8d4855ff568b6d143be Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Fri, 26 Mar 2021 13:02:46 -0700 Subject: [PATCH 323/370] Make rust-demangler installable Adds bootstrap rules to support installing rust-demangler. When compiling with `-Z instrument-coverage`, the coverage reports are generated by `llvm-cov`. `llvm-cov` includes a built-in demangler for C++, and an option to supply an alternate demangler. For Rust, we have `rust-demangler`, currently used in `rustc` coverage tests. Fuchsia's toolchain for Rust is built via `./x.py install`. Fuchsia is adding support for Rust coverage, and we need to include the `rust-demangler` in the installed `bin` directory. Configured rust-demangler as an in-tree extended tool. Added tests to support `./x.py test rust-demangler`. Install with extended tools by default only if `profiler = true`. --- config.toml.example | 9 +- src/bootstrap/builder.rs | 3 + src/bootstrap/dist.rs | 86 +++++++++++++++++++ src/bootstrap/install.rs | 20 +++++ src/bootstrap/tarball.rs | 5 ++ src/bootstrap/test.rs | 53 +++++++++++- src/bootstrap/tool.rs | 2 +- src/tools/rust-demangler/Cargo.toml | 6 +- src/tools/rust-demangler/README.md | 29 +++++++ src/tools/rust-demangler/src/lib.rs | 22 +++++ src/tools/rust-demangler/{ => src}/main.rs | 40 +-------- src/tools/rust-demangler/tests/lib.rs | 97 ++++++++++++++++++++++ 12 files changed, 328 insertions(+), 44 deletions(-) create mode 100644 src/tools/rust-demangler/README.md create mode 100644 src/tools/rust-demangler/src/lib.rs rename src/tools/rust-demangler/{ => src}/main.rs (76%) create mode 100644 src/tools/rust-demangler/tests/lib.rs diff --git a/config.toml.example b/config.toml.example index ee06e1bd0ba..d8b550d4c74 100644 --- a/config.toml.example +++ b/config.toml.example @@ -259,10 +259,11 @@ changelog-seen = 2 # be built if `extended = true`. #extended = false -# Installs chosen set of extended tools if `extended = true`. By default builds all. -# If chosen tool failed to build the installation fails. If `extended = false`, this -# option is ignored. -#tools = ["cargo", "rls", "clippy", "rustfmt", "analysis", "src"] +# Installs chosen set of extended tools if `extended = true`. By default builds +# all extended tools except `rust-demangler`, unless the target is also being +# built with `profiler = true`. If chosen tool failed to build the installation +# fails. If `extended = false`, this option is ignored. +#tools = ["cargo", "rls", "clippy", "rustfmt", "analysis", "src"] # + "rust-demangler" if `profiler` # Verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose #verbose = 0 diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 22a1eb63702..86f59495504 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -420,6 +420,7 @@ impl<'a> Builder<'a> { test::Rustfmt, test::Miri, test::Clippy, + test::RustDemangler, test::CompiletestTest, test::RustdocJSStd, test::RustdocJSNotStd, @@ -466,6 +467,7 @@ impl<'a> Builder<'a> { dist::Rls, dist::RustAnalyzer, dist::Rustfmt, + dist::RustDemangler, dist::Clippy, dist::Miri, dist::LlvmTools, @@ -481,6 +483,7 @@ impl<'a> Builder<'a> { install::Rls, install::RustAnalyzer, install::Rustfmt, + install::RustDemangler, install::Clippy, install::Miri, install::Analysis, diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 802b5c99500..34243b79717 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1246,6 +1246,50 @@ impl Step for Rustfmt { } } +#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RustDemangler { + pub compiler: Compiler, + pub target: TargetSelection, +} + +impl Step for RustDemangler { + type Output = GeneratedTarball; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("rust-demangler") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(RustDemangler { + compiler: run.builder.compiler_for( + run.builder.top_stage, + run.builder.config.build, + run.target, + ), + target: run.target, + }); + } + + fn run(self, builder: &Builder<'_>) -> GeneratedTarball { + let compiler = self.compiler; + let target = self.target; + assert!(builder.config.extended); + + let rust_demangler = builder + .ensure(tool::RustDemangler { compiler, target, extra_features: Vec::new() }) + .expect("rust-demangler expected to build - in-tree tool"); + + // Prepare the image directory + let mut tarball = Tarball::new(builder, "rust-demangler", &target.triple); + tarball.set_overlay(OverlayKind::RustDemangler); + tarball.is_preview(true); + tarball.add_file(&rust_demangler, "bin", 0o755); + tarball.add_legal_and_readme_to("share/doc/rust-demangler"); + tarball.generate() + } +} + #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] pub struct Extended { stage: u32, @@ -1282,6 +1326,14 @@ impl Step for Extended { let rustc_installer = builder.ensure(Rustc { compiler: builder.compiler(stage, target) }); let cargo_installer = builder.ensure(Cargo { compiler, target }); let rustfmt_installer = builder.ensure(Rustfmt { compiler, target }); + let profiler = builder.config.profiler_enabled(target); + let install_rust_demangler = + builder.config.tools.as_ref().map_or(profiler, |t| t.contains("rust-demangler")); + let rust_demangler_installer = if install_rust_demangler { + Some(builder.ensure(RustDemangler { compiler, target })) + } else { + None + }; let rls_installer = builder.ensure(Rls { compiler, target }); let rust_analyzer_installer = builder.ensure(RustAnalyzer { compiler, target }); let llvm_tools_installer = builder.ensure(LlvmTools { target }); @@ -1312,6 +1364,9 @@ impl Step for Extended { tarballs.push(clippy_installer); tarballs.extend(miri_installer.clone()); tarballs.extend(rustfmt_installer.clone()); + if let Some(rust_demangler_installer) = rust_demangler_installer { + tarballs.push(rust_demangler_installer); + } tarballs.extend(llvm_tools_installer); if let Some(analysis_installer) = analysis_installer { tarballs.push(analysis_installer); @@ -1413,6 +1468,9 @@ impl Step for Extended { prepare("rust-docs"); prepare("rust-std"); prepare("rust-analysis"); + if install_rust_demangler { + prepare("rust-demangler"); + } prepare("clippy"); if rls_installer.is_some() { @@ -1476,6 +1534,9 @@ impl Step for Extended { prepare("rustc"); prepare("cargo"); prepare("rust-analysis"); + if install_rust_demangler { + prepare("rust-demangler"); + } prepare("rust-docs"); prepare("rust-std"); prepare("clippy"); @@ -1620,6 +1681,25 @@ impl Step for Extended { .arg("-t") .arg(etc.join("msi/remove-duplicates.xsl")), ); + if install_rust_demangler { + builder.run( + Command::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rust-demangler") + .args(&heat_flags) + .arg("-cg") + .arg("RustDemanglerGroup") + .arg("-dr") + .arg("RustDemangler") + .arg("-var") + .arg("var.RustDemanglerDir") + .arg("-out") + .arg(exe.join("RustDemanglerGroup.wxs")) + .arg("-t") + .arg(etc.join("msi/remove-duplicates.xsl")), + ); + } if miri_installer.is_some() { builder.run( Command::new(&heat) @@ -1715,6 +1795,9 @@ impl Step for Extended { candle("CargoGroup.wxs".as_ref()); candle("StdGroup.wxs".as_ref()); candle("ClippyGroup.wxs".as_ref()); + if install_rust_demangler { + candle("RustDemanglerGroup.wxs".as_ref()); + } if rls_installer.is_some() { candle("RlsGroup.wxs".as_ref()); } @@ -1761,6 +1844,9 @@ impl Step for Extended { if rust_analyzer_installer.is_some() { cmd.arg("RustAnalyzerGroup.wixobj"); } + if install_rust_demangler { + cmd.arg("RustDemanglerGroup.wixobj"); + } if miri_installer.is_some() { cmd.arg("MiriGroup.wixobj"); } diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index b427420d577..e034e2a2f90 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -190,6 +190,26 @@ install!((self, builder, _config), ); } }; + RustDemangler, + "rust-demangler", + Self::should_build(_config), + only_hosts: true, + { + let profiler = builder.config.profiler_enabled(self.target); + let install_rust_demangler = + builder.config.tools.as_ref().map_or(profiler, |t| t.contains("rust-demangler")); + if install_rust_demangler { + let tarball = builder.ensure( + dist::RustDemangler { compiler: self.compiler, target: self.target } + ); + install_sh(builder, "rust-demangler", self.compiler.stage, Some(self.target), &tarball); + } else { + builder.info( + &format!("skipping Install RustDemangler stage{} ({})", + self.compiler.stage, self.target), + ); + } + }; Analysis, "analysis", Self::should_build(_config), only_hosts: false, { let tarball = builder.ensure(dist::Analysis { // Find the actual compiler (handling the full bootstrap option) which diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 7fb03056f1b..4a5d5fbf04f 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -15,6 +15,7 @@ pub(crate) enum OverlayKind { Clippy, Miri, Rustfmt, + RustDemangler, RLS, RustAnalyzer, } @@ -47,6 +48,9 @@ impl OverlayKind { "src/tools/rustfmt/LICENSE-APACHE", "src/tools/rustfmt/LICENSE-MIT", ], + OverlayKind::RustDemangler => { + &["src/tools/rust-demangler/README.md", "LICENSE-APACHE", "LICENSE-MIT"] + } OverlayKind::RLS => &[ "src/tools/rls/README.md", "src/tools/rls/LICENSE-APACHE", @@ -64,6 +68,7 @@ impl OverlayKind { match self { OverlayKind::Rust => builder.rust_version(), OverlayKind::LLVM => builder.rust_version(), + OverlayKind::RustDemangler => builder.rust_version(), OverlayKind::Cargo => { builder.cargo_info.version(builder, &builder.release_num("cargo")) } diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index adb0a372c64..7425dcb52c0 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -351,6 +351,54 @@ impl Step for Rustfmt { } } +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct RustDemangler { + stage: u32, + host: TargetSelection, +} + +impl Step for RustDemangler { + type Output = (); + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/rust-demangler") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(RustDemangler { stage: run.builder.top_stage, host: run.target }); + } + + /// Runs `cargo test` for rust-demangler. + fn run(self, builder: &Builder<'_>) { + let stage = self.stage; + let host = self.host; + let compiler = builder.compiler(stage, host); + + let rust_demangler = builder + .ensure(tool::RustDemangler { compiler, target: self.host, extra_features: Vec::new() }) + .expect("in-tree tool"); + let mut cargo = tool::prepare_tool_cargo( + builder, + compiler, + Mode::ToolRustc, + host, + "test", + "src/tools/rust-demangler", + SourceType::InTree, + &[], + ); + + let dir = testdir(builder, compiler.host); + t!(fs::create_dir_all(&dir)); + + cargo.env("RUST_DEMANGLER_DRIVER_PATH", rust_demangler); + cargo.add_rustc_lib_path(builder, compiler); + + builder.run(&mut cargo.into()); + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct Miri { stage: u32, @@ -1126,7 +1174,10 @@ note: if you're sure you want to do this, please open an issue as to why. In the } if mode == "run-make" && suite.ends_with("fulldeps") { - cmd.arg("--rust-demangler-path").arg(builder.tool_exe(Tool::RustDemangler)); + let rust_demangler = builder + .ensure(tool::RustDemangler { compiler, target, extra_features: Vec::new() }) + .expect("in-tree tool"); + cmd.arg("--rust-demangler-path").arg(rust_demangler); } cmd.arg("--src-base").arg(builder.src.join("src/test").join(suite)); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 3fc3b68fd86..bfb846f3b56 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -368,7 +368,6 @@ bootstrap_tool!( Compiletest, "src/tools/compiletest", "compiletest", is_unstable_tool = true; BuildManifest, "src/tools/build-manifest", "build-manifest"; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client"; - RustDemangler, "src/tools/rust-demangler", "rust-demangler"; RustInstaller, "src/tools/rust-installer", "fabricate", is_external_tool = true; RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes"; ExpandYamlAnchors, "src/tools/expand-yaml-anchors", "expand-yaml-anchors"; @@ -719,6 +718,7 @@ tool_extended!((self, builder), }); self.extra_features.push("clippy".to_owned()); }; + RustDemangler, rust_demangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, {}; Rustfmt, rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, {}; RustAnalyzer, rust_analyzer, "src/tools/rust-analyzer/crates/rust-analyzer", "rust-analyzer", stable=false, {}; ); diff --git a/src/tools/rust-demangler/Cargo.toml b/src/tools/rust-demangler/Cargo.toml index ac684a3c47e..b7bc1125319 100644 --- a/src/tools/rust-demangler/Cargo.toml +++ b/src/tools/rust-demangler/Cargo.toml @@ -8,6 +8,10 @@ edition = "2018" regex = "1.0" rustc-demangle = "0.1.17" +[lib] +name = "rust_demangler" +doctest = false + [[bin]] name = "rust-demangler" -path = "main.rs" +test = false diff --git a/src/tools/rust-demangler/README.md b/src/tools/rust-demangler/README.md new file mode 100644 index 00000000000..a45f5c45732 --- /dev/null +++ b/src/tools/rust-demangler/README.md @@ -0,0 +1,29 @@ +# rust-demangler + +Demangles rustc mangled names. + +This tool uses the [rustc-demangle](https://crates.io/crates/rustc-demangle) +crate to convert an input buffer of newline-separated mangled names into their +demangled translations. + +This tool takes a list of mangled names (one per line) on standard input, and +prints a corresponding list of demangled names. The tool is designed to support +programs that can leverage a third-party demangler, such as `llvm-cov`, via the +`-Xdemangler=` option. + +To use `rust-demangler` with `llvm-cov` for example, add the `-Xdemangler=...` +option: + +```shell +$ TARGET="${PWD}/build/x86_64-unknown-linux-gnu" +$ "${TARGET}"/llvm/bin/llvm-cov show \ + --Xdemangler=path/to/rust-demangler \ + --instr-profile=main.profdata ./main --show-line-counts-or-regions +``` + +## License + +Rust-demangler is distributed under the terms of both the MIT license and the +Apache License (Version 2.0). + +See [LICENSE-APACHE](/LICENSE-APACHE) and [LICENSE-MIT](/LICENSE-MIT) for details. diff --git a/src/tools/rust-demangler/src/lib.rs b/src/tools/rust-demangler/src/lib.rs new file mode 100644 index 00000000000..4d2911ee7f8 --- /dev/null +++ b/src/tools/rust-demangler/src/lib.rs @@ -0,0 +1,22 @@ +use regex::Regex; +use rustc_demangle::demangle; + +const REPLACE_COLONS: &str = "::"; + +pub fn create_disambiguator_re() -> Regex { + Regex::new(r"\[[a-f0-9]{5,16}\]::").unwrap() +} + +pub fn demangle_lines(buffer: &str, strip_crate_disambiguators: Option) -> Vec { + let lines = buffer.lines(); + let mut demangled_lines = Vec::new(); + for mangled in lines { + let mut demangled = demangle(mangled).to_string(); + if let Some(re) = &strip_crate_disambiguators { + demangled = re.replace_all(&demangled, REPLACE_COLONS).to_string(); + } + demangled_lines.push(demangled); + } + demangled_lines.push("".to_string()); + demangled_lines +} diff --git a/src/tools/rust-demangler/main.rs b/src/tools/rust-demangler/src/main.rs similarity index 76% rename from src/tools/rust-demangler/main.rs rename to src/tools/rust-demangler/src/main.rs index fd031ccb252..a87369d7baa 100644 --- a/src/tools/rust-demangler/main.rs +++ b/src/tools/rust-demangler/src/main.rs @@ -1,27 +1,5 @@ //! Demangles rustc mangled names. //! -//! This tool uses https://crates.io/crates/rustc-demangle to convert an input buffer of -//! newline-separated mangled names into their demangled translations. -//! -//! This tool can be leveraged by other applications that support third-party demanglers. -//! It takes a list of mangled names (one per line) on standard input, and prints a corresponding -//! list of demangled names. The tool is designed to support other programs that can leverage a -//! third-party demangler, such as `llvm-cov`, via the `-Xdemangler=` option. -//! -//! To use `rust-demangler`, first build the tool with: -//! -//! ```shell -//! $ ./x.py build rust-demangler -//! ``` -//! -//! Then, with `llvm-cov` for example, add the `-Xdemangler=...` option: -//! -//! ```shell -//! $ TARGET="${PWD}/build/x86_64-unknown-linux-gnu" -//! $ "${TARGET}"/llvm/bin/llvm-cov show --Xdemangler="${TARGET}"/stage0-tools-bin/rust-demangler \ -//! --instr-profile=main.profdata ./main --show-line-counts-or-regions -//! ``` -//! //! Note regarding crate disambiguators: //! //! Some demangled symbol paths can include "crate disambiguator" suffixes, represented as a large @@ -57,12 +35,9 @@ //! These disambiguators seem to have more analytical value (for instance, in coverage analysis), so //! they are not removed. -use regex::Regex; -use rustc_demangle::demangle; +use rust_demangler::*; use std::io::{self, Read, Write}; -const REPLACE_COLONS: &str = "::"; - fn main() -> io::Result<()> { // FIXME(richkadel): In Issue #77615 discussed updating the `rustc-demangle` library, to provide // an option to generate demangled names without including crate disambiguators. If that @@ -82,7 +57,7 @@ fn main() -> io::Result<()> { // and more than three leading zeros should be extremely unlikely. Conversely, it should be // sufficient to assume the zero-based indexes for closures and anonymous scopes will never // exceed the value 9999. - let mut strip_crate_disambiguators = Some(Regex::new(r"\[[a-f0-9]{5,16}\]::").unwrap()); + let mut strip_crate_disambiguators = Some(create_disambiguator_re()); let mut args = std::env::args(); let progname = args.next().unwrap(); @@ -115,16 +90,7 @@ fn main() -> io::Result<()> { let mut buffer = String::new(); io::stdin().read_to_string(&mut buffer)?; - let lines = buffer.lines(); - let mut demangled_lines = Vec::new(); - for mangled in lines { - let mut demangled = demangle(mangled).to_string(); - if let Some(re) = &strip_crate_disambiguators { - demangled = re.replace_all(&demangled, REPLACE_COLONS).to_string(); - } - demangled_lines.push(demangled); - } - demangled_lines.push("".to_string()); + let demangled_lines = demangle_lines(&buffer, strip_crate_disambiguators); io::stdout().write_all(demangled_lines.join("\n").as_bytes())?; Ok(()) } diff --git a/src/tools/rust-demangler/tests/lib.rs b/src/tools/rust-demangler/tests/lib.rs new file mode 100644 index 00000000000..8a1647601e4 --- /dev/null +++ b/src/tools/rust-demangler/tests/lib.rs @@ -0,0 +1,97 @@ +use rust_demangler::*; + +const MANGLED_LINES: &str = r" +_RNvC6_123foo3bar +_RNqCs4fqI2P2rA04_11utf8_identsu30____7hkackfecea1cbdathfdh9hlq6y +_RNCNCNgCs6DXkGYLi8lr_2cc5spawn00B5_ +_RNCINkXs25_NgCsbmNqQUJIY6D_4core5sliceINyB9_4IterhENuNgNoBb_4iter8iterator8Iterator9rpositionNCNgNpB9_6memchr7memrchrs_0E0Bb_ +_RINbNbCskIICzLVDPPb_5alloc5alloc8box_freeDINbNiB4_5boxed5FnBoxuEp6OutputuEL_ECs1iopQbuBiw2_3std +INtC8arrayvec8ArrayVechKj7b_E +_RMCs4fqI2P2rA04_13const_genericINtB0_8UnsignedKhb_E +_RMCs4fqI2P2rA04_13const_genericINtB0_6SignedKs98_E +_RMCs4fqI2P2rA04_13const_genericINtB0_6SignedKanb_E +_RMCs4fqI2P2rA04_13const_genericINtB0_4BoolKb0_E +_RMCs4fqI2P2rA04_13const_genericINtB0_4BoolKb1_E +_RMCs4fqI2P2rA04_13const_genericINtB0_4CharKc76_E +_RMCs4fqI2P2rA04_13const_genericINtB0_4CharKca_E +_RMCs4fqI2P2rA04_13const_genericINtB0_4CharKc2202_E +_RNvNvMCs4fqI2P2rA04_13const_genericINtB4_3FooKpE3foo3FOO +_RC3foo.llvm.9D1C9369 +_RC3foo.llvm.9D1C9369@@16 +_RNvC9backtrace3foo.llvm.A5310EB9 +_RNvNtNtNtNtCs92dm3009vxr_4rand4rngs7adapter9reseeding4fork23FORK_HANDLER_REGISTERED.0.0 +"; + +#[test] +fn test_demangle_lines() { + let demangled_lines = demangle_lines(MANGLED_LINES, None); + let mut iter = demangled_lines.iter(); + assert_eq!("", iter.next().unwrap()); + assert_eq!("123foo[0]::bar", iter.next().unwrap()); + assert_eq!("utf8_idents[317d481089b8c8fe]::საჭმელად_გემრიელი_სადილი", iter.next().unwrap()); + assert_eq!("cc[4d6468d6c9fd4bb3]::spawn::{closure#0}::{closure#0}", iter.next().unwrap()); + assert_eq!( + " as core[846817f741e54dfd]::iter::iterator::Iterator>::rposition::::{closure#0}", + iter.next().unwrap() + ); + assert_eq!( + "alloc[f15a878b47eb696b]::alloc::box_free::>", + iter.next().unwrap() + ); + assert_eq!("INtC8arrayvec8ArrayVechKj7b_E", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">::foo::FOO", iter.next().unwrap()); + assert_eq!("foo[0]", iter.next().unwrap()); + assert_eq!("foo[0]", iter.next().unwrap()); + assert_eq!("backtrace[0]::foo", iter.next().unwrap()); + assert_eq!( + "rand[693ea8e72247470f]::rngs::adapter::reseeding::fork::FORK_HANDLER_REGISTERED.0.0", + iter.next().unwrap() + ); + assert_eq!("", iter.next().unwrap()); + assert!(iter.next().is_none()); +} + +#[test] +fn test_demangle_lines_no_crate_disambiguators() { + let demangled_lines = demangle_lines(MANGLED_LINES, Some(create_disambiguator_re())); + let mut iter = demangled_lines.iter(); + assert_eq!("", iter.next().unwrap()); + assert_eq!("123foo[0]::bar", iter.next().unwrap()); + assert_eq!("utf8_idents::საჭმელად_გემრიელი_სადილი", iter.next().unwrap()); + assert_eq!("cc::spawn::{closure#0}::{closure#0}", iter.next().unwrap()); + assert_eq!( + " as core::iter::iterator::Iterator>::rposition::::{closure#0}", + iter.next().unwrap() + ); + assert_eq!( + "alloc::alloc::box_free::>", + iter.next().unwrap() + ); + assert_eq!("INtC8arrayvec8ArrayVechKj7b_E", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">", iter.next().unwrap()); + assert_eq!(">::foo::FOO", iter.next().unwrap()); + assert_eq!("foo[0]", iter.next().unwrap()); + assert_eq!("foo[0]", iter.next().unwrap()); + assert_eq!("backtrace[0]::foo", iter.next().unwrap()); + assert_eq!( + "rand::rngs::adapter::reseeding::fork::FORK_HANDLER_REGISTERED.0.0", + iter.next().unwrap() + ); + assert_eq!("", iter.next().unwrap()); + assert!(iter.next().is_none()); +} From c2a8bfe0ab54fa2a2682e05e59bc96d9363760f0 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Mon, 29 Mar 2021 08:28:52 -0700 Subject: [PATCH 324/370] Changed function signature to keep buffer handling out of lib --- src/tools/rust-demangler/src/lib.rs | 5 ++--- src/tools/rust-demangler/src/main.rs | 3 ++- src/tools/rust-demangler/tests/lib.rs | 8 +++----- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/tools/rust-demangler/src/lib.rs b/src/tools/rust-demangler/src/lib.rs index 4d2911ee7f8..1d972229d95 100644 --- a/src/tools/rust-demangler/src/lib.rs +++ b/src/tools/rust-demangler/src/lib.rs @@ -1,5 +1,6 @@ use regex::Regex; use rustc_demangle::demangle; +use std::str::Lines; const REPLACE_COLONS: &str = "::"; @@ -7,8 +8,7 @@ pub fn create_disambiguator_re() -> Regex { Regex::new(r"\[[a-f0-9]{5,16}\]::").unwrap() } -pub fn demangle_lines(buffer: &str, strip_crate_disambiguators: Option) -> Vec { - let lines = buffer.lines(); +pub fn demangle_lines(lines: Lines<'_>, strip_crate_disambiguators: Option) -> Vec { let mut demangled_lines = Vec::new(); for mangled in lines { let mut demangled = demangle(mangled).to_string(); @@ -17,6 +17,5 @@ pub fn demangle_lines(buffer: &str, strip_crate_disambiguators: Option) - } demangled_lines.push(demangled); } - demangled_lines.push("".to_string()); demangled_lines } diff --git a/src/tools/rust-demangler/src/main.rs b/src/tools/rust-demangler/src/main.rs index a87369d7baa..1b5ef5d2442 100644 --- a/src/tools/rust-demangler/src/main.rs +++ b/src/tools/rust-demangler/src/main.rs @@ -90,7 +90,8 @@ fn main() -> io::Result<()> { let mut buffer = String::new(); io::stdin().read_to_string(&mut buffer)?; - let demangled_lines = demangle_lines(&buffer, strip_crate_disambiguators); + let mut demangled_lines = demangle_lines(buffer.lines(), strip_crate_disambiguators); + demangled_lines.push("".to_string()); // ensure a trailing newline io::stdout().write_all(demangled_lines.join("\n").as_bytes())?; Ok(()) } diff --git a/src/tools/rust-demangler/tests/lib.rs b/src/tools/rust-demangler/tests/lib.rs index 8a1647601e4..09752fd7212 100644 --- a/src/tools/rust-demangler/tests/lib.rs +++ b/src/tools/rust-demangler/tests/lib.rs @@ -1,6 +1,6 @@ use rust_demangler::*; -const MANGLED_LINES: &str = r" +const MANGLED_INPUT: &str = r" _RNvC6_123foo3bar _RNqCs4fqI2P2rA04_11utf8_identsu30____7hkackfecea1cbdathfdh9hlq6y _RNCNCNgCs6DXkGYLi8lr_2cc5spawn00B5_ @@ -24,7 +24,7 @@ _RNvNtNtNtNtCs92dm3009vxr_4rand4rngs7adapter9reseeding4fork23FORK_HANDLER_REGIST #[test] fn test_demangle_lines() { - let demangled_lines = demangle_lines(MANGLED_LINES, None); + let demangled_lines = demangle_lines(MANGLED_INPUT.lines(), None); let mut iter = demangled_lines.iter(); assert_eq!("", iter.next().unwrap()); assert_eq!("123foo[0]::bar", iter.next().unwrap()); @@ -55,13 +55,12 @@ fn test_demangle_lines() { "rand[693ea8e72247470f]::rngs::adapter::reseeding::fork::FORK_HANDLER_REGISTERED.0.0", iter.next().unwrap() ); - assert_eq!("", iter.next().unwrap()); assert!(iter.next().is_none()); } #[test] fn test_demangle_lines_no_crate_disambiguators() { - let demangled_lines = demangle_lines(MANGLED_LINES, Some(create_disambiguator_re())); + let demangled_lines = demangle_lines(MANGLED_INPUT.lines(), Some(create_disambiguator_re())); let mut iter = demangled_lines.iter(); assert_eq!("", iter.next().unwrap()); assert_eq!("123foo[0]::bar", iter.next().unwrap()); @@ -92,6 +91,5 @@ fn test_demangle_lines_no_crate_disambiguators() { "rand::rngs::adapter::reseeding::fork::FORK_HANDLER_REGISTERED.0.0", iter.next().unwrap() ); - assert_eq!("", iter.next().unwrap()); assert!(iter.next().is_none()); } From 3ea62cb5d19846b44172d861ae231c8c09322800 Mon Sep 17 00:00:00 2001 From: Simon Jakobi Date: Sat, 3 Apr 2021 13:05:11 +0200 Subject: [PATCH 325/370] Remove redundant `ignore-tidy-linelength` annotations This is step 2 towards fixing #77548. In the codegen and codegen-units test suites, the `//` comment markers were kept in order not to affect any source locations. This is because these tests cannot be automatically `--bless`ed. --- .../drop_in_place_intrinsic.rs | 2 +- .../item-collection/function-as-argument.rs | 2 +- .../item-collection/generic-drop-glue.rs | 2 +- .../instantiation-through-vtable.rs | 2 +- .../item-collection/non-generic-closures.rs | 2 +- .../item-collection/non-generic-drop-glue.rs | 2 +- .../trait-method-as-argument.rs | 2 +- .../item-collection/transitive-drop-glue.rs | 2 +- .../item-collection/tuple-drop-glue.rs | 2 +- .../partitioning/extern-drop-glue.rs | 2 +- .../partitioning/extern-generic.rs | 2 +- .../inlining-from-extern-crate.rs | 2 +- .../partitioning/local-drop-glue.rs | 2 +- .../local-inlining-but-not-all.rs | 2 +- .../partitioning/local-inlining.rs | 2 +- .../partitioning/local-transitive-inlining.rs | 2 +- .../methods-are-with-self-type.rs | 2 +- .../partitioning/shared-generics.rs | 2 +- .../partitioning/vtable-through-const.rs | 2 +- src/test/codegen/align-enum.rs | 2 +- src/test/codegen/align-struct.rs | 2 +- src/test/codegen/async-fn-debug-msvc.rs | 2 +- src/test/codegen/async-fn-debug.rs | 2 +- src/test/codegen/c-variadic.rs | 2 +- src/test/codegen/consts.rs | 2 +- src/test/codegen/debug-compile-unit-path.rs | 2 +- src/test/codegen/enum-debug-clike.rs | 2 +- src/test/codegen/enum-debug-niche-2.rs | 2 +- src/test/codegen/function-arguments.rs | 2 +- src/test/codegen/gdb_debug_script_load.rs | 2 +- src/test/codegen/generator-debug-msvc.rs | 2 +- src/test/codegen/generator-debug.rs | 2 +- src/test/codegen/inline-debuginfo.rs | 2 +- src/test/codegen/instrument-mcount.rs | 2 +- .../codegen/issue-44056-macos-tls-align.rs | 2 +- src/test/codegen/packed.rs | 2 +- .../auxiliary/remap_path_prefix_aux.rs | 2 +- .../auxiliary/xcrate-generic.rs | 2 +- src/test/codegen/remap_path_prefix/main.rs | 2 +- src/test/codegen/repeat-trusted-len.rs | 2 +- .../codegen/repr-transparent-aggregates-1.rs | 2 +- .../codegen/repr-transparent-aggregates-2.rs | 2 +- .../codegen/repr-transparent-aggregates-3.rs | 2 +- .../riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs | 2 +- .../codegen/riscv-abi/riscv64-lp64d-abi.rs | 2 +- .../riscv-abi/riscv64-lp64f-lp64d-abi.rs | 2 +- ...intrinsic-generic-arithmetic-saturating.rs | 2 +- .../simd-intrinsic-generic-bitmask.rs | 2 +- .../simd-intrinsic-generic-gather.rs | 2 +- .../simd-intrinsic-generic-scatter.rs | 2 +- .../simd-intrinsic-transmute-array.rs | 2 +- src/test/codegen/stores.rs | 2 +- src/test/codegen/target-cpu-on-functions.rs | 2 +- src/test/codegen/tune-cpu-on-functions.rs | 2 +- src/test/debuginfo/borrowed-enum.rs | 2 - src/test/debuginfo/boxed-struct.rs | 2 - .../by-value-non-immediate-argument.rs | 1 - .../debuginfo/c-style-enum-in-composite.rs | 1 - src/test/debuginfo/c-style-enum.rs | 2 - .../destructured-for-loop-variable.rs | 2 - src/test/debuginfo/evec-in-struct.rs | 2 - .../debuginfo/function-arg-initialization.rs | 1 - .../debuginfo/gdb-pretty-struct-and-enums.rs | 1 - src/test/debuginfo/generator-objects.rs | 2 - .../generic-method-on-generic-struct.rs | 2 - .../debuginfo/generic-struct-style-enum.rs | 1 - src/test/debuginfo/generic-struct.rs | 2 - .../debuginfo/generic-tuple-style-enum.rs | 2 - src/test/debuginfo/issue-57822.rs | 1 - src/test/debuginfo/method-on-enum.rs | 1 - src/test/debuginfo/option-like-enum.rs | 1 - .../packed-struct-with-destructor.rs | 1 - src/test/debuginfo/packed-struct.rs | 1 - src/test/debuginfo/pretty-std-collections.rs | 1 - src/test/debuginfo/simd.rs | 1 - src/test/debuginfo/simple-struct.rs | 2 - src/test/debuginfo/struct-in-enum.rs | 1 - src/test/debuginfo/struct-in-struct.rs | 1 - src/test/debuginfo/struct-style-enum.rs | 2 - src/test/debuginfo/struct-with-destructor.rs | 2 - src/test/debuginfo/tuple-in-struct.rs | 2 - src/test/debuginfo/tuple-struct.rs | 2 - src/test/debuginfo/tuple-style-enum.rs | 2 - src/test/debuginfo/type-names.rs | 1 - src/test/debuginfo/vec-slices.rs | 2 - .../mir-opt/early_otherwise_branch_68867.rs | 1 - ...h.before-SimplifyBranches-final.after.diff | 500 +++++++++--------- ...ch_68867.try_sum.EarlyOtherwiseBranch.diff | 322 +++++------ .../rustdoc-ui/commandline-argfile-missing.rs | 1 - src/test/rustdoc-ui/doc-spotlight.fixed | 1 - src/test/rustdoc-ui/doc-spotlight.rs | 1 - src/test/rustdoc-ui/doc-spotlight.stderr | 2 +- src/test/rustdoc/assoc-item-cast.rs | 1 - src/test/rustdoc/assoc-types.rs | 2 - src/test/rustdoc/async-fn.rs | 1 - src/test/rustdoc/const-display.rs | 2 - src/test/rustdoc/const-generics/add-impl.rs | 2 - src/test/rustdoc/const-generics/const-impl.rs | 2 - src/test/rustdoc/const-generics/type-alias.rs | 1 - src/test/rustdoc/deref-recursive-pathbuf.rs | 2 - src/test/rustdoc/deref-recursive.rs | 2 - src/test/rustdoc/deref-typedef.rs | 2 - src/test/rustdoc/double-quote-escape.rs | 1 - src/test/rustdoc/duplicate-cfg.rs | 2 - src/test/rustdoc/fn-type.rs | 2 - src/test/rustdoc/for-lifetime.rs | 2 - src/test/rustdoc/inline_cross/impl_trait.rs | 1 - .../rustdoc/intra-doc/associated-defaults.rs | 1 - .../rustdoc/intra-doc/associated-items.rs | 1 - .../rustdoc/intra-doc/cross-crate/macro.rs | 1 - .../rustdoc/intra-doc/cross-crate/traits.rs | 1 - .../intra-doc/disambiguators-removed.rs | 1 - .../rustdoc/intra-doc/non-path-primitives.rs | 1 - src/test/rustdoc/intra-doc/prim-assoc.rs | 1 - .../intra-doc/prim-methods-external-core.rs | 1 - .../rustdoc/intra-doc/prim-methods-local.rs | 1 - src/test/rustdoc/intra-doc/prim-methods.rs | 1 - src/test/rustdoc/intra-doc/prim-precedence.rs | 1 - .../intra-doc/primitive-non-default-impl.rs | 1 - src/test/rustdoc/intra-doc/self.rs | 1 - src/test/rustdoc/intra-doc/trait-impl.rs | 1 - src/test/rustdoc/intra-doc/trait-item.rs | 1 - src/test/rustdoc/intra-doc/true-false.rs | 1 - src/test/rustdoc/issue-29503.rs | 2 - src/test/rustdoc/issue-55364.rs | 2 - src/test/rustdoc/issue-75588.rs | 1 - src/test/rustdoc/playground-arg.rs | 1 - src/test/rustdoc/playground.rs | 2 - src/test/rustdoc/primitive-link.rs | 1 - .../rustdoc/raw-ident-eliminate-r-hashtag.rs | 2 - src/test/rustdoc/smart-punct.rs | 2 - src/test/rustdoc/src-links-external.rs | 1 - src/test/rustdoc/struct-field.rs | 1 - src/test/rustdoc/trait-attributes.rs | 1 - .../ambiguous-associated-type2.rs | 2 - .../ambiguous-associated-type2.stderr | 4 +- .../duplicate.full_tait.stderr | 142 ++--- .../duplicate.min_tait.stderr | 140 ++--- .../ui/associated-type-bounds/duplicate.rs | 2 - .../issue-61949-self-return-type.rs | 1 - .../issue-61949-self-return-type.stderr | 2 +- .../ui/borrowck/borrowck-describe-lvalue.rs | 2 - .../borrowck/borrowck-describe-lvalue.stderr | 64 +-- src/test/ui/borrowck/borrowck-union-borrow.rs | 2 - .../ui/borrowck/borrowck-union-borrow.stderr | 24 +- ...ccess-during-reservation.nll_target.stderr | 4 +- ...o-phase-allow-access-during-reservation.rs | 2 - ...ion-sharing-interference.nll_target.stderr | 2 +- ...-phase-reservation-sharing-interference.rs | 2 - src/test/ui/commandline-argfile-missing.rs | 1 - src/test/ui/consts/issue-32829-2.rs | 2 - src/test/ui/consts/issue-32829-2.stderr | 6 +- src/test/ui/consts/offset_ub.rs | 1 - src/test/ui/consts/offset_ub.stderr | 44 +- src/test/ui/deprecation/deprecation-lint.rs | 1 - .../ui/deprecation/deprecation-lint.stderr | 246 ++++----- .../rustc_deprecation-in-future.rs | 2 - .../rustc_deprecation-in-future.stderr | 6 +- src/test/ui/error-codes/E0063.rs | 2 - src/test/ui/error-codes/E0063.stderr | 8 +- src/test/ui/export-fully-qualified.rs | 2 - src/test/ui/export-fully-qualified.stderr | 2 +- src/test/ui/feature-gates/feature-gate-abi.rs | 1 - .../ui/feature-gates/feature-gate-abi.stderr | 152 +++--- .../feature-gate-rustc-attrs-1.rs | 2 - .../feature-gate-rustc-attrs-1.stderr | 6 +- ...sue-43106-gating-of-builtin-attrs-error.rs | 1 - ...43106-gating-of-builtin-attrs-error.stderr | 72 +-- .../issue-43106-gating-of-builtin-attrs.rs | 1 - ...issue-43106-gating-of-builtin-attrs.stderr | 416 +++++++-------- .../ui/impl-trait/bound-normalization-fail.rs | 1 - .../bound-normalization-fail.stderr | 8 +- .../impl-trait/issue-55872-1.full_tait.stderr | 10 +- .../impl-trait/issue-55872-1.min_tait.stderr | 8 +- src/test/ui/impl-trait/issue-55872-1.rs | 1 - .../impl-trait/issue-55872-2.full_tait.stderr | 6 +- .../impl-trait/issue-55872-2.min_tait.stderr | 4 +- src/test/ui/impl-trait/issue-55872-2.rs | 1 - .../impl-trait/issue-55872.full_tait.stderr | 4 +- .../ui/impl-trait/issue-55872.min_tait.stderr | 2 +- src/test/ui/impl-trait/issue-55872.rs | 1 - .../extern-prelude-extern-crate-fail.rs | 2 - .../extern-prelude-extern-crate-fail.stderr | 4 +- src/test/ui/issues/issue-3214.rs | 2 - src/test/ui/issues/issue-3214.stderr | 8 +- src/test/ui/issues/issue-45157.rs | 1 - src/test/ui/issues/issue-45157.stderr | 2 +- src/test/ui/issues/issue-47725.rs | 1 - src/test/ui/issues/issue-47725.stderr | 14 +- src/test/ui/issues/issue-53251.rs | 2 - src/test/ui/issues/issue-53251.stderr | 8 +- src/test/ui/issues/issue-54044.rs | 1 - src/test/ui/issues/issue-54044.stderr | 6 +- src/test/ui/issues/issue-60622.rs | 2 - src/test/ui/issues/issue-60622.stderr | 8 +- .../ui/issues/issue-82833-slice-miscompile.rs | 1 - src/test/ui/kinds-of-primitive-impl.rs | 3 - src/test/ui/kinds-of-primitive-impl.stderr | 6 +- src/test/ui/lint/lint-stability-deprecated.rs | 1 - .../ui/lint/lint-stability-deprecated.stderr | 218 ++++---- src/test/ui/lint/uninitialized-zeroed.rs | 1 - src/test/ui/lint/uninitialized-zeroed.stderr | 98 ++-- .../loops/loops-reject-duplicate-labels-2.rs | 1 - .../loops-reject-duplicate-labels-2.stderr | 16 +- .../ui/loops/loops-reject-duplicate-labels.rs | 1 - .../loops-reject-duplicate-labels.stderr | 16 +- .../macro-or-patterns-back-compat.fixed | 1 - .../macros/macro-or-patterns-back-compat.rs | 1 - .../macro-or-patterns-back-compat.stderr | 10 +- .../methods/method-call-lifetime-args-fail.rs | 2 - .../method-call-lifetime-args-fail.stderr | 108 ++-- src/test/ui/nll/issue-51268.rs | 2 - src/test/ui/nll/issue-51268.stderr | 2 +- src/test/ui/nll/issue-57100.rs | 1 - src/test/ui/nll/issue-57100.stderr | 4 +- .../ui/non-ice-error-on-worker-io-fail.rs | 1 - .../ui/panic-runtime/two-panic-runtimes.rs | 1 - .../unwind-tables-panic-required.rs | 1 - .../unwind-tables-target-required.rs | 1 - src/test/ui/parser/duplicate-visibility.rs | 2 - .../ui/parser/duplicate-visibility.stderr | 2 +- .../issue-66357-unexpected-unreachable.rs | 2 - .../issue-66357-unexpected-unreachable.stderr | 4 +- src/test/ui/parser/unicode-quote-chars.rs | 2 - src/test/ui/parser/unicode-quote-chars.stderr | 6 +- .../usefulness/refutable-pattern-errors.rs | 2 - .../refutable-pattern-errors.stderr | 4 +- .../privacy/associated-item-privacy-trait.rs | 2 - .../associated-item-privacy-trait.stderr | 60 +-- src/test/ui/proc-macro/meta-macro-hygiene.rs | 1 - .../ui/proc-macro/meta-macro-hygiene.stdout | 3 +- src/test/ui/regions/regions-enum-not-wf.rs | 2 - .../ui/regions/regions-enum-not-wf.stderr | 6 +- .../regions-enum-not-wf.rs | 2 - .../regions-enum-not-wf.stderr | 6 +- ...intrinsic-generic-arithmetic-saturating.rs | 1 - ...insic-generic-arithmetic-saturating.stderr | 4 +- .../simd-type-generic-monomorphisation.rs | 1 - src/test/ui/simd/simd-type.rs | 1 - src/test/ui/simd/simd-type.stderr | 12 +- src/test/ui/single-primitive-inherent-impl.rs | 2 - .../ui/single-primitive-inherent-impl.stderr | 2 +- .../generics-default-stability-where.rs | 1 - .../generics-default-stability-where.stderr | 2 +- .../generics-default-stability.rs | 1 - .../generics-default-stability.stderr | 142 ++--- .../structure-constructor-type-mismatch.rs | 2 - ...structure-constructor-type-mismatch.stderr | 30 +- src/test/ui/symbol-names/impl1.legacy.stderr | 24 +- src/test/ui/symbol-names/impl1.rs | 1 - src/test/ui/symbol-names/impl1.stderr | 26 - src/test/ui/symbol-names/impl1.v0.stderr | 24 +- .../ui/symbol-names/issue-60925.legacy.stderr | 6 +- src/test/ui/symbol-names/issue-60925.rs | 1 - src/test/ui/symbol-names/issue-60925.stderr | 20 - .../ui/symbol-names/issue-60925.v0.stderr | 6 +- .../ui/symbol-names/issue-75326.legacy.stderr | 6 +- src/test/ui/symbol-names/issue-75326.rs | 1 - .../ui/symbol-names/issue-75326.v0.stderr | 6 +- ...rrect-variant-form-through-alias-caught.rs | 2 - ...t-variant-form-through-alias-caught.stderr | 10 +- .../issue-53598.full_tait.stderr | 4 +- .../issue-53598.min_tait.stderr | 2 +- .../ui/type-alias-impl-trait/issue-53598.rs | 1 - .../issue-57700.full_tait.stderr | 4 +- .../issue-57700.min_tait.stderr | 2 +- .../ui/type-alias-impl-trait/issue-57700.rs | 1 - src/test/ui/union/union-deref.rs | 1 - src/test/ui/union/union-deref.stderr | 12 +- .../return-unsized-from-trait-method.rs | 2 - .../return-unsized-from-trait-method.stderr | 2 +- 271 files changed, 1616 insertions(+), 1868 deletions(-) delete mode 100644 src/test/ui/symbol-names/impl1.stderr delete mode 100644 src/test/ui/symbol-names/issue-60925.stderr diff --git a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs index f58117f44d8..a3f1fb5e7a2 100644 --- a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs +++ b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags:-Zprint-mono-items=eager // compile-flags:-Zinline-in-all-cgus diff --git a/src/test/codegen-units/item-collection/function-as-argument.rs b/src/test/codegen-units/item-collection/function-as-argument.rs index 2329dec385f..ea500c3111a 100644 --- a/src/test/codegen-units/item-collection/function-as-argument.rs +++ b/src/test/codegen-units/item-collection/function-as-argument.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags:-Zprint-mono-items=eager #![deny(dead_code)] diff --git a/src/test/codegen-units/item-collection/generic-drop-glue.rs b/src/test/codegen-units/item-collection/generic-drop-glue.rs index 948098b0cbc..25cf5dad614 100644 --- a/src/test/codegen-units/item-collection/generic-drop-glue.rs +++ b/src/test/codegen-units/item-collection/generic-drop-glue.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags:-Zprint-mono-items=eager // compile-flags:-Zinline-in-all-cgus diff --git a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs index 919c43738fb..e78226d4083 100644 --- a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs +++ b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags:-Zprint-mono-items=eager -Zinline-in-all-cgus -Zmir-opt-level=0 #![deny(dead_code)] diff --git a/src/test/codegen-units/item-collection/non-generic-closures.rs b/src/test/codegen-units/item-collection/non-generic-closures.rs index affdda39043..379fbcf2613 100644 --- a/src/test/codegen-units/item-collection/non-generic-closures.rs +++ b/src/test/codegen-units/item-collection/non-generic-closures.rs @@ -3,7 +3,7 @@ // ignoring this test until MIR codegen has taken over completely // ignore-test -// ignore-tidy-linelength +// // compile-flags:-Zprint-mono-items=eager #![deny(dead_code)] diff --git a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs index 720421d3e0f..06f76f7db36 100644 --- a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs +++ b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags:-Zprint-mono-items=eager // compile-flags:-Zinline-in-all-cgus diff --git a/src/test/codegen-units/item-collection/trait-method-as-argument.rs b/src/test/codegen-units/item-collection/trait-method-as-argument.rs index 6817b33c611..235569728a2 100644 --- a/src/test/codegen-units/item-collection/trait-method-as-argument.rs +++ b/src/test/codegen-units/item-collection/trait-method-as-argument.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags:-Zprint-mono-items=eager #![deny(dead_code)] diff --git a/src/test/codegen-units/item-collection/transitive-drop-glue.rs b/src/test/codegen-units/item-collection/transitive-drop-glue.rs index 2ec572b4373..8249e7cba94 100644 --- a/src/test/codegen-units/item-collection/transitive-drop-glue.rs +++ b/src/test/codegen-units/item-collection/transitive-drop-glue.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags:-Zprint-mono-items=eager // compile-flags:-Zinline-in-all-cgus diff --git a/src/test/codegen-units/item-collection/tuple-drop-glue.rs b/src/test/codegen-units/item-collection/tuple-drop-glue.rs index 232570779c8..ae3b2e081ff 100644 --- a/src/test/codegen-units/item-collection/tuple-drop-glue.rs +++ b/src/test/codegen-units/item-collection/tuple-drop-glue.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags:-Zprint-mono-items=eager // compile-flags:-Zinline-in-all-cgus diff --git a/src/test/codegen-units/partitioning/extern-drop-glue.rs b/src/test/codegen-units/partitioning/extern-drop-glue.rs index 6232b9edf82..8b0448ec470 100644 --- a/src/test/codegen-units/partitioning/extern-drop-glue.rs +++ b/src/test/codegen-units/partitioning/extern-drop-glue.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // We specify -C incremental here because we want to test the partitioning for // incremental compilation diff --git a/src/test/codegen-units/partitioning/extern-generic.rs b/src/test/codegen-units/partitioning/extern-generic.rs index 02930f96bd1..c96df6e102a 100644 --- a/src/test/codegen-units/partitioning/extern-generic.rs +++ b/src/test/codegen-units/partitioning/extern-generic.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // We specify -C incremental here because we want to test the partitioning for // incremental compilation // compile-flags:-Zprint-mono-items=eager -Cincremental=tmp/partitioning-tests/extern-generic -Zshare-generics=y diff --git a/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs b/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs index 410b77b0050..b86e325537b 100644 --- a/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs +++ b/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // We specify -C incremental here because we want to test the partitioning for // incremental compilation // compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/inlining-from-extern-crate diff --git a/src/test/codegen-units/partitioning/local-drop-glue.rs b/src/test/codegen-units/partitioning/local-drop-glue.rs index 3017e4f9494..78d69fdb7d8 100644 --- a/src/test/codegen-units/partitioning/local-drop-glue.rs +++ b/src/test/codegen-units/partitioning/local-drop-glue.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // We specify -C incremental here because we want to test the partitioning for // incremental compilation // We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing diff --git a/src/test/codegen-units/partitioning/local-inlining-but-not-all.rs b/src/test/codegen-units/partitioning/local-inlining-but-not-all.rs index a24943348f3..d53f7b62291 100644 --- a/src/test/codegen-units/partitioning/local-inlining-but-not-all.rs +++ b/src/test/codegen-units/partitioning/local-inlining-but-not-all.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // We specify -C incremental here because we want to test the partitioning for // incremental compilation // compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/local-inlining-but-not-all diff --git a/src/test/codegen-units/partitioning/local-inlining.rs b/src/test/codegen-units/partitioning/local-inlining.rs index 0cc652eeb52..1ea804b2f9d 100644 --- a/src/test/codegen-units/partitioning/local-inlining.rs +++ b/src/test/codegen-units/partitioning/local-inlining.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // We specify -C incremental here because we want to test the partitioning for // incremental compilation // compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/local-inlining diff --git a/src/test/codegen-units/partitioning/local-transitive-inlining.rs b/src/test/codegen-units/partitioning/local-transitive-inlining.rs index 0c8a67aeb3d..56d108074e4 100644 --- a/src/test/codegen-units/partitioning/local-transitive-inlining.rs +++ b/src/test/codegen-units/partitioning/local-transitive-inlining.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // We specify -C incremental here because we want to test the partitioning for // incremental compilation // compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/local-transitive-inlining diff --git a/src/test/codegen-units/partitioning/methods-are-with-self-type.rs b/src/test/codegen-units/partitioning/methods-are-with-self-type.rs index 6c55904c1bf..e67090303a3 100644 --- a/src/test/codegen-units/partitioning/methods-are-with-self-type.rs +++ b/src/test/codegen-units/partitioning/methods-are-with-self-type.rs @@ -3,7 +3,7 @@ // much sense at the moment. // ignore-test -// ignore-tidy-linelength +// // We specify -C incremental here because we want to test the partitioning for // incremental compilation // compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/methods-are-with-self-type diff --git a/src/test/codegen-units/partitioning/shared-generics.rs b/src/test/codegen-units/partitioning/shared-generics.rs index eb3196439ba..17c1fbb2f73 100644 --- a/src/test/codegen-units/partitioning/shared-generics.rs +++ b/src/test/codegen-units/partitioning/shared-generics.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // no-prefer-dynamic // NOTE: We always compile this test with -Copt-level=0 because higher opt-levels // prevent drop-glue from participating in share-generics. diff --git a/src/test/codegen-units/partitioning/vtable-through-const.rs b/src/test/codegen-units/partitioning/vtable-through-const.rs index 8028c4f5f0b..f6ae46b0551 100644 --- a/src/test/codegen-units/partitioning/vtable-through-const.rs +++ b/src/test/codegen-units/partitioning/vtable-through-const.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // We specify -C incremental here because we want to test the partitioning for // incremental compilation diff --git a/src/test/codegen/align-enum.rs b/src/test/codegen/align-enum.rs index 95ca7cfe750..0f2cf5a7616 100644 --- a/src/test/codegen/align-enum.rs +++ b/src/test/codegen/align-enum.rs @@ -1,5 +1,5 @@ // compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 -// ignore-tidy-linelength +// #![crate_type = "lib"] diff --git a/src/test/codegen/align-struct.rs b/src/test/codegen/align-struct.rs index cda7235a3d8..82eec67af0f 100644 --- a/src/test/codegen/align-struct.rs +++ b/src/test/codegen/align-struct.rs @@ -1,5 +1,5 @@ // compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 -// ignore-tidy-linelength +// #![crate_type = "lib"] diff --git a/src/test/codegen/async-fn-debug-msvc.rs b/src/test/codegen/async-fn-debug-msvc.rs index 4e145b81ecb..2b8c0dfc229 100644 --- a/src/test/codegen/async-fn-debug-msvc.rs +++ b/src/test/codegen/async-fn-debug-msvc.rs @@ -3,7 +3,7 @@ // - The generator types and variants are marked artificial // - Captured vars from the source are not marked artificial // -// ignore-tidy-linelength +// // compile-flags: -C debuginfo=2 --edition=2018 // only-msvc diff --git a/src/test/codegen/async-fn-debug.rs b/src/test/codegen/async-fn-debug.rs index 8fa4be1ae86..e9b774b48c3 100644 --- a/src/test/codegen/async-fn-debug.rs +++ b/src/test/codegen/async-fn-debug.rs @@ -3,7 +3,7 @@ // - The generator types and variants are marked artificial // - Captured vars from the source are not marked artificial // -// ignore-tidy-linelength +// // compile-flags: -C debuginfo=2 --edition=2018 // ignore-msvc diff --git a/src/test/codegen/c-variadic.rs b/src/test/codegen/c-variadic.rs index 29c82686731..e038ed70451 100644 --- a/src/test/codegen/c-variadic.rs +++ b/src/test/codegen/c-variadic.rs @@ -1,6 +1,6 @@ // ignore-wasm32-bare compiled with panic=abort by default // compile-flags: -C no-prepopulate-passes -// ignore-tidy-linelength +// #![crate_type = "lib"] #![feature(c_variadic)] diff --git a/src/test/codegen/consts.rs b/src/test/codegen/consts.rs index fcb9002986a..3aab4bea3d0 100644 --- a/src/test/codegen/consts.rs +++ b/src/test/codegen/consts.rs @@ -1,5 +1,5 @@ // compile-flags: -C no-prepopulate-passes -// ignore-tidy-linelength +// #![crate_type = "lib"] diff --git a/src/test/codegen/debug-compile-unit-path.rs b/src/test/codegen/debug-compile-unit-path.rs index fcb66e08576..3661be046d0 100644 --- a/src/test/codegen/debug-compile-unit-path.rs +++ b/src/test/codegen/debug-compile-unit-path.rs @@ -1,5 +1,5 @@ // compile-flags: -g --remap-path-prefix={{cwd}}=/cwd/ --remap-path-prefix={{src-base}}=/base/ -// ignore-tidy-linelength +// // // Ensure that we remap the compile unit directory and that we set it to the compilers current // working directory and not something else. diff --git a/src/test/codegen/enum-debug-clike.rs b/src/test/codegen/enum-debug-clike.rs index 134443931e9..1e369a2c4e6 100644 --- a/src/test/codegen/enum-debug-clike.rs +++ b/src/test/codegen/enum-debug-clike.rs @@ -1,7 +1,7 @@ // This tests that debug info for "c-like" enums is properly emitted. // This is ignored for the fallback mode on MSVC due to problems with PDB. -// ignore-tidy-linelength +// // ignore-msvc // compile-flags: -g -C no-prepopulate-passes diff --git a/src/test/codegen/enum-debug-niche-2.rs b/src/test/codegen/enum-debug-niche-2.rs index 0f78234d977..9c72ad9d248 100644 --- a/src/test/codegen/enum-debug-niche-2.rs +++ b/src/test/codegen/enum-debug-niche-2.rs @@ -1,7 +1,7 @@ // This tests that optimized enum debug info accurately reflects the enum layout. // This is ignored for the fallback mode on MSVC due to problems with PDB. -// ignore-tidy-linelength +// // ignore-msvc // compile-flags: -g -C no-prepopulate-passes diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs index 0c34bf1b914..f936f909603 100644 --- a/src/test/codegen/function-arguments.rs +++ b/src/test/codegen/function-arguments.rs @@ -1,5 +1,5 @@ // compile-flags: -O -C no-prepopulate-passes -// ignore-tidy-linelength +// // min-system-llvm-version: 12.0 #![crate_type = "lib"] diff --git a/src/test/codegen/gdb_debug_script_load.rs b/src/test/codegen/gdb_debug_script_load.rs index 178269f611e..856b67bf9df 100644 --- a/src/test/codegen/gdb_debug_script_load.rs +++ b/src/test/codegen/gdb_debug_script_load.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // ignore-windows // ignore-macos // ignore-wasm diff --git a/src/test/codegen/generator-debug-msvc.rs b/src/test/codegen/generator-debug-msvc.rs index 82a1568ea95..4f8a320ee9b 100644 --- a/src/test/codegen/generator-debug-msvc.rs +++ b/src/test/codegen/generator-debug-msvc.rs @@ -3,7 +3,7 @@ // - The generator types and variants are marked artificial // - Captured vars from the source are not marked artificial // -// ignore-tidy-linelength +// // compile-flags: -C debuginfo=2 // only-msvc diff --git a/src/test/codegen/generator-debug.rs b/src/test/codegen/generator-debug.rs index 5c7c6414818..86ac6db702a 100644 --- a/src/test/codegen/generator-debug.rs +++ b/src/test/codegen/generator-debug.rs @@ -3,7 +3,7 @@ // - The generator types and variants are marked artificial // - Captured vars from the source are not marked artificial // -// ignore-tidy-linelength +// // compile-flags: -C debuginfo=2 --edition=2018 // ignore-msvc diff --git a/src/test/codegen/inline-debuginfo.rs b/src/test/codegen/inline-debuginfo.rs index 1546dfa10a3..5b230361f39 100644 --- a/src/test/codegen/inline-debuginfo.rs +++ b/src/test/codegen/inline-debuginfo.rs @@ -1,6 +1,6 @@ #![crate_type="rlib"] // compile-flags: -Copt-level=3 -g -// ignore-tidy-linelength +// #[no_mangle] #[inline(always)] diff --git a/src/test/codegen/instrument-mcount.rs b/src/test/codegen/instrument-mcount.rs index 518a2a0da2a..b26076e7a7b 100644 --- a/src/test/codegen/instrument-mcount.rs +++ b/src/test/codegen/instrument-mcount.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags: -Z instrument-mcount #![crate_type = "lib"] diff --git a/src/test/codegen/issue-44056-macos-tls-align.rs b/src/test/codegen/issue-44056-macos-tls-align.rs index 2270eca5014..1a3923f1bb1 100644 --- a/src/test/codegen/issue-44056-macos-tls-align.rs +++ b/src/test/codegen/issue-44056-macos-tls-align.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // only-macos // no-system-llvm // compile-flags: -O diff --git a/src/test/codegen/packed.rs b/src/test/codegen/packed.rs index 6ab28e87cb6..dfa7803d4f2 100644 --- a/src/test/codegen/packed.rs +++ b/src/test/codegen/packed.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags: -O -C no-prepopulate-passes #![crate_type = "lib"] diff --git a/src/test/codegen/remap_path_prefix/auxiliary/remap_path_prefix_aux.rs b/src/test/codegen/remap_path_prefix/auxiliary/remap_path_prefix_aux.rs index b87a20e75f4..887915955b5 100644 --- a/src/test/codegen/remap_path_prefix/auxiliary/remap_path_prefix_aux.rs +++ b/src/test/codegen/remap_path_prefix/auxiliary/remap_path_prefix_aux.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags: -g --remap-path-prefix={{cwd}}=/the/aux-cwd --remap-path-prefix={{src-base}}/remap_path_prefix/auxiliary=/the/aux-src diff --git a/src/test/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs b/src/test/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs index 57e877ef0d0..59092dbf637 100644 --- a/src/test/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs +++ b/src/test/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags: -g --remap-path-prefix={{cwd}}=/the/aux-cwd --remap-path-prefix={{src-base}}/remap_path_prefix/auxiliary=/the/aux-src #![crate_type = "lib"] diff --git a/src/test/codegen/remap_path_prefix/main.rs b/src/test/codegen/remap_path_prefix/main.rs index 20475bab0fc..c2d01c7fec2 100644 --- a/src/test/codegen/remap_path_prefix/main.rs +++ b/src/test/codegen/remap_path_prefix/main.rs @@ -1,5 +1,5 @@ // ignore-windows -// ignore-tidy-linelength +// // compile-flags: -g -C no-prepopulate-passes --remap-path-prefix={{cwd}}=/the/cwd --remap-path-prefix={{src-base}}=/the/src // aux-build:remap_path_prefix_aux.rs diff --git a/src/test/codegen/repeat-trusted-len.rs b/src/test/codegen/repeat-trusted-len.rs index 8e08b78ad1e..9e904fc82ab 100644 --- a/src/test/codegen/repeat-trusted-len.rs +++ b/src/test/codegen/repeat-trusted-len.rs @@ -1,5 +1,5 @@ // compile-flags: -O -// ignore-tidy-linelength +// #![crate_type = "lib"] diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs index 847b94fac78..5c3bcc28878 100644 --- a/src/test/codegen/repr-transparent-aggregates-1.rs +++ b/src/test/codegen/repr-transparent-aggregates-1.rs @@ -1,5 +1,5 @@ // compile-flags: -C no-prepopulate-passes -// ignore-tidy-linelength +// // min-system-llvm-version: 12.0 // ignore-arm diff --git a/src/test/codegen/repr-transparent-aggregates-2.rs b/src/test/codegen/repr-transparent-aggregates-2.rs index 1fb12d92bd1..429d760b4aa 100644 --- a/src/test/codegen/repr-transparent-aggregates-2.rs +++ b/src/test/codegen/repr-transparent-aggregates-2.rs @@ -1,5 +1,5 @@ // compile-flags: -C no-prepopulate-passes -// ignore-tidy-linelength +// // min-system-llvm-version: 12.0 // ignore-aarch64 diff --git a/src/test/codegen/repr-transparent-aggregates-3.rs b/src/test/codegen/repr-transparent-aggregates-3.rs index 3381764bfc8..21176ac0e7a 100644 --- a/src/test/codegen/repr-transparent-aggregates-3.rs +++ b/src/test/codegen/repr-transparent-aggregates-3.rs @@ -1,5 +1,5 @@ // compile-flags: -C no-prepopulate-passes -// ignore-tidy-linelength +// // min-system-llvm-version: 12.0 // only-mips64 diff --git a/src/test/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs b/src/test/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs index 180ba07764b..693f0d99c4f 100644 --- a/src/test/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs +++ b/src/test/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags: -C no-prepopulate-passes // only-riscv64 // only-linux diff --git a/src/test/codegen/riscv-abi/riscv64-lp64d-abi.rs b/src/test/codegen/riscv-abi/riscv64-lp64d-abi.rs index 0b6e1878d4d..1555acadfbc 100644 --- a/src/test/codegen/riscv-abi/riscv64-lp64d-abi.rs +++ b/src/test/codegen/riscv-abi/riscv64-lp64d-abi.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags: -C no-prepopulate-passes // only-riscv64 // only-linux diff --git a/src/test/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs b/src/test/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs index 1cea6e3db2a..f08fabed421 100644 --- a/src/test/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs +++ b/src/test/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags: -C no-prepopulate-passes // only-riscv64 // only-linux diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs index 267c995e070..6fb0ceb4025 100644 --- a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs +++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs @@ -1,5 +1,5 @@ // compile-flags: -C no-prepopulate-passes -// ignore-tidy-linelength +// #![crate_type = "lib"] diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs index 87c8b0d87d8..4a98d797b52 100644 --- a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs +++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs @@ -1,5 +1,5 @@ // compile-flags: -C no-prepopulate-passes -// ignore-tidy-linelength +// #![crate_type = "lib"] diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs index 3b1f4398f90..e2e0fc16dfa 100644 --- a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs +++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags: -C no-prepopulate-passes diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs index 9fce849e523..050a0e5b426 100644 --- a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs +++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags: -C no-prepopulate-passes diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs index ae13d91ddeb..7d9b0d2a77b 100644 --- a/src/test/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs +++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs @@ -1,4 +1,4 @@ -// ignore-tidy-linelength +// // compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] diff --git a/src/test/codegen/stores.rs b/src/test/codegen/stores.rs index 4ea003e99ad..17f051a5bce 100644 --- a/src/test/codegen/stores.rs +++ b/src/test/codegen/stores.rs @@ -1,5 +1,5 @@ // compile-flags: -C no-prepopulate-passes -// ignore-tidy-linelength +// #![crate_type = "lib"] diff --git a/src/test/codegen/target-cpu-on-functions.rs b/src/test/codegen/target-cpu-on-functions.rs index 7544ac01309..c043eceb5cd 100644 --- a/src/test/codegen/target-cpu-on-functions.rs +++ b/src/test/codegen/target-cpu-on-functions.rs @@ -2,7 +2,7 @@ // "target-cpu" attribute in LLVM. // no-prefer-dynamic -// ignore-tidy-linelength +// // compile-flags: -C no-prepopulate-passes -C panic=abort -C linker-plugin-lto -Cpasses=name-anon-globals #![crate_type = "staticlib"] diff --git a/src/test/codegen/tune-cpu-on-functions.rs b/src/test/codegen/tune-cpu-on-functions.rs index 9121799cdbf..ed8dc0e9383 100644 --- a/src/test/codegen/tune-cpu-on-functions.rs +++ b/src/test/codegen/tune-cpu-on-functions.rs @@ -2,7 +2,7 @@ // "tune-cpu" attribute in LLVM. // no-prefer-dynamic -// ignore-tidy-linelength +// // compile-flags: -C no-prepopulate-passes -C panic=abort -C linker-plugin-lto -Cpasses=name-anon-globals -Z tune-cpu=generic #![crate_type = "staticlib"] diff --git a/src/test/debuginfo/borrowed-enum.rs b/src/test/debuginfo/borrowed-enum.rs index 85e11c10c68..f3e465dc652 100644 --- a/src/test/debuginfo/borrowed-enum.rs +++ b/src/test/debuginfo/borrowed-enum.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // Require a gdb or lldb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // rust-lldb diff --git a/src/test/debuginfo/boxed-struct.rs b/src/test/debuginfo/boxed-struct.rs index 04bdf728901..155088c61fe 100644 --- a/src/test/debuginfo/boxed-struct.rs +++ b/src/test/debuginfo/boxed-struct.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // min-lldb-version: 310 // compile-flags:-g diff --git a/src/test/debuginfo/by-value-non-immediate-argument.rs b/src/test/debuginfo/by-value-non-immediate-argument.rs index 11a115e2393..b417567dcfe 100644 --- a/src/test/debuginfo/by-value-non-immediate-argument.rs +++ b/src/test/debuginfo/by-value-non-immediate-argument.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // ignore-test // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // min-lldb-version: 310 diff --git a/src/test/debuginfo/c-style-enum-in-composite.rs b/src/test/debuginfo/c-style-enum-in-composite.rs index f859fe8d1ce..2ed49de58cd 100644 --- a/src/test/debuginfo/c-style-enum-in-composite.rs +++ b/src/test/debuginfo/c-style-enum-in-composite.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // min-lldb-version: 310 // compile-flags:-g diff --git a/src/test/debuginfo/c-style-enum.rs b/src/test/debuginfo/c-style-enum.rs index 5706d5c4cc6..dce34fc0dcf 100644 --- a/src/test/debuginfo/c-style-enum.rs +++ b/src/test/debuginfo/c-style-enum.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // ignore-aarch64 // ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // min-lldb-version: 310 diff --git a/src/test/debuginfo/destructured-for-loop-variable.rs b/src/test/debuginfo/destructured-for-loop-variable.rs index 868f2285f35..1532c83dfac 100644 --- a/src/test/debuginfo/destructured-for-loop-variable.rs +++ b/src/test/debuginfo/destructured-for-loop-variable.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // min-lldb-version: 310 // This fails on lldb 6.0.1 on x86-64 Fedora 28; so mark it macOS-only diff --git a/src/test/debuginfo/evec-in-struct.rs b/src/test/debuginfo/evec-in-struct.rs index 2033966adad..0d94cd224ec 100644 --- a/src/test/debuginfo/evec-in-struct.rs +++ b/src/test/debuginfo/evec-in-struct.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // min-lldb-version: 310 // compile-flags:-g diff --git a/src/test/debuginfo/function-arg-initialization.rs b/src/test/debuginfo/function-arg-initialization.rs index 8c86d2cf435..dea1339517b 100644 --- a/src/test/debuginfo/function-arg-initialization.rs +++ b/src/test/debuginfo/function-arg-initialization.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // ignore-test // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // min-lldb-version: 310 diff --git a/src/test/debuginfo/gdb-pretty-struct-and-enums.rs b/src/test/debuginfo/gdb-pretty-struct-and-enums.rs index 2a8359de522..3314f0a4e43 100644 --- a/src/test/debuginfo/gdb-pretty-struct-and-enums.rs +++ b/src/test/debuginfo/gdb-pretty-struct-and-enums.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // ignore-lldb // ignore-android: FIXME(#10381) // min-gdb-version: 8.1 diff --git a/src/test/debuginfo/generator-objects.rs b/src/test/debuginfo/generator-objects.rs index 0023f69d27f..b65471011fd 100644 --- a/src/test/debuginfo/generator-objects.rs +++ b/src/test/debuginfo/generator-objects.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // Require a gdb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 diff --git a/src/test/debuginfo/generic-method-on-generic-struct.rs b/src/test/debuginfo/generic-method-on-generic-struct.rs index f7767292222..85fe8ac08f3 100644 --- a/src/test/debuginfo/generic-method-on-generic-struct.rs +++ b/src/test/debuginfo/generic-method-on-generic-struct.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // compile-flags:-g // Some versions of the non-rust-enabled LLDB print the wrong generic diff --git a/src/test/debuginfo/generic-struct-style-enum.rs b/src/test/debuginfo/generic-struct-style-enum.rs index 678ca8df040..764330ae27f 100644 --- a/src/test/debuginfo/generic-struct-style-enum.rs +++ b/src/test/debuginfo/generic-struct-style-enum.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // min-lldb-version: 310 // Require a gdb that can read DW_TAG_variant_part. diff --git a/src/test/debuginfo/generic-struct.rs b/src/test/debuginfo/generic-struct.rs index 1d122ce285d..170a610c621 100644 --- a/src/test/debuginfo/generic-struct.rs +++ b/src/test/debuginfo/generic-struct.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // Some versions of the non-rust-enabled LLDB print the wrong generic // parameter type names in this test. // rust-lldb diff --git a/src/test/debuginfo/generic-tuple-style-enum.rs b/src/test/debuginfo/generic-tuple-style-enum.rs index 89aa78a6e10..60362e54e7d 100644 --- a/src/test/debuginfo/generic-tuple-style-enum.rs +++ b/src/test/debuginfo/generic-tuple-style-enum.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // Require a gdb or lldb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // rust-lldb diff --git a/src/test/debuginfo/issue-57822.rs b/src/test/debuginfo/issue-57822.rs index c2cc6f9d24c..a68e4c0a556 100644 --- a/src/test/debuginfo/issue-57822.rs +++ b/src/test/debuginfo/issue-57822.rs @@ -3,7 +3,6 @@ // Require a gdb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 -// ignore-tidy-linelength // compile-flags:-g diff --git a/src/test/debuginfo/method-on-enum.rs b/src/test/debuginfo/method-on-enum.rs index 94ca0289b78..80f4c2e1150 100644 --- a/src/test/debuginfo/method-on-enum.rs +++ b/src/test/debuginfo/method-on-enum.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // min-lldb-version: 310 // ignore-test // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 diff --git a/src/test/debuginfo/option-like-enum.rs b/src/test/debuginfo/option-like-enum.rs index 67a3d133ed3..04d08b9e6a5 100644 --- a/src/test/debuginfo/option-like-enum.rs +++ b/src/test/debuginfo/option-like-enum.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // ignore-test // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // min-lldb-version: 310 diff --git a/src/test/debuginfo/packed-struct-with-destructor.rs b/src/test/debuginfo/packed-struct-with-destructor.rs index 380e882a0fb..196d85b4181 100644 --- a/src/test/debuginfo/packed-struct-with-destructor.rs +++ b/src/test/debuginfo/packed-struct-with-destructor.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // min-lldb-version: 310 // compile-flags:-g diff --git a/src/test/debuginfo/packed-struct.rs b/src/test/debuginfo/packed-struct.rs index 9654847ce5d..7d1893a9431 100644 --- a/src/test/debuginfo/packed-struct.rs +++ b/src/test/debuginfo/packed-struct.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // min-lldb-version: 310 // ignore-gdb-version: 7.11.90 - 7.12.9 diff --git a/src/test/debuginfo/pretty-std-collections.rs b/src/test/debuginfo/pretty-std-collections.rs index 8026550882d..93597aa7e23 100644 --- a/src/test/debuginfo/pretty-std-collections.rs +++ b/src/test/debuginfo/pretty-std-collections.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // ignore-windows failing on win32 bot // ignore-freebsd: gdb package too new // ignore-android: FIXME(#10381) diff --git a/src/test/debuginfo/simd.rs b/src/test/debuginfo/simd.rs index e41acc2e1ec..b7bfe44b6ec 100644 --- a/src/test/debuginfo/simd.rs +++ b/src/test/debuginfo/simd.rs @@ -1,6 +1,5 @@ // Need a fix for LLDB first... // ignore-lldb -// ignore-tidy-linelength // FIXME: LLVM generates invalid debug info for variables requiring // dynamic stack realignment, which is the case on s390x for vector diff --git a/src/test/debuginfo/simple-struct.rs b/src/test/debuginfo/simple-struct.rs index 49aa3bcbcaa..aa3cf023a71 100644 --- a/src/test/debuginfo/simple-struct.rs +++ b/src/test/debuginfo/simple-struct.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // min-lldb-version: 310 // ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 diff --git a/src/test/debuginfo/struct-in-enum.rs b/src/test/debuginfo/struct-in-enum.rs index db20e9d3e45..41d15af14ed 100644 --- a/src/test/debuginfo/struct-in-enum.rs +++ b/src/test/debuginfo/struct-in-enum.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // min-lldb-version: 310 // ignore-gdb-version: 7.11.90 - 7.12.9 // ignore-test // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 diff --git a/src/test/debuginfo/struct-in-struct.rs b/src/test/debuginfo/struct-in-struct.rs index a76a4c05d9b..a9e7797ec70 100644 --- a/src/test/debuginfo/struct-in-struct.rs +++ b/src/test/debuginfo/struct-in-struct.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // min-lldb-version: 310 // compile-flags:-g diff --git a/src/test/debuginfo/struct-style-enum.rs b/src/test/debuginfo/struct-style-enum.rs index 34f75a4e304..3d819e36898 100644 --- a/src/test/debuginfo/struct-style-enum.rs +++ b/src/test/debuginfo/struct-style-enum.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // Require a gdb or lldb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // rust-lldb diff --git a/src/test/debuginfo/struct-with-destructor.rs b/src/test/debuginfo/struct-with-destructor.rs index ebae953cb4b..4334cd9028b 100644 --- a/src/test/debuginfo/struct-with-destructor.rs +++ b/src/test/debuginfo/struct-with-destructor.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // min-lldb-version: 310 // compile-flags:-g diff --git a/src/test/debuginfo/tuple-in-struct.rs b/src/test/debuginfo/tuple-in-struct.rs index c43c1f7bf6d..759eab8e8a0 100644 --- a/src/test/debuginfo/tuple-in-struct.rs +++ b/src/test/debuginfo/tuple-in-struct.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // min-lldb-version: 310 // compile-flags:-g diff --git a/src/test/debuginfo/tuple-struct.rs b/src/test/debuginfo/tuple-struct.rs index 78b6e6a54db..b8702f970a3 100644 --- a/src/test/debuginfo/tuple-struct.rs +++ b/src/test/debuginfo/tuple-struct.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // min-lldb-version: 310 // compile-flags:-g diff --git a/src/test/debuginfo/tuple-style-enum.rs b/src/test/debuginfo/tuple-style-enum.rs index 87b0bc6294d..39ead172e65 100644 --- a/src/test/debuginfo/tuple-style-enum.rs +++ b/src/test/debuginfo/tuple-style-enum.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // Require a gdb or lldb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // rust-lldb diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs index 43e68fedbfa..cc4a4476d16 100644 --- a/src/test/debuginfo/type-names.rs +++ b/src/test/debuginfo/type-names.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // ignore-lldb // ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 diff --git a/src/test/debuginfo/vec-slices.rs b/src/test/debuginfo/vec-slices.rs index c385491bd1d..e109b1bf2ae 100644 --- a/src/test/debuginfo/vec-slices.rs +++ b/src/test/debuginfo/vec-slices.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // ignore-windows // ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 // min-lldb-version: 310 diff --git a/src/test/mir-opt/early_otherwise_branch_68867.rs b/src/test/mir-opt/early_otherwise_branch_68867.rs index e11337643da..02221c4cf4a 100644 --- a/src/test/mir-opt/early_otherwise_branch_68867.rs +++ b/src/test/mir-opt/early_otherwise_branch_68867.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts // example from #68867 diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-final.after.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-final.after.diff index 59bf5a185e0..2893ee9ac33 100644 --- a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-final.after.diff +++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-final.after.diff @@ -2,299 +2,299 @@ + // MIR for `try_sum` after SimplifyBranches-final fn try_sum(_1: &ViewportPercentageLength, _2: &ViewportPercentageLength) -> Result { - debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:18:5: 18:6 - debug other => _2; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:19:5: 19:10 - let mut _0: std::result::Result; // return place in scope 0 at $DIR/early_otherwise_branch_68867.rs:20:6: 20:42 - let mut _3: ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 - let mut _4: (&ViewportPercentageLength, &ViewportPercentageLength); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 - let mut _5: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 - let mut _6: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 - let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 - let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:21: 24:30 - let mut _9: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:23: 25:34 - let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:23: 26:34 - let mut _11: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 - let _12: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 - let _13: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 - let mut _14: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 - let mut _15: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 - let mut _16: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 - let _17: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:14: 24:17 - let _18: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:24: 24:29 - let mut _19: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:49 - let mut _20: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:41 - let mut _21: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:49 - let _22: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 - let _23: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 - let mut _24: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 - let mut _25: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 - let mut _26: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 - let _27: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:16: 26:19 - let _28: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:28: 26:33 - let mut _29: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:55 - let mut _30: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:47 - let mut _31: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:50: 26:55 - let mut _32: !; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:27:14: 27:28 - let mut _33: (); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:27:25: 27:27 -+ let mut _34: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 -+ let mut _35: bool; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 + debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:17:5: 17:6 + debug other => _2; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:18:5: 18:10 + let mut _0: std::result::Result; // return place in scope 0 at $DIR/early_otherwise_branch_68867.rs:19:6: 19:42 + let mut _3: ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 + let mut _4: (&ViewportPercentageLength, &ViewportPercentageLength); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _5: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:15: 21:16 + let mut _6: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:18: 21:23 + let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 + let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 + let mut _9: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:23: 24:34 + let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:23: 25:34 + let mut _11: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 + let _12: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + let _13: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + let mut _14: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 + let mut _15: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 + let mut _16: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:44: 22:49 + let _17: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + let _18: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + let mut _19: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 + let mut _20: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 + let mut _21: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 + let _22: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + let _23: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + let mut _24: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 + let mut _25: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 + let mut _26: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:50: 24:55 + let _27: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + let _28: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + let mut _29: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 + let mut _30: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 + let mut _31: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 + let mut _32: !; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:14: 26:28 + let mut _33: (); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 ++ let mut _34: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 ++ let mut _35: bool; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 scope 1 { -- debug one => _12; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 -- debug other => _13; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 -+ debug one => _15; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 -+ debug other => _16; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 +- debug one => _12; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 +- debug other => _13; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 ++ debug one => _15; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 ++ debug other => _16; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 } scope 2 { -- debug one => _17; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:24:14: 24:17 -- debug other => _18; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:24:24: 24:29 -+ debug one => _20; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:24:14: 24:17 -+ debug other => _21; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:24:24: 24:29 +- debug one => _17; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 +- debug other => _18; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 ++ debug one => _20; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 ++ debug other => _21; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 } scope 3 { -- debug one => _22; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 -- debug other => _23; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 -+ debug one => _25; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 -+ debug other => _26; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 +- debug one => _22; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 +- debug other => _23; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 ++ debug one => _25; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 ++ debug other => _26; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 } scope 4 { -- debug one => _27; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:26:16: 26:19 -- debug other => _28; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:26:28: 26:33 -+ debug one => _30; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:26:16: 26:19 -+ debug other => _31; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:26:28: 26:33 +- debug one => _27; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 +- debug other => _28; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 ++ debug one => _30; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 ++ debug other => _31; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 } bb0: { -- StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 -- StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 -- StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 -- _5 = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 -+ (_4.0: &ViewportPercentageLength) = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 - StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 - _6 = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 -- (_4.0: &ViewportPercentageLength) = move _5; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 - (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 - StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 -- StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 - _11 = discriminant((*(_4.0: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -- switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -+ StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -+ _34 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -+ StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -+ _35 = Ne(_34, _11); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -+ StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -+ switchInt(move _35) -> [false: bb7, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 +- StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 +- StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 +- StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:15: 21:16 +- _5 = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:15: 21:16 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:15: 21:16 ++ (_4.0: &ViewportPercentageLength) = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:15: 21:16 + StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:18: 21:23 + _6 = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:18: 21:23 +- (_4.0: &ViewportPercentageLength) = move _5; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 +- StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 + _11 = discriminant((*(_4.0: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 +- switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 ++ StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 ++ _34 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 ++ StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 ++ _35 = Ne(_34, _11); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 ++ StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 ++ switchInt(move _35) -> [false: bb7, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 } bb1: { -- _7 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 -- switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 +- _7 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 +- switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 - } - - bb2: { -+ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:25: 27:27 - StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:25: 27:27 -- nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:21: 27:28 - discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:21: 27:28 - StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:27: 27:28 -- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7 -- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2 - return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2 ++ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 + StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 +- nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:21: 26:28 + discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:21: 26:28 + StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:27: 26:28 +- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:6: 27:7 +- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:1: 28:2 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:6: 27:7 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:1: 28:2 + return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:2: 28:2 } + bb2: { -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 -+ _15 = (((*(_4.0: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 -+ _16 = (((*(_4.1: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 -+ ((((_0 as Ok).0: ViewportPercentageLength) as Vw).0: f32) = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 -+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 ++ _15 = (((*(_4.0: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 ++ _16 = (((*(_4.1: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:44: 22:49 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:44: 22:49 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vw).0: f32) = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:48: 22:49 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:48: 22:49 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:35: 22:50 ++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:35: 22:50 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 ++ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 + } + bb3: { -- _8 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:21: 24:30 -- switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:21: 24:30 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:14: 24:17 -+ _20 = (((*(_4.0: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:14: 24:17 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:24: 24:29 -+ _21 = (((*(_4.1: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:24: 24:29 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:49 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:41 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:41 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:49 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:49 -+ ((((_0 as Ok).0: ViewportPercentageLength) as Vh).0: f32) = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:49 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:48: 24:49 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:48: 24:49 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:35: 24:50 -+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:35: 24:50 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 +- _8 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 +- switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 ++ _20 = (((*(_4.0: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 ++ _21 = (((*(_4.1: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vh).0: f32) = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 ++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 ++ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 } bb4: { -- _9 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:23: 25:34 -- switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:23: 25:34 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 -+ _25 = (((*(_4.0: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 -+ _26 = (((*(_4.1: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 -+ ((((_0 as Ok).0: ViewportPercentageLength) as Vmin).0: f32) = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 -+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 +- _9 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:23: 24:34 +- switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:23: 24:34 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 ++ _25 = (((*(_4.0: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 ++ _26 = (((*(_4.1: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:50: 24:55 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:50: 24:55 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vmin).0: f32) = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:54: 24:55 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:54: 24:55 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:39: 24:56 ++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:39: 24:56 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 ++ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 } bb5: { -- _10 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:23: 26:34 -- switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:23: 26:34 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:16: 26:19 -+ _30 = (((*(_4.0: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:16: 26:19 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:28: 26:33 -+ _31 = (((*(_4.1: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:28: 26:33 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:55 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:47 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:47 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:50: 26:55 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:50: 26:55 -+ ((((_0 as Ok).0: ViewportPercentageLength) as Vmax).0: f32) = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:55 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:54: 26:55 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:54: 26:55 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:39: 26:56 -+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:39: 26:56 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 +- _10 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:23: 25:34 +- switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:23: 25:34 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 ++ _30 = (((*(_4.0: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 ++ _31 = (((*(_4.1: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vmax).0: f32) = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 ++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 ++ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 } bb6: { -- StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 -- _12 = (((*(_4.0: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 -- StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 -- _13 = (((*(_4.1: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 -- StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 -- StorageLive(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 -- _15 = _12; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 -- StorageLive(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 -- _16 = _13; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 -- _14 = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 -- StorageDead(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 -- StorageDead(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 -- ((_3 as Vw).0: f32) = move _14; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 -- discriminant(_3) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 -- StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -- StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -- StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7 -+ discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2 -+ return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2 +- StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 +- _12 = (((*(_4.0: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 +- StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 +- _13 = (((*(_4.1: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 +- StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 +- StorageLive(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 +- _15 = _12; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 +- StorageLive(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:44: 22:49 +- _16 = _13; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:44: 22:49 +- _14 = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 +- StorageDead(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:48: 22:49 +- StorageDead(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:48: 22:49 +- ((_3 as Vw).0: f32) = move _14; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:35: 22:50 +- discriminant(_3) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:35: 22:50 +- StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 +- StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 +- StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 +- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:5: 27:7 ++ discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:5: 27:7 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:6: 27:7 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:1: 28:2 ++ return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:2: 28:2 } bb7: { -- StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:14: 24:17 -- _17 = (((*(_4.0: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:14: 24:17 -- StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:24: 24:29 -- _18 = (((*(_4.1: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:24: 24:29 -- StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:49 -- StorageLive(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:41 -- _20 = _17; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:41 -- StorageLive(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:49 -- _21 = _18; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:49 -- _19 = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:49 -- StorageDead(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:48: 24:49 -- StorageDead(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:48: 24:49 -- ((_3 as Vh).0: f32) = move _19; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:35: 24:50 -- discriminant(_3) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:35: 24:50 -- StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50 -- StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50 -- StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 +- StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 +- _17 = (((*(_4.0: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 +- StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 +- _18 = (((*(_4.1: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 +- StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 +- StorageLive(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 +- _20 = _17; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 +- StorageLive(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 +- _21 = _18; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 +- _19 = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 +- StorageDead(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 +- StorageDead(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 +- ((_3 as Vh).0: f32) = move _19; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 +- discriminant(_3) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 +- StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 +- StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 +- StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 +- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 - } - - bb8: { -- StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 -- _22 = (((*(_4.0: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 -- StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 -- _23 = (((*(_4.1: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 -- StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 -- StorageLive(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 -- _25 = _22; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 -- StorageLive(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 -- _26 = _23; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 -- _24 = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 -- StorageDead(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 -- StorageDead(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 -- ((_3 as Vmin).0: f32) = move _24; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 -- discriminant(_3) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 -- StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -- StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -- StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 +- StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 +- _22 = (((*(_4.0: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 +- StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 +- _23 = (((*(_4.1: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 +- StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 +- StorageLive(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 +- _25 = _22; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 +- StorageLive(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:50: 24:55 +- _26 = _23; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:50: 24:55 +- _24 = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 +- StorageDead(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:54: 24:55 +- StorageDead(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:54: 24:55 +- ((_3 as Vmin).0: f32) = move _24; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:39: 24:56 +- discriminant(_3) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:39: 24:56 +- StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 +- StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 +- StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 +- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 - } - - bb9: { -- StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:16: 26:19 -- _27 = (((*(_4.0: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:16: 26:19 -- StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:28: 26:33 -- _28 = (((*(_4.1: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:28: 26:33 -- StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:55 -- StorageLive(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:47 -- _30 = _27; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:47 -- StorageLive(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:50: 26:55 -- _31 = _28; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:50: 26:55 -- _29 = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:55 -- StorageDead(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:54: 26:55 -- StorageDead(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:54: 26:55 -- ((_3 as Vmax).0: f32) = move _29; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:39: 26:56 -- discriminant(_3) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:39: 26:56 -- StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56 -- StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56 -- StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 +- StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 +- _27 = (((*(_4.0: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 +- StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 +- _28 = (((*(_4.1: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 +- StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 +- StorageLive(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 +- _30 = _27; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 +- StorageLive(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 +- _31 = _28; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 +- _29 = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 +- StorageDead(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 +- StorageDead(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 +- ((_3 as Vmax).0: f32) = move _29; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 +- discriminant(_3) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 +- StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 +- StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 +- StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 +- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 - } - - bb10: { -- ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7 -- discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7 -- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7 -- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2 -- return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2 -+ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 -+ switchInt(_11) -> [0_isize: bb2, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 +- ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:5: 27:7 +- discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:5: 27:7 +- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:6: 27:7 +- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:1: 28:2 +- return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:2: 28:2 ++ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 ++ switchInt(_11) -> [0_isize: bb2, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 } } diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff index 2d320786ea9..9039989e0f2 100644 --- a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff @@ -2,215 +2,215 @@ + // MIR for `try_sum` after EarlyOtherwiseBranch fn try_sum(_1: &ViewportPercentageLength, _2: &ViewportPercentageLength) -> Result { - debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:18:5: 18:6 - debug other => _2; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:19:5: 19:10 - let mut _0: std::result::Result; // return place in scope 0 at $DIR/early_otherwise_branch_68867.rs:20:6: 20:42 - let mut _3: ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 - let mut _4: (&ViewportPercentageLength, &ViewportPercentageLength); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 - let mut _5: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 - let mut _6: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 - let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 - let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:21: 24:30 - let mut _9: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:23: 25:34 - let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:23: 26:34 - let mut _11: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 - let _12: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 - let _13: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 - let mut _14: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 - let mut _15: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 - let mut _16: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 - let _17: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:14: 24:17 - let _18: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:24: 24:29 - let mut _19: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:49 - let mut _20: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:41 - let mut _21: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:49 - let _22: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 - let _23: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 - let mut _24: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 - let mut _25: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 - let mut _26: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 - let _27: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:16: 26:19 - let _28: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:28: 26:33 - let mut _29: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:55 - let mut _30: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:47 - let mut _31: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:50: 26:55 - let mut _32: !; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:27:14: 27:28 - let mut _33: (); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:27:25: 27:27 -+ let mut _34: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 -+ let mut _35: bool; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 + debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:17:5: 17:6 + debug other => _2; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:18:5: 18:10 + let mut _0: std::result::Result; // return place in scope 0 at $DIR/early_otherwise_branch_68867.rs:19:6: 19:42 + let mut _3: ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 + let mut _4: (&ViewportPercentageLength, &ViewportPercentageLength); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _5: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:15: 21:16 + let mut _6: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:18: 21:23 + let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 + let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 + let mut _9: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:23: 24:34 + let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:23: 25:34 + let mut _11: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 + let _12: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + let _13: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + let mut _14: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 + let mut _15: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 + let mut _16: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:44: 22:49 + let _17: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + let _18: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + let mut _19: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 + let mut _20: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 + let mut _21: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 + let _22: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + let _23: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + let mut _24: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 + let mut _25: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 + let mut _26: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:24:50: 24:55 + let _27: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + let _28: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + let mut _29: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 + let mut _30: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 + let mut _31: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 + let mut _32: !; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:14: 26:28 + let mut _33: (); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 ++ let mut _34: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 ++ let mut _35: bool; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 scope 1 { - debug one => _12; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 - debug other => _13; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + debug one => _12; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + debug other => _13; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 } scope 2 { - debug one => _17; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:24:14: 24:17 - debug other => _18; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:24:24: 24:29 + debug one => _17; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + debug other => _18; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 } scope 3 { - debug one => _22; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 - debug other => _23; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + debug one => _22; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + debug other => _23; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 } scope 4 { - debug one => _27; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:26:16: 26:19 - debug other => _28; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:26:28: 26:33 + debug one => _27; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + debug other => _28; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 } bb0: { - StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 - StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 - StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 - _5 = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 - StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 - _6 = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 - (_4.0: &ViewportPercentageLength) = move _5; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 - (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 - StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 - StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 - _11 = discriminant((*(_4.0: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -- switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -+ StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -+ _34 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -+ StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -+ _35 = Ne(_34, _11); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -+ StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 -+ switchInt(move _35) -> [false: bb7, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 + StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 + StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:15: 21:16 + _5 = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:15: 21:16 + StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:18: 21:23 + _6 = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:18: 21:23 + (_4.0: &ViewportPercentageLength) = move _5; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 + StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 + _11 = discriminant((*(_4.0: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 +- switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 ++ StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 ++ _34 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 ++ StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 ++ _35 = Ne(_34, _11); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 ++ StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 ++ switchInt(move _35) -> [false: bb7, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:11: 22:18 } bb1: { -- _7 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 -- switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 +- _7 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 +- switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 - } - - bb2: { -+ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:25: 27:27 - StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:25: 27:27 -- nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:21: 27:28 - discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:21: 27:28 - StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:27: 27:28 - StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7 - StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2 - return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2 ++ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 + StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 +- nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:21: 26:28 + discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:21: 26:28 + StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:27: 26:28 + StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:6: 27:7 + StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:1: 28:2 + return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:2: 28:2 } - bb3: { -- _8 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:21: 24:30 -- switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:21: 24:30 +- _8 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 +- switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 - } - - bb4: { -- _9 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:23: 25:34 -- switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:23: 25:34 +- _9 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:23: 24:34 +- switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:23: 24:34 - } - - bb5: { -- _10 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:23: 26:34 -- switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:23: 26:34 +- _10 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:23: 25:34 +- switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:23: 25:34 - } - - bb6: { + bb2: { - StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 - _12 = (((*(_4.0: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 - StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 - _13 = (((*(_4.1: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 - StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 - StorageLive(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 - _15 = _12; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 - StorageLive(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 - _16 = _13; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 - _14 = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 - StorageDead(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 - StorageDead(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 - ((_3 as Vw).0: f32) = move _14; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 - discriminant(_3) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 - StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 - StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 - StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 + StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + _12 = (((*(_4.0: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + _13 = (((*(_4.1: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 + StorageLive(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 + _15 = _12; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 + StorageLive(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:44: 22:49 + _16 = _13; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:44: 22:49 + _14 = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 + StorageDead(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:48: 22:49 + StorageDead(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:48: 22:49 + ((_3 as Vw).0: f32) = move _14; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:35: 22:50 + discriminant(_3) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:35: 22:50 + StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 + StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 + StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 +- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 ++ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 } - bb7: { + bb3: { - StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:14: 24:17 - _17 = (((*(_4.0: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:14: 24:17 - StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:24: 24:29 - _18 = (((*(_4.1: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:24: 24:29 - StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:49 - StorageLive(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:41 - _20 = _17; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:41 - StorageLive(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:49 - _21 = _18; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:49 - _19 = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:49 - StorageDead(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:48: 24:49 - StorageDead(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:48: 24:49 - ((_3 as Vh).0: f32) = move _19; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:35: 24:50 - discriminant(_3) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:35: 24:50 - StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50 - StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50 - StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 + StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + _17 = (((*(_4.0: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + _18 = (((*(_4.1: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 + StorageLive(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 + _20 = _17; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 + StorageLive(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 + _21 = _18; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 + _19 = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 + StorageDead(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 + StorageDead(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 + ((_3 as Vh).0: f32) = move _19; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 + discriminant(_3) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 + StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 + StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 + StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 +- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 ++ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 } - bb8: { + bb4: { - StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 - _22 = (((*(_4.0: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 - StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 - _23 = (((*(_4.1: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 - StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 - StorageLive(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 - _25 = _22; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 - StorageLive(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 - _26 = _23; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 - _24 = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 - StorageDead(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 - StorageDead(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 - ((_3 as Vmin).0: f32) = move _24; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 - discriminant(_3) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 - StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 - StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 - StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 + StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + _22 = (((*(_4.0: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + _23 = (((*(_4.1: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 + StorageLive(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 + _25 = _22; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 + StorageLive(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:50: 24:55 + _26 = _23; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:50: 24:55 + _24 = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 + StorageDead(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:54: 24:55 + StorageDead(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:54: 24:55 + ((_3 as Vmin).0: f32) = move _24; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:39: 24:56 + discriminant(_3) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:39: 24:56 + StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 + StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 + StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 +- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 ++ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 } - bb9: { + bb5: { - StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:16: 26:19 - _27 = (((*(_4.0: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:16: 26:19 - StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:28: 26:33 - _28 = (((*(_4.1: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:28: 26:33 - StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:55 - StorageLive(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:47 - _30 = _27; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:47 - StorageLive(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:50: 26:55 - _31 = _28; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:50: 26:55 - _29 = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:55 - StorageDead(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:54: 26:55 - StorageDead(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:54: 26:55 - ((_3 as Vmax).0: f32) = move _29; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:39: 26:56 - discriminant(_3) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:39: 26:56 - StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56 - StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56 - StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 + StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + _27 = (((*(_4.0: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + _28 = (((*(_4.1: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 + StorageLive(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 + _30 = _27; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 + StorageLive(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 + _31 = _28; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 + _29 = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 + StorageDead(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 + StorageDead(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 + ((_3 as Vmax).0: f32) = move _29; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 + discriminant(_3) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 + StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 + StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 + StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 +- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 ++ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 27:6 } - bb10: { + bb6: { - ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7 - discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7 - StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7 - StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2 - return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2 + ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:5: 27:7 + discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:5: 27:7 + StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:6: 27:7 + StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:1: 28:2 + return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:2: 28:2 + } + + bb7: { -+ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 -+ switchInt(_11) -> [0_isize: bb2, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 ++ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 ++ switchInt(_11) -> [0_isize: bb2, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:21: 22:30 } } diff --git a/src/test/rustdoc-ui/commandline-argfile-missing.rs b/src/test/rustdoc-ui/commandline-argfile-missing.rs index 020c3ff3c7e..5a6465bd064 100644 --- a/src/test/rustdoc-ui/commandline-argfile-missing.rs +++ b/src/test/rustdoc-ui/commandline-argfile-missing.rs @@ -1,6 +1,5 @@ // Check to see if we can get parameters from an @argsfile file // -// ignore-tidy-linelength // normalize-stderr-test: "os error \d+" -> "os error $$ERR" // normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " // compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args diff --git a/src/test/rustdoc-ui/doc-spotlight.fixed b/src/test/rustdoc-ui/doc-spotlight.fixed index 6c90aace689..94b69a99879 100644 --- a/src/test/rustdoc-ui/doc-spotlight.fixed +++ b/src/test/rustdoc-ui/doc-spotlight.fixed @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // check-pass // run-rustfix diff --git a/src/test/rustdoc-ui/doc-spotlight.rs b/src/test/rustdoc-ui/doc-spotlight.rs index 7cea553c4b0..cc5f159a809 100644 --- a/src/test/rustdoc-ui/doc-spotlight.rs +++ b/src/test/rustdoc-ui/doc-spotlight.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // check-pass // run-rustfix diff --git a/src/test/rustdoc-ui/doc-spotlight.stderr b/src/test/rustdoc-ui/doc-spotlight.stderr index e79cdc3d77a..e5fa6293f3d 100644 --- a/src/test/rustdoc-ui/doc-spotlight.stderr +++ b/src/test/rustdoc-ui/doc-spotlight.stderr @@ -1,5 +1,5 @@ warning: unknown `doc` attribute `spotlight` - --> $DIR/doc-spotlight.rs:7:7 + --> $DIR/doc-spotlight.rs:6:7 | LL | #[doc(spotlight)] | ^^^^^^^^^ help: use `notable_trait` instead diff --git a/src/test/rustdoc/assoc-item-cast.rs b/src/test/rustdoc/assoc-item-cast.rs index dc62fac6a95..273fc62aa17 100644 --- a/src/test/rustdoc/assoc-item-cast.rs +++ b/src/test/rustdoc/assoc-item-cast.rs @@ -1,6 +1,5 @@ #![crate_name = "foo"] -// ignore-tidy-linelength pub trait Expression { type SqlType; diff --git a/src/test/rustdoc/assoc-types.rs b/src/test/rustdoc/assoc-types.rs index 5f0fdbb322c..82fa7cf9e60 100644 --- a/src/test/rustdoc/assoc-types.rs +++ b/src/test/rustdoc/assoc-types.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![crate_type="lib"] // @has assoc_types/trait.Index.html diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs index aa4ad261c80..4b66b5271c5 100644 --- a/src/test/rustdoc/async-fn.rs +++ b/src/test/rustdoc/async-fn.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // edition:2018 // @has async_fn/fn.foo.html '//pre[@class="rust fn"]' 'pub async fn foo() -> Option' pub async fn foo() -> Option { diff --git a/src/test/rustdoc/const-display.rs b/src/test/rustdoc/const-display.rs index 11ba68a388f..fb5c8517f6c 100644 --- a/src/test/rustdoc/const-display.rs +++ b/src/test/rustdoc/const-display.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![crate_name = "foo"] #![unstable(feature = "humans", diff --git a/src/test/rustdoc/const-generics/add-impl.rs b/src/test/rustdoc/const-generics/add-impl.rs index 85be89719ec..db4be82e6bf 100644 --- a/src/test/rustdoc/const-generics/add-impl.rs +++ b/src/test/rustdoc/const-generics/add-impl.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![feature(const_generics)] #![crate_name = "foo"] diff --git a/src/test/rustdoc/const-generics/const-impl.rs b/src/test/rustdoc/const-generics/const-impl.rs index 03f5bb2ca43..04fb3395333 100644 --- a/src/test/rustdoc/const-generics/const-impl.rs +++ b/src/test/rustdoc/const-generics/const-impl.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![feature(const_generics)] #![crate_name = "foo"] diff --git a/src/test/rustdoc/const-generics/type-alias.rs b/src/test/rustdoc/const-generics/type-alias.rs index 85160dc07a7..ebda5b19404 100644 --- a/src/test/rustdoc/const-generics/type-alias.rs +++ b/src/test/rustdoc/const-generics/type-alias.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![crate_name = "foo"] // @has foo/type.CellIndex.html '//pre[@class="rust typedef"]' 'type CellIndex = [i64; D];' diff --git a/src/test/rustdoc/deref-recursive-pathbuf.rs b/src/test/rustdoc/deref-recursive-pathbuf.rs index 759e881aab4..459a30060c6 100644 --- a/src/test/rustdoc/deref-recursive-pathbuf.rs +++ b/src/test/rustdoc/deref-recursive-pathbuf.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // #26207: Show all methods reachable via Deref impls, recursing through multiple dereferencing // levels and across multiple crates. diff --git a/src/test/rustdoc/deref-recursive.rs b/src/test/rustdoc/deref-recursive.rs index 5aef87c38cd..b96b5397ad7 100644 --- a/src/test/rustdoc/deref-recursive.rs +++ b/src/test/rustdoc/deref-recursive.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // #26207: Show all methods reachable via Deref impls, recursing through multiple dereferencing // levels if needed. diff --git a/src/test/rustdoc/deref-typedef.rs b/src/test/rustdoc/deref-typedef.rs index 589f133b975..47009559e6f 100644 --- a/src/test/rustdoc/deref-typedef.rs +++ b/src/test/rustdoc/deref-typedef.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![crate_name = "foo"] // @has 'foo/struct.Bar.html' diff --git a/src/test/rustdoc/double-quote-escape.rs b/src/test/rustdoc/double-quote-escape.rs index 243d8ad7965..546af2c121a 100644 --- a/src/test/rustdoc/double-quote-escape.rs +++ b/src/test/rustdoc/double-quote-escape.rs @@ -1,6 +1,5 @@ #![crate_name = "foo"] -// ignore-tidy-linelength pub trait Foo { fn foo() {} diff --git a/src/test/rustdoc/duplicate-cfg.rs b/src/test/rustdoc/duplicate-cfg.rs index 7b938af3c7d..cec504ea151 100644 --- a/src/test/rustdoc/duplicate-cfg.rs +++ b/src/test/rustdoc/duplicate-cfg.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![crate_name = "foo"] #![feature(doc_cfg)] diff --git a/src/test/rustdoc/fn-type.rs b/src/test/rustdoc/fn-type.rs index f5e123aed9c..3959aeb6cfb 100644 --- a/src/test/rustdoc/fn-type.rs +++ b/src/test/rustdoc/fn-type.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![crate_name = "foo"] #![crate_type = "lib"] diff --git a/src/test/rustdoc/for-lifetime.rs b/src/test/rustdoc/for-lifetime.rs index 299794b63b2..34a7eae31c7 100644 --- a/src/test/rustdoc/for-lifetime.rs +++ b/src/test/rustdoc/for-lifetime.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![crate_name = "foo"] #![crate_type = "lib"] diff --git a/src/test/rustdoc/inline_cross/impl_trait.rs b/src/test/rustdoc/inline_cross/impl_trait.rs index 44e2c4d3fb2..a2adc0e63c9 100644 --- a/src/test/rustdoc/inline_cross/impl_trait.rs +++ b/src/test/rustdoc/inline_cross/impl_trait.rs @@ -1,6 +1,5 @@ // aux-build:impl_trait_aux.rs // edition:2018 -// ignore-tidy-linelength extern crate impl_trait_aux; diff --git a/src/test/rustdoc/intra-doc/associated-defaults.rs b/src/test/rustdoc/intra-doc/associated-defaults.rs index f99d9b5baea..28dc7073a3e 100644 --- a/src/test/rustdoc/intra-doc/associated-defaults.rs +++ b/src/test/rustdoc/intra-doc/associated-defaults.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![deny(intra_doc_link_resolution_failure)] #![feature(associated_type_defaults)] diff --git a/src/test/rustdoc/intra-doc/associated-items.rs b/src/test/rustdoc/intra-doc/associated-items.rs index 09dfbfcf68a..43a43a79738 100644 --- a/src/test/rustdoc/intra-doc/associated-items.rs +++ b/src/test/rustdoc/intra-doc/associated-items.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![deny(intra_doc_link_resolution_failure)] /// [`std::collections::BTreeMap::into_iter`] diff --git a/src/test/rustdoc/intra-doc/cross-crate/macro.rs b/src/test/rustdoc/intra-doc/cross-crate/macro.rs index 311b16dff13..62659ce689a 100644 --- a/src/test/rustdoc/intra-doc/cross-crate/macro.rs +++ b/src/test/rustdoc/intra-doc/cross-crate/macro.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // aux-build:macro_inner.rs // aux-build:proc_macro.rs // build-aux-docs diff --git a/src/test/rustdoc/intra-doc/cross-crate/traits.rs b/src/test/rustdoc/intra-doc/cross-crate/traits.rs index 07decb48019..68f5cb3a092 100644 --- a/src/test/rustdoc/intra-doc/cross-crate/traits.rs +++ b/src/test/rustdoc/intra-doc/cross-crate/traits.rs @@ -1,6 +1,5 @@ // aux-build:traits.rs // build-aux-docs -// ignore-tidy-line-length #![deny(broken_intra_doc_links)] extern crate inner; diff --git a/src/test/rustdoc/intra-doc/disambiguators-removed.rs b/src/test/rustdoc/intra-doc/disambiguators-removed.rs index aa0ced62aaf..12c3cee29c3 100644 --- a/src/test/rustdoc/intra-doc/disambiguators-removed.rs +++ b/src/test/rustdoc/intra-doc/disambiguators-removed.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![deny(intra_doc_link_resolution_failure)] // first try backticks /// Trait: [`trait@Name`], fn: [`fn@Name`], [`Name`][`macro@Name`] diff --git a/src/test/rustdoc/intra-doc/non-path-primitives.rs b/src/test/rustdoc/intra-doc/non-path-primitives.rs index ffa02b0c635..ee71537d155 100644 --- a/src/test/rustdoc/intra-doc/non-path-primitives.rs +++ b/src/test/rustdoc/intra-doc/non-path-primitives.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![crate_name = "foo"] #![feature(intra_doc_pointers)] #![deny(rustdoc::broken_intra_doc_links)] diff --git a/src/test/rustdoc/intra-doc/prim-assoc.rs b/src/test/rustdoc/intra-doc/prim-assoc.rs index d687cbd69bb..4099ececfaf 100644 --- a/src/test/rustdoc/intra-doc/prim-assoc.rs +++ b/src/test/rustdoc/intra-doc/prim-assoc.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![deny(broken_intra_doc_links)] //! [i32::MAX] diff --git a/src/test/rustdoc/intra-doc/prim-methods-external-core.rs b/src/test/rustdoc/intra-doc/prim-methods-external-core.rs index 434e0338983..695a7fbfb53 100644 --- a/src/test/rustdoc/intra-doc/prim-methods-external-core.rs +++ b/src/test/rustdoc/intra-doc/prim-methods-external-core.rs @@ -2,7 +2,6 @@ // build-aux-docs // ignore-cross-compile // ignore-windows -// ignore-tidy-linelength #![deny(broken_intra_doc_links)] #![feature(no_core, lang_items)] diff --git a/src/test/rustdoc/intra-doc/prim-methods-local.rs b/src/test/rustdoc/intra-doc/prim-methods-local.rs index 9888f29db5b..f0b939a468c 100644 --- a/src/test/rustdoc/intra-doc/prim-methods-local.rs +++ b/src/test/rustdoc/intra-doc/prim-methods-local.rs @@ -3,7 +3,6 @@ #![no_core] #![crate_type = "rlib"] -// ignore-tidy-linelength // @has prim_methods_local/index.html // @has - '//*[@id="main"]//a[@href="https://doc.rust-lang.org/nightly/std/primitive.char.html"]' 'char' diff --git a/src/test/rustdoc/intra-doc/prim-methods.rs b/src/test/rustdoc/intra-doc/prim-methods.rs index f19cff7d34a..6de15e76d15 100644 --- a/src/test/rustdoc/intra-doc/prim-methods.rs +++ b/src/test/rustdoc/intra-doc/prim-methods.rs @@ -1,6 +1,5 @@ #![deny(broken_intra_doc_links)] -// ignore-tidy-linelength // @has prim_methods/index.html // @has - '//*[@id="main"]//a[@href="https://doc.rust-lang.org/nightly/std/primitive.char.html"]' 'char' diff --git a/src/test/rustdoc/intra-doc/prim-precedence.rs b/src/test/rustdoc/intra-doc/prim-precedence.rs index ed2c2cda718..ab6e3da17f4 100644 --- a/src/test/rustdoc/intra-doc/prim-precedence.rs +++ b/src/test/rustdoc/intra-doc/prim-precedence.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![deny(broken_intra_doc_links)] pub mod char { diff --git a/src/test/rustdoc/intra-doc/primitive-non-default-impl.rs b/src/test/rustdoc/intra-doc/primitive-non-default-impl.rs index 548eb090a32..cf83ead4db7 100644 --- a/src/test/rustdoc/intra-doc/primitive-non-default-impl.rs +++ b/src/test/rustdoc/intra-doc/primitive-non-default-impl.rs @@ -1,6 +1,5 @@ #![deny(broken_intra_doc_links)] -// ignore-tidy-linelength // @has primitive_non_default_impl/fn.str_methods.html /// [`str::trim`] diff --git a/src/test/rustdoc/intra-doc/self.rs b/src/test/rustdoc/intra-doc/self.rs index 81545fec741..b2b75127b31 100644 --- a/src/test/rustdoc/intra-doc/self.rs +++ b/src/test/rustdoc/intra-doc/self.rs @@ -1,6 +1,5 @@ #![crate_name = "foo"] -// ignore-tidy-linelength // @has foo/index.html '//a/@href' '../foo/struct.Foo.html#method.new' // @has foo/struct.Foo.html '//a/@href' '../foo/struct.Foo.html#method.new' diff --git a/src/test/rustdoc/intra-doc/trait-impl.rs b/src/test/rustdoc/intra-doc/trait-impl.rs index fab8406d525..ef1987a829a 100644 --- a/src/test/rustdoc/intra-doc/trait-impl.rs +++ b/src/test/rustdoc/intra-doc/trait-impl.rs @@ -1,6 +1,5 @@ #![crate_name = "foo"] -// ignore-tidy-linelength pub struct MyStruct; diff --git a/src/test/rustdoc/intra-doc/trait-item.rs b/src/test/rustdoc/intra-doc/trait-item.rs index de8585f4c9a..affd2aaec2d 100644 --- a/src/test/rustdoc/intra-doc/trait-item.rs +++ b/src/test/rustdoc/intra-doc/trait-item.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![deny(broken_intra_doc_links)] /// Link to [S::assoc_fn()] diff --git a/src/test/rustdoc/intra-doc/true-false.rs b/src/test/rustdoc/intra-doc/true-false.rs index 7b21e934147..db637ece369 100644 --- a/src/test/rustdoc/intra-doc/true-false.rs +++ b/src/test/rustdoc/intra-doc/true-false.rs @@ -1,7 +1,6 @@ #![deny(broken_intra_doc_links)] #![crate_name = "foo"] -// ignore-tidy-linelength // @has foo/index.html // @has - '//*[@id="main"]//a[@href="https://doc.rust-lang.org/nightly/std/primitive.bool.html"]' 'true' diff --git a/src/test/rustdoc/issue-29503.rs b/src/test/rustdoc/issue-29503.rs index d7e0f37b286..19bab394dcf 100644 --- a/src/test/rustdoc/issue-29503.rs +++ b/src/test/rustdoc/issue-29503.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - use std::fmt; // @has issue_29503/trait.MyTrait.html diff --git a/src/test/rustdoc/issue-55364.rs b/src/test/rustdoc/issue-55364.rs index 200a29fc7ee..4aa553f7793 100644 --- a/src/test/rustdoc/issue-55364.rs +++ b/src/test/rustdoc/issue-55364.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // First a module with inner documentation // @has issue_55364/subone/index.html diff --git a/src/test/rustdoc/issue-75588.rs b/src/test/rustdoc/issue-75588.rs index 835ed02ac00..aebffeff5f0 100644 --- a/src/test/rustdoc/issue-75588.rs +++ b/src/test/rustdoc/issue-75588.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // aux-build:realcore.rs // aux-build:real_gimli.rs diff --git a/src/test/rustdoc/playground-arg.rs b/src/test/rustdoc/playground-arg.rs index dbe2297f818..69c89626539 100644 --- a/src/test/rustdoc/playground-arg.rs +++ b/src/test/rustdoc/playground-arg.rs @@ -1,5 +1,4 @@ // compile-flags: --playground-url=https://example.com/ -Z unstable-options -// ignore-tidy-linelength #![crate_name = "foo"] diff --git a/src/test/rustdoc/playground.rs b/src/test/rustdoc/playground.rs index 9971c7b4297..877ea1cfba1 100644 --- a/src/test/rustdoc/playground.rs +++ b/src/test/rustdoc/playground.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![crate_name = "foo"] #![doc(html_playground_url = "https://www.example.com/")] diff --git a/src/test/rustdoc/primitive-link.rs b/src/test/rustdoc/primitive-link.rs index 3041ff77684..dd455e45bfc 100644 --- a/src/test/rustdoc/primitive-link.rs +++ b/src/test/rustdoc/primitive-link.rs @@ -1,6 +1,5 @@ #![crate_name = "foo"] -// ignore-tidy-linelength // @has foo/struct.Foo.html '//*[@class="docblock"]/p/a[@href="https://doc.rust-lang.org/nightly/std/primitive.u32.html"]' 'u32' // @has foo/struct.Foo.html '//*[@class="docblock"]/p/a[@href="https://doc.rust-lang.org/nightly/std/primitive.i64.html"]' 'i64' diff --git a/src/test/rustdoc/raw-ident-eliminate-r-hashtag.rs b/src/test/rustdoc/raw-ident-eliminate-r-hashtag.rs index f895a4c2104..3ecf434c39e 100644 --- a/src/test/rustdoc/raw-ident-eliminate-r-hashtag.rs +++ b/src/test/rustdoc/raw-ident-eliminate-r-hashtag.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![crate_type="lib"] pub mod internal { diff --git a/src/test/rustdoc/smart-punct.rs b/src/test/rustdoc/smart-punct.rs index a1ca2699554..5319892c99c 100644 --- a/src/test/rustdoc/smart-punct.rs +++ b/src/test/rustdoc/smart-punct.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![crate_name = "foo"] //! This is the "start" of the 'document'! How'd you know that "it's" the start? diff --git a/src/test/rustdoc/src-links-external.rs b/src/test/rustdoc/src-links-external.rs index 0469e4ad624..8012e442213 100644 --- a/src/test/rustdoc/src-links-external.rs +++ b/src/test/rustdoc/src-links-external.rs @@ -1,7 +1,6 @@ // aux-build:src-links-external.rs // build-aux-docs // ignore-cross-compile -// ignore-tidy-linelength #![crate_name = "foo"] diff --git a/src/test/rustdoc/struct-field.rs b/src/test/rustdoc/struct-field.rs index 532e29bc691..974b863bb16 100644 --- a/src/test/rustdoc/struct-field.rs +++ b/src/test/rustdoc/struct-field.rs @@ -1,6 +1,5 @@ #![crate_name = "foo"] -// ignore-tidy-linelength // @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/struct.Foo.html#structfield.bar"]' 'Foo::bar' // @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/union.Bar.html#structfield.foo"]' 'Bar::foo' diff --git a/src/test/rustdoc/trait-attributes.rs b/src/test/rustdoc/trait-attributes.rs index a6ee046edec..2a103509ae1 100644 --- a/src/test/rustdoc/trait-attributes.rs +++ b/src/test/rustdoc/trait-attributes.rs @@ -1,6 +1,5 @@ #![crate_name = "foo"] -// ignore-tidy-linelength pub trait Foo { // @has foo/trait.Foo.html '//h3[@id="tymethod.foo"]//span[@class="docblock attributes"]' '#[must_use]' diff --git a/src/test/ui/associated-type-bounds/ambiguous-associated-type2.rs b/src/test/ui/associated-type-bounds/ambiguous-associated-type2.rs index 1b6d6d0ff59..48de593342f 100644 --- a/src/test/ui/associated-type-bounds/ambiguous-associated-type2.rs +++ b/src/test/ui/associated-type-bounds/ambiguous-associated-type2.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - trait Foo { type Item; } diff --git a/src/test/ui/associated-type-bounds/ambiguous-associated-type2.stderr b/src/test/ui/associated-type-bounds/ambiguous-associated-type2.stderr index bda1debeac0..e72ef0e4b33 100644 --- a/src/test/ui/associated-type-bounds/ambiguous-associated-type2.stderr +++ b/src/test/ui/associated-type-bounds/ambiguous-associated-type2.stderr @@ -1,12 +1,12 @@ error[E0391]: cycle detected when computing the super traits of `Baz` with associated type name `Item` - --> $DIR/ambiguous-associated-type2.rs:9:1 + --> $DIR/ambiguous-associated-type2.rs:7:1 | LL | trait Baz: Foo + Bar {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: ...which again requires computing the super traits of `Baz` with associated type name `Item`, completing the cycle note: cycle used when computing the super traits of `Baz` - --> $DIR/ambiguous-associated-type2.rs:9:1 + --> $DIR/ambiguous-associated-type2.rs:7:1 | LL | trait Baz: Foo + Bar {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/associated-type-bounds/duplicate.full_tait.stderr b/src/test/ui/associated-type-bounds/duplicate.full_tait.stderr index bde2d034e25..bd3cac1f887 100644 --- a/src/test/ui/associated-type-bounds/duplicate.full_tait.stderr +++ b/src/test/ui/associated-type-bounds/duplicate.full_tait.stderr @@ -1,5 +1,5 @@ warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/duplicate.rs:6:32 + --> $DIR/duplicate.rs:4:32 | LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] | ^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: see issue #63063 for more information warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/duplicate.rs:8:12 + --> $DIR/duplicate.rs:6:12 | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | #![feature(impl_trait_in_bindings)] = note: see issue #63065 for more information error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:13:36 + --> $DIR/duplicate.rs:11:36 | LL | struct SI1> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -24,7 +24,7 @@ LL | struct SI1> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:15:36 + --> $DIR/duplicate.rs:13:36 | LL | struct SI2> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -32,7 +32,7 @@ LL | struct SI2> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:17:39 + --> $DIR/duplicate.rs:15:39 | LL | struct SI3> { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -40,7 +40,7 @@ LL | struct SI3> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:19:45 + --> $DIR/duplicate.rs:17:45 | LL | struct SW1 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -48,7 +48,7 @@ LL | struct SW1 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:21:45 + --> $DIR/duplicate.rs:19:45 | LL | struct SW2 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -56,7 +56,7 @@ LL | struct SW2 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:23:48 + --> $DIR/duplicate.rs:21:48 | LL | struct SW3 where T: Iterator { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -64,7 +64,7 @@ LL | struct SW3 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:26:34 + --> $DIR/duplicate.rs:24:34 | LL | enum EI1> { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -72,7 +72,7 @@ LL | enum EI1> { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:28:34 + --> $DIR/duplicate.rs:26:34 | LL | enum EI2> { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -80,7 +80,7 @@ LL | enum EI2> { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:30:37 + --> $DIR/duplicate.rs:28:37 | LL | enum EI3> { V(T) } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -88,7 +88,7 @@ LL | enum EI3> { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:32:43 + --> $DIR/duplicate.rs:30:43 | LL | enum EW1 where T: Iterator { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -96,7 +96,7 @@ LL | enum EW1 where T: Iterator { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:34:43 + --> $DIR/duplicate.rs:32:43 | LL | enum EW2 where T: Iterator { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -104,7 +104,7 @@ LL | enum EW2 where T: Iterator { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:36:46 + --> $DIR/duplicate.rs:34:46 | LL | enum EW3 where T: Iterator { V(T) } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -112,7 +112,7 @@ LL | enum EW3 where T: Iterator { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:39:35 + --> $DIR/duplicate.rs:37:35 | LL | union UI1> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -120,7 +120,7 @@ LL | union UI1> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:41:35 + --> $DIR/duplicate.rs:39:35 | LL | union UI2> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -128,7 +128,7 @@ LL | union UI2> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:43:38 + --> $DIR/duplicate.rs:41:38 | LL | union UI3> { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -136,7 +136,7 @@ LL | union UI3> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:45:44 + --> $DIR/duplicate.rs:43:44 | LL | union UW1 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -144,7 +144,7 @@ LL | union UW1 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:47:44 + --> $DIR/duplicate.rs:45:44 | LL | union UW2 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -152,7 +152,7 @@ LL | union UW2 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:49:47 + --> $DIR/duplicate.rs:47:47 | LL | union UW3 where T: Iterator { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -160,7 +160,7 @@ LL | union UW3 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:52:32 + --> $DIR/duplicate.rs:50:32 | LL | fn FI1>() {} | ---------- ^^^^^^^^^^ re-bound here @@ -168,7 +168,7 @@ LL | fn FI1>() {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:54:32 + --> $DIR/duplicate.rs:52:32 | LL | fn FI2>() {} | ---------- ^^^^^^^^^^ re-bound here @@ -176,7 +176,7 @@ LL | fn FI2>() {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:56:35 + --> $DIR/duplicate.rs:54:35 | LL | fn FI3>() {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -184,7 +184,7 @@ LL | fn FI3>() {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:58:43 + --> $DIR/duplicate.rs:56:43 | LL | fn FW1() where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -192,7 +192,7 @@ LL | fn FW1() where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:60:43 + --> $DIR/duplicate.rs:58:43 | LL | fn FW2() where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -200,7 +200,7 @@ LL | fn FW2() where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:62:46 + --> $DIR/duplicate.rs:60:46 | LL | fn FW3() where T: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -208,7 +208,7 @@ LL | fn FW3() where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:68:40 + --> $DIR/duplicate.rs:66:40 | LL | fn FAPIT1(_: impl Iterator) {} | ---------- ^^^^^^^^^^ re-bound here @@ -216,7 +216,7 @@ LL | fn FAPIT1(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:70:40 + --> $DIR/duplicate.rs:68:40 | LL | fn FAPIT2(_: impl Iterator) {} | ---------- ^^^^^^^^^^ re-bound here @@ -224,7 +224,7 @@ LL | fn FAPIT2(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:72:43 + --> $DIR/duplicate.rs:70:43 | LL | fn FAPIT3(_: impl Iterator) {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -232,7 +232,7 @@ LL | fn FAPIT3(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:75:39 + --> $DIR/duplicate.rs:73:39 | LL | const CIT1: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -240,7 +240,7 @@ LL | const CIT1: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:77:39 + --> $DIR/duplicate.rs:75:39 | LL | const CIT2: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -248,7 +248,7 @@ LL | const CIT2: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:79:42 + --> $DIR/duplicate.rs:77:42 | LL | const CIT3: impl Iterator = iter::empty(); | ------------- ^^^^^^^^^^^^^ re-bound here @@ -256,7 +256,7 @@ LL | const CIT3: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:81:40 + --> $DIR/duplicate.rs:79:40 | LL | static SIT1: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -264,7 +264,7 @@ LL | static SIT1: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:83:40 + --> $DIR/duplicate.rs:81:40 | LL | static SIT2: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -272,7 +272,7 @@ LL | static SIT2: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:85:43 + --> $DIR/duplicate.rs:83:43 | LL | static SIT3: impl Iterator = iter::empty(); | ------------- ^^^^^^^^^^^^^ re-bound here @@ -280,7 +280,7 @@ LL | static SIT3: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:88:46 + --> $DIR/duplicate.rs:86:46 | LL | fn lit1() { let _: impl Iterator = iter::empty(); } | ---------- ^^^^^^^^^^ re-bound here @@ -288,7 +288,7 @@ LL | fn lit1() { let _: impl Iterator = iter::empty(); } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:90:46 + --> $DIR/duplicate.rs:88:46 | LL | fn lit2() { let _: impl Iterator = iter::empty(); } | ---------- ^^^^^^^^^^ re-bound here @@ -296,7 +296,7 @@ LL | fn lit2() { let _: impl Iterator = iter::empty(); } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:92:49 + --> $DIR/duplicate.rs:90:49 | LL | fn lit3() { let _: impl Iterator = iter::empty(); } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -304,7 +304,7 @@ LL | fn lit3() { let _: impl Iterator = iter::empt | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:95:35 + --> $DIR/duplicate.rs:93:35 | LL | type TAI1> = T; | ---------- ^^^^^^^^^^ re-bound here @@ -312,7 +312,7 @@ LL | type TAI1> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:97:35 + --> $DIR/duplicate.rs:95:35 | LL | type TAI2> = T; | ---------- ^^^^^^^^^^ re-bound here @@ -320,7 +320,7 @@ LL | type TAI2> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:99:38 + --> $DIR/duplicate.rs:97:38 | LL | type TAI3> = T; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -328,7 +328,7 @@ LL | type TAI3> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:101:44 + --> $DIR/duplicate.rs:99:44 | LL | type TAW1 where T: Iterator = T; | ---------- ^^^^^^^^^^ re-bound here @@ -336,7 +336,7 @@ LL | type TAW1 where T: Iterator = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:103:44 + --> $DIR/duplicate.rs:101:44 | LL | type TAW2 where T: Iterator = T; | ---------- ^^^^^^^^^^ re-bound here @@ -344,7 +344,7 @@ LL | type TAW2 where T: Iterator = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:105:47 + --> $DIR/duplicate.rs:103:47 | LL | type TAW3 where T: Iterator = T; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -352,7 +352,7 @@ LL | type TAW3 where T: Iterator = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:108:36 + --> $DIR/duplicate.rs:106:36 | LL | type ETAI1> = impl Copy; | ---------- ^^^^^^^^^^ re-bound here @@ -360,7 +360,7 @@ LL | type ETAI1> = impl Copy; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:110:36 + --> $DIR/duplicate.rs:108:36 | LL | type ETAI2> = impl Copy; | ---------- ^^^^^^^^^^ re-bound here @@ -368,7 +368,7 @@ LL | type ETAI2> = impl Copy; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:112:39 + --> $DIR/duplicate.rs:110:39 | LL | type ETAI3> = impl Copy; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -376,7 +376,7 @@ LL | type ETAI3> = impl Copy; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:114:40 + --> $DIR/duplicate.rs:112:40 | LL | type ETAI4 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -384,7 +384,7 @@ LL | type ETAI4 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:116:40 + --> $DIR/duplicate.rs:114:40 | LL | type ETAI5 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -392,7 +392,7 @@ LL | type ETAI5 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:118:43 + --> $DIR/duplicate.rs:116:43 | LL | type ETAI6 = impl Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -400,7 +400,7 @@ LL | type ETAI6 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:121:36 + --> $DIR/duplicate.rs:119:36 | LL | trait TRI1> {} | ---------- ^^^^^^^^^^ re-bound here @@ -408,7 +408,7 @@ LL | trait TRI1> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:123:36 + --> $DIR/duplicate.rs:121:36 | LL | trait TRI2> {} | ---------- ^^^^^^^^^^ re-bound here @@ -416,7 +416,7 @@ LL | trait TRI2> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:125:39 + --> $DIR/duplicate.rs:123:39 | LL | trait TRI3> {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -424,7 +424,7 @@ LL | trait TRI3> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:127:34 + --> $DIR/duplicate.rs:125:34 | LL | trait TRS1: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -432,7 +432,7 @@ LL | trait TRS1: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:129:34 + --> $DIR/duplicate.rs:127:34 | LL | trait TRS2: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -440,7 +440,7 @@ LL | trait TRS2: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:131:37 + --> $DIR/duplicate.rs:129:37 | LL | trait TRS3: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -448,7 +448,7 @@ LL | trait TRS3: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:133:45 + --> $DIR/duplicate.rs:131:45 | LL | trait TRW1 where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -456,7 +456,7 @@ LL | trait TRW1 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:135:45 + --> $DIR/duplicate.rs:133:45 | LL | trait TRW2 where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -464,7 +464,7 @@ LL | trait TRW2 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:137:48 + --> $DIR/duplicate.rs:135:48 | LL | trait TRW3 where T: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -472,7 +472,7 @@ LL | trait TRW3 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:139:46 + --> $DIR/duplicate.rs:137:46 | LL | trait TRSW1 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -480,7 +480,7 @@ LL | trait TRSW1 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:139:46 + --> $DIR/duplicate.rs:137:46 | LL | trait TRSW1 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -488,7 +488,7 @@ LL | trait TRSW1 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:142:46 + --> $DIR/duplicate.rs:140:46 | LL | trait TRSW2 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -496,7 +496,7 @@ LL | trait TRSW2 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:142:46 + --> $DIR/duplicate.rs:140:46 | LL | trait TRSW2 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -504,7 +504,7 @@ LL | trait TRSW2 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:145:49 + --> $DIR/duplicate.rs:143:49 | LL | trait TRSW3 where Self: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -512,7 +512,7 @@ LL | trait TRSW3 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:145:49 + --> $DIR/duplicate.rs:143:49 | LL | trait TRSW3 where Self: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -520,7 +520,7 @@ LL | trait TRSW3 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:155:40 + --> $DIR/duplicate.rs:153:40 | LL | type TADyn1 = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -528,7 +528,7 @@ LL | type TADyn1 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:157:44 + --> $DIR/duplicate.rs:155:44 | LL | type TADyn2 = Box>; | ---------- ^^^^^^^^^^ re-bound here @@ -536,7 +536,7 @@ LL | type TADyn2 = Box>; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:159:43 + --> $DIR/duplicate.rs:157:43 | LL | type TADyn3 = dyn Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -544,7 +544,7 @@ LL | type TADyn3 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:148:43 + --> $DIR/duplicate.rs:146:43 | LL | trait TRA1 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -552,7 +552,7 @@ LL | trait TRA1 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:150:43 + --> $DIR/duplicate.rs:148:43 | LL | trait TRA2 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -560,7 +560,7 @@ LL | trait TRA2 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:152:46 + --> $DIR/duplicate.rs:150:46 | LL | trait TRA3 { type A: Iterator; } | ------------- ^^^^^^^^^^^^^ re-bound here diff --git a/src/test/ui/associated-type-bounds/duplicate.min_tait.stderr b/src/test/ui/associated-type-bounds/duplicate.min_tait.stderr index cc775dee4a2..500e527a018 100644 --- a/src/test/ui/associated-type-bounds/duplicate.min_tait.stderr +++ b/src/test/ui/associated-type-bounds/duplicate.min_tait.stderr @@ -1,5 +1,5 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/duplicate.rs:8:12 + --> $DIR/duplicate.rs:6:12 | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #![feature(impl_trait_in_bindings)] = note: see issue #63065 for more information error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:13:36 + --> $DIR/duplicate.rs:11:36 | LL | struct SI1> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -16,7 +16,7 @@ LL | struct SI1> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:15:36 + --> $DIR/duplicate.rs:13:36 | LL | struct SI2> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -24,7 +24,7 @@ LL | struct SI2> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:17:39 + --> $DIR/duplicate.rs:15:39 | LL | struct SI3> { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -32,7 +32,7 @@ LL | struct SI3> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:19:45 + --> $DIR/duplicate.rs:17:45 | LL | struct SW1 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -40,7 +40,7 @@ LL | struct SW1 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:21:45 + --> $DIR/duplicate.rs:19:45 | LL | struct SW2 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -48,7 +48,7 @@ LL | struct SW2 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:23:48 + --> $DIR/duplicate.rs:21:48 | LL | struct SW3 where T: Iterator { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -56,7 +56,7 @@ LL | struct SW3 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:26:34 + --> $DIR/duplicate.rs:24:34 | LL | enum EI1> { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -64,7 +64,7 @@ LL | enum EI1> { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:28:34 + --> $DIR/duplicate.rs:26:34 | LL | enum EI2> { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -72,7 +72,7 @@ LL | enum EI2> { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:30:37 + --> $DIR/duplicate.rs:28:37 | LL | enum EI3> { V(T) } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -80,7 +80,7 @@ LL | enum EI3> { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:32:43 + --> $DIR/duplicate.rs:30:43 | LL | enum EW1 where T: Iterator { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -88,7 +88,7 @@ LL | enum EW1 where T: Iterator { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:34:43 + --> $DIR/duplicate.rs:32:43 | LL | enum EW2 where T: Iterator { V(T) } | ---------- ^^^^^^^^^^ re-bound here @@ -96,7 +96,7 @@ LL | enum EW2 where T: Iterator { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:36:46 + --> $DIR/duplicate.rs:34:46 | LL | enum EW3 where T: Iterator { V(T) } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -104,7 +104,7 @@ LL | enum EW3 where T: Iterator { V(T) } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:39:35 + --> $DIR/duplicate.rs:37:35 | LL | union UI1> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -112,7 +112,7 @@ LL | union UI1> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:41:35 + --> $DIR/duplicate.rs:39:35 | LL | union UI2> { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -120,7 +120,7 @@ LL | union UI2> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:43:38 + --> $DIR/duplicate.rs:41:38 | LL | union UI3> { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -128,7 +128,7 @@ LL | union UI3> { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:45:44 + --> $DIR/duplicate.rs:43:44 | LL | union UW1 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -136,7 +136,7 @@ LL | union UW1 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:47:44 + --> $DIR/duplicate.rs:45:44 | LL | union UW2 where T: Iterator { f: T } | ---------- ^^^^^^^^^^ re-bound here @@ -144,7 +144,7 @@ LL | union UW2 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:49:47 + --> $DIR/duplicate.rs:47:47 | LL | union UW3 where T: Iterator { f: T } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -152,7 +152,7 @@ LL | union UW3 where T: Iterator { f: T } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:52:32 + --> $DIR/duplicate.rs:50:32 | LL | fn FI1>() {} | ---------- ^^^^^^^^^^ re-bound here @@ -160,7 +160,7 @@ LL | fn FI1>() {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:54:32 + --> $DIR/duplicate.rs:52:32 | LL | fn FI2>() {} | ---------- ^^^^^^^^^^ re-bound here @@ -168,7 +168,7 @@ LL | fn FI2>() {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:56:35 + --> $DIR/duplicate.rs:54:35 | LL | fn FI3>() {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -176,7 +176,7 @@ LL | fn FI3>() {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:58:43 + --> $DIR/duplicate.rs:56:43 | LL | fn FW1() where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -184,7 +184,7 @@ LL | fn FW1() where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:60:43 + --> $DIR/duplicate.rs:58:43 | LL | fn FW2() where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -192,7 +192,7 @@ LL | fn FW2() where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:62:46 + --> $DIR/duplicate.rs:60:46 | LL | fn FW3() where T: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -200,7 +200,7 @@ LL | fn FW3() where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:68:40 + --> $DIR/duplicate.rs:66:40 | LL | fn FAPIT1(_: impl Iterator) {} | ---------- ^^^^^^^^^^ re-bound here @@ -208,7 +208,7 @@ LL | fn FAPIT1(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:70:40 + --> $DIR/duplicate.rs:68:40 | LL | fn FAPIT2(_: impl Iterator) {} | ---------- ^^^^^^^^^^ re-bound here @@ -216,7 +216,7 @@ LL | fn FAPIT2(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:72:43 + --> $DIR/duplicate.rs:70:43 | LL | fn FAPIT3(_: impl Iterator) {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -224,7 +224,7 @@ LL | fn FAPIT3(_: impl Iterator) {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:75:39 + --> $DIR/duplicate.rs:73:39 | LL | const CIT1: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -232,7 +232,7 @@ LL | const CIT1: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:77:39 + --> $DIR/duplicate.rs:75:39 | LL | const CIT2: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -240,7 +240,7 @@ LL | const CIT2: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:79:42 + --> $DIR/duplicate.rs:77:42 | LL | const CIT3: impl Iterator = iter::empty(); | ------------- ^^^^^^^^^^^^^ re-bound here @@ -248,7 +248,7 @@ LL | const CIT3: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:81:40 + --> $DIR/duplicate.rs:79:40 | LL | static SIT1: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -256,7 +256,7 @@ LL | static SIT1: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:83:40 + --> $DIR/duplicate.rs:81:40 | LL | static SIT2: impl Iterator = iter::empty(); | ---------- ^^^^^^^^^^ re-bound here @@ -264,7 +264,7 @@ LL | static SIT2: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:85:43 + --> $DIR/duplicate.rs:83:43 | LL | static SIT3: impl Iterator = iter::empty(); | ------------- ^^^^^^^^^^^^^ re-bound here @@ -272,7 +272,7 @@ LL | static SIT3: impl Iterator = iter::empty(); | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:88:46 + --> $DIR/duplicate.rs:86:46 | LL | fn lit1() { let _: impl Iterator = iter::empty(); } | ---------- ^^^^^^^^^^ re-bound here @@ -280,7 +280,7 @@ LL | fn lit1() { let _: impl Iterator = iter::empty(); } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:90:46 + --> $DIR/duplicate.rs:88:46 | LL | fn lit2() { let _: impl Iterator = iter::empty(); } | ---------- ^^^^^^^^^^ re-bound here @@ -288,7 +288,7 @@ LL | fn lit2() { let _: impl Iterator = iter::empty(); } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:92:49 + --> $DIR/duplicate.rs:90:49 | LL | fn lit3() { let _: impl Iterator = iter::empty(); } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -296,7 +296,7 @@ LL | fn lit3() { let _: impl Iterator = iter::empt | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:95:35 + --> $DIR/duplicate.rs:93:35 | LL | type TAI1> = T; | ---------- ^^^^^^^^^^ re-bound here @@ -304,7 +304,7 @@ LL | type TAI1> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:97:35 + --> $DIR/duplicate.rs:95:35 | LL | type TAI2> = T; | ---------- ^^^^^^^^^^ re-bound here @@ -312,7 +312,7 @@ LL | type TAI2> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:99:38 + --> $DIR/duplicate.rs:97:38 | LL | type TAI3> = T; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -320,7 +320,7 @@ LL | type TAI3> = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:101:44 + --> $DIR/duplicate.rs:99:44 | LL | type TAW1 where T: Iterator = T; | ---------- ^^^^^^^^^^ re-bound here @@ -328,7 +328,7 @@ LL | type TAW1 where T: Iterator = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:103:44 + --> $DIR/duplicate.rs:101:44 | LL | type TAW2 where T: Iterator = T; | ---------- ^^^^^^^^^^ re-bound here @@ -336,7 +336,7 @@ LL | type TAW2 where T: Iterator = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:105:47 + --> $DIR/duplicate.rs:103:47 | LL | type TAW3 where T: Iterator = T; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -344,7 +344,7 @@ LL | type TAW3 where T: Iterator = T; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:108:36 + --> $DIR/duplicate.rs:106:36 | LL | type ETAI1> = impl Copy; | ---------- ^^^^^^^^^^ re-bound here @@ -352,7 +352,7 @@ LL | type ETAI1> = impl Copy; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:110:36 + --> $DIR/duplicate.rs:108:36 | LL | type ETAI2> = impl Copy; | ---------- ^^^^^^^^^^ re-bound here @@ -360,7 +360,7 @@ LL | type ETAI2> = impl Copy; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:112:39 + --> $DIR/duplicate.rs:110:39 | LL | type ETAI3> = impl Copy; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -368,7 +368,7 @@ LL | type ETAI3> = impl Copy; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:114:40 + --> $DIR/duplicate.rs:112:40 | LL | type ETAI4 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -376,7 +376,7 @@ LL | type ETAI4 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:116:40 + --> $DIR/duplicate.rs:114:40 | LL | type ETAI5 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -384,7 +384,7 @@ LL | type ETAI5 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:118:43 + --> $DIR/duplicate.rs:116:43 | LL | type ETAI6 = impl Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -392,7 +392,7 @@ LL | type ETAI6 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:121:36 + --> $DIR/duplicate.rs:119:36 | LL | trait TRI1> {} | ---------- ^^^^^^^^^^ re-bound here @@ -400,7 +400,7 @@ LL | trait TRI1> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:123:36 + --> $DIR/duplicate.rs:121:36 | LL | trait TRI2> {} | ---------- ^^^^^^^^^^ re-bound here @@ -408,7 +408,7 @@ LL | trait TRI2> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:125:39 + --> $DIR/duplicate.rs:123:39 | LL | trait TRI3> {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -416,7 +416,7 @@ LL | trait TRI3> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:127:34 + --> $DIR/duplicate.rs:125:34 | LL | trait TRS1: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -424,7 +424,7 @@ LL | trait TRS1: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:129:34 + --> $DIR/duplicate.rs:127:34 | LL | trait TRS2: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -432,7 +432,7 @@ LL | trait TRS2: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:131:37 + --> $DIR/duplicate.rs:129:37 | LL | trait TRS3: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -440,7 +440,7 @@ LL | trait TRS3: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:133:45 + --> $DIR/duplicate.rs:131:45 | LL | trait TRW1 where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -448,7 +448,7 @@ LL | trait TRW1 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:135:45 + --> $DIR/duplicate.rs:133:45 | LL | trait TRW2 where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -456,7 +456,7 @@ LL | trait TRW2 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:137:48 + --> $DIR/duplicate.rs:135:48 | LL | trait TRW3 where T: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -464,7 +464,7 @@ LL | trait TRW3 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:139:46 + --> $DIR/duplicate.rs:137:46 | LL | trait TRSW1 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -472,7 +472,7 @@ LL | trait TRSW1 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:139:46 + --> $DIR/duplicate.rs:137:46 | LL | trait TRSW1 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -480,7 +480,7 @@ LL | trait TRSW1 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:142:46 + --> $DIR/duplicate.rs:140:46 | LL | trait TRSW2 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -488,7 +488,7 @@ LL | trait TRSW2 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:142:46 + --> $DIR/duplicate.rs:140:46 | LL | trait TRSW2 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -496,7 +496,7 @@ LL | trait TRSW2 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:145:49 + --> $DIR/duplicate.rs:143:49 | LL | trait TRSW3 where Self: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -504,7 +504,7 @@ LL | trait TRSW3 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:145:49 + --> $DIR/duplicate.rs:143:49 | LL | trait TRSW3 where Self: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -512,7 +512,7 @@ LL | trait TRSW3 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:155:40 + --> $DIR/duplicate.rs:153:40 | LL | type TADyn1 = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -520,7 +520,7 @@ LL | type TADyn1 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:157:44 + --> $DIR/duplicate.rs:155:44 | LL | type TADyn2 = Box>; | ---------- ^^^^^^^^^^ re-bound here @@ -528,7 +528,7 @@ LL | type TADyn2 = Box>; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:159:43 + --> $DIR/duplicate.rs:157:43 | LL | type TADyn3 = dyn Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -536,7 +536,7 @@ LL | type TADyn3 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:148:43 + --> $DIR/duplicate.rs:146:43 | LL | trait TRA1 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -544,7 +544,7 @@ LL | trait TRA1 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:150:43 + --> $DIR/duplicate.rs:148:43 | LL | trait TRA2 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -552,7 +552,7 @@ LL | trait TRA2 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified - --> $DIR/duplicate.rs:152:46 + --> $DIR/duplicate.rs:150:46 | LL | trait TRA3 { type A: Iterator; } | ------------- ^^^^^^^^^^^^^ re-bound here diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs index a7bbeaf38e7..c3319a7050d 100644 --- a/src/test/ui/associated-type-bounds/duplicate.rs +++ b/src/test/ui/associated-type-bounds/duplicate.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![feature(associated_type_bounds)] // revisions: min_tait full_tait #![feature(min_type_alias_impl_trait)] diff --git a/src/test/ui/async-await/issue-61949-self-return-type.rs b/src/test/ui/async-await/issue-61949-self-return-type.rs index 6a28c69193d..43429ba2329 100644 --- a/src/test/ui/async-await/issue-61949-self-return-type.rs +++ b/src/test/ui/async-await/issue-61949-self-return-type.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // edition:2018 // This test checks that `Self` is prohibited as a return type. See #61949 for context. diff --git a/src/test/ui/async-await/issue-61949-self-return-type.stderr b/src/test/ui/async-await/issue-61949-self-return-type.stderr index 4eeef871c5b..52b726e186e 100644 --- a/src/test/ui/async-await/issue-61949-self-return-type.stderr +++ b/src/test/ui/async-await/issue-61949-self-return-type.stderr @@ -1,5 +1,5 @@ error[E0760]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - --> $DIR/issue-61949-self-return-type.rs:11:40 + --> $DIR/issue-61949-self-return-type.rs:10:40 | LL | pub async fn new(_bar: &'a i32) -> Self { | ^^^^ help: consider spelling out the type instead: `Foo<'a>` diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.rs b/src/test/ui/borrowck/borrowck-describe-lvalue.rs index c8bfbe0729c..0e6c0635adb 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.rs +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - pub struct Foo { x: u32 } diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr index e386aa1f1f4..0f2ebbcbf3c 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-describe-lvalue.rs:256:13 + --> $DIR/borrowck-describe-lvalue.rs:254:13 | LL | let y = &mut x; | ------ first mutable borrow occurs here @@ -9,7 +9,7 @@ LL | *y = 1; | ------ first borrow later used here error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-describe-lvalue.rs:266:20 + --> $DIR/borrowck-describe-lvalue.rs:264:20 | LL | let y = &mut x; | ------ first mutable borrow occurs here @@ -19,7 +19,7 @@ LL | *y = 1; | ------ first borrow later used here error: captured variable cannot escape `FnMut` closure body - --> $DIR/borrowck-describe-lvalue.rs:264:16 + --> $DIR/borrowck-describe-lvalue.rs:262:16 | LL | let mut x = 0; | ----- variable defined here @@ -38,7 +38,7 @@ LL | | } = note: ...therefore, they cannot allow references to captured variables to escape error[E0503]: cannot use `f.x` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:39:9 + --> $DIR/borrowck-describe-lvalue.rs:37:9 | LL | let x = f.x(); | - borrow of `f` occurs here @@ -48,7 +48,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `g.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:46:9 + --> $DIR/borrowck-describe-lvalue.rs:44:9 | LL | let x = g.x(); | - borrow of `g` occurs here @@ -58,7 +58,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `h.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:53:9 + --> $DIR/borrowck-describe-lvalue.rs:51:9 | LL | let x = &mut h.0; | -------- borrow of `h.0` occurs here @@ -68,7 +68,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `e.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:61:20 + --> $DIR/borrowck-describe-lvalue.rs:59:20 | LL | let x = e.x(); | - borrow of `e` occurs here @@ -80,7 +80,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `u.a` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:69:9 + --> $DIR/borrowck-describe-lvalue.rs:67:9 | LL | let x = &mut u.a; | -------- borrow of `u.a` occurs here @@ -90,7 +90,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `f.x` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:76:9 + --> $DIR/borrowck-describe-lvalue.rs:74:9 | LL | let x = f.x(); | - borrow of `*f` occurs here @@ -100,7 +100,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `g.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:83:9 + --> $DIR/borrowck-describe-lvalue.rs:81:9 | LL | let x = g.x(); | - borrow of `*g` occurs here @@ -110,7 +110,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `h.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:90:9 + --> $DIR/borrowck-describe-lvalue.rs:88:9 | LL | let x = &mut h.0; | -------- borrow of `h.0` occurs here @@ -120,7 +120,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `e.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:98:20 + --> $DIR/borrowck-describe-lvalue.rs:96:20 | LL | let x = e.x(); | - borrow of `*e` occurs here @@ -132,7 +132,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `u.a` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:107:9 + --> $DIR/borrowck-describe-lvalue.rs:105:9 | LL | let x = &mut u.a; | -------- borrow of `u.a` occurs here @@ -142,7 +142,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:115:15 + --> $DIR/borrowck-describe-lvalue.rs:113:15 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -154,7 +154,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:120:18 + --> $DIR/borrowck-describe-lvalue.rs:118:18 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -166,7 +166,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:125:25 + --> $DIR/borrowck-describe-lvalue.rs:123:25 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -178,7 +178,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:130:28 + --> $DIR/borrowck-describe-lvalue.rs:128:28 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -190,7 +190,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:141:15 + --> $DIR/borrowck-describe-lvalue.rs:139:15 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -202,7 +202,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:146:18 + --> $DIR/borrowck-describe-lvalue.rs:144:18 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -214,7 +214,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:151:15 + --> $DIR/borrowck-describe-lvalue.rs:149:15 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -226,7 +226,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:156:18 + --> $DIR/borrowck-describe-lvalue.rs:154:18 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -238,7 +238,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `e` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:169:13 + --> $DIR/borrowck-describe-lvalue.rs:167:13 | LL | let x = &mut e; | ------ borrow of `e` occurs here @@ -250,7 +250,7 @@ LL | drop(x); | - borrow later used here error[E0502]: cannot borrow `e.0` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:169:18 + --> $DIR/borrowck-describe-lvalue.rs:167:18 | LL | let x = &mut e; | ------ mutable borrow occurs here @@ -262,7 +262,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `e.x` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:173:23 + --> $DIR/borrowck-describe-lvalue.rs:171:23 | LL | let x = &mut e; | ------ mutable borrow occurs here @@ -274,7 +274,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `s.y.0` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:186:22 + --> $DIR/borrowck-describe-lvalue.rs:184:22 | LL | let x = &mut s; | ------ mutable borrow occurs here @@ -286,7 +286,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `s.x.y` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:192:28 + --> $DIR/borrowck-describe-lvalue.rs:190:28 | LL | let x = &mut s; | ------ mutable borrow occurs here @@ -298,7 +298,7 @@ LL | drop(x); | - mutable borrow later used here error[E0503]: cannot use `*v` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:234:9 + --> $DIR/borrowck-describe-lvalue.rs:232:9 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -309,7 +309,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[_].y` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:234:9 + --> $DIR/borrowck-describe-lvalue.rs:232:9 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -320,7 +320,7 @@ LL | drop(x); | - borrow later used here error[E0502]: cannot borrow `v[..].x` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:245:24 + --> $DIR/borrowck-describe-lvalue.rs:243:24 | LL | let x = &mut v; | ------ mutable borrow occurs here @@ -332,7 +332,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:208:29 + --> $DIR/borrowck-describe-lvalue.rs:206:29 | LL | let x = &mut block; | ---------- mutable borrow occurs here @@ -343,7 +343,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:223:33 + --> $DIR/borrowck-describe-lvalue.rs:221:33 | LL | let x = &mut block; | ---------- mutable borrow occurs here @@ -354,7 +354,7 @@ LL | drop(x); | - mutable borrow later used here error[E0382]: use of moved value: `x` - --> $DIR/borrowck-describe-lvalue.rs:276:22 + --> $DIR/borrowck-describe-lvalue.rs:274:22 | LL | drop(x); | - value moved here diff --git a/src/test/ui/borrowck/borrowck-union-borrow.rs b/src/test/ui/borrowck/borrowck-union-borrow.rs index 63901680bd1..f01915398a4 100644 --- a/src/test/ui/borrowck/borrowck-union-borrow.rs +++ b/src/test/ui/borrowck/borrowck-union-borrow.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #[derive(Clone, Copy)] union U { a: u8, diff --git a/src/test/ui/borrowck/borrowck-union-borrow.stderr b/src/test/ui/borrowck/borrowck-union-borrow.stderr index ca10e299c58..395cd0b4855 100644 --- a/src/test/ui/borrowck/borrowck-union-borrow.stderr +++ b/src/test/ui/borrowck/borrowck-union-borrow.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `u.a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-union-borrow.rs:25:23 + --> $DIR/borrowck-union-borrow.rs:23:23 | LL | let ra = &u.a; | ---- immutable borrow occurs here @@ -9,7 +9,7 @@ LL | drop(ra); | -- immutable borrow later used here error[E0506]: cannot assign to `u.a` because it is borrowed - --> $DIR/borrowck-union-borrow.rs:30:13 + --> $DIR/borrowck-union-borrow.rs:28:13 | LL | let ra = &u.a; | ---- borrow of `u.a` occurs here @@ -19,7 +19,7 @@ LL | drop(ra); | -- borrow later used here error[E0502]: cannot borrow `u` (via `u.b`) as mutable because it is also borrowed as immutable (via `u.a`) - --> $DIR/borrowck-union-borrow.rs:46:23 + --> $DIR/borrowck-union-borrow.rs:44:23 | LL | let ra = &u.a; | ---- immutable borrow occurs here (via `u.a`) @@ -31,7 +31,7 @@ LL | drop(ra); = note: `u.b` is a field of the union `U`, so it overlaps the field `u.a` error[E0506]: cannot assign to `u.b` because it is borrowed - --> $DIR/borrowck-union-borrow.rs:51:13 + --> $DIR/borrowck-union-borrow.rs:49:13 | LL | let ra = &u.a; | ---- borrow of `u.b` occurs here @@ -41,7 +41,7 @@ LL | drop(ra); | -- borrow later used here error[E0502]: cannot borrow `u.a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-union-borrow.rs:57:22 + --> $DIR/borrowck-union-borrow.rs:55:22 | LL | let rma = &mut u.a; | -------- mutable borrow occurs here @@ -51,7 +51,7 @@ LL | drop(rma); | --- mutable borrow later used here error[E0503]: cannot use `u.a` because it was mutably borrowed - --> $DIR/borrowck-union-borrow.rs:62:21 + --> $DIR/borrowck-union-borrow.rs:60:21 | LL | let ra = &mut u.a; | -------- borrow of `u.a` occurs here @@ -61,7 +61,7 @@ LL | drop(ra); | -- borrow later used here error[E0499]: cannot borrow `u.a` as mutable more than once at a time - --> $DIR/borrowck-union-borrow.rs:67:24 + --> $DIR/borrowck-union-borrow.rs:65:24 | LL | let rma = &mut u.a; | -------- first mutable borrow occurs here @@ -71,7 +71,7 @@ LL | drop(rma); | --- first borrow later used here error[E0506]: cannot assign to `u.a` because it is borrowed - --> $DIR/borrowck-union-borrow.rs:72:13 + --> $DIR/borrowck-union-borrow.rs:70:13 | LL | let rma = &mut u.a; | -------- borrow of `u.a` occurs here @@ -81,7 +81,7 @@ LL | drop(rma); | --- borrow later used here error[E0502]: cannot borrow `u` (via `u.b`) as immutable because it is also borrowed as mutable (via `u.a`) - --> $DIR/borrowck-union-borrow.rs:78:22 + --> $DIR/borrowck-union-borrow.rs:76:22 | LL | let rma = &mut u.a; | -------- mutable borrow occurs here (via `u.a`) @@ -93,7 +93,7 @@ LL | drop(rma); = note: `u.b` is a field of the union `U`, so it overlaps the field `u.a` error[E0503]: cannot use `u.b` because it was mutably borrowed - --> $DIR/borrowck-union-borrow.rs:83:21 + --> $DIR/borrowck-union-borrow.rs:81:21 | LL | let ra = &mut u.a; | -------- borrow of `u.a` occurs here @@ -104,7 +104,7 @@ LL | drop(ra); | -- borrow later used here error[E0499]: cannot borrow `u` (via `u.b`) as mutable more than once at a time - --> $DIR/borrowck-union-borrow.rs:89:24 + --> $DIR/borrowck-union-borrow.rs:87:24 | LL | let rma = &mut u.a; | -------- first mutable borrow occurs here (via `u.a`) @@ -116,7 +116,7 @@ LL | drop(rma); = note: `u.b` is a field of the union `U`, so it overlaps the field `u.a` error[E0506]: cannot assign to `u.b` because it is borrowed - --> $DIR/borrowck-union-borrow.rs:94:13 + --> $DIR/borrowck-union-borrow.rs:92:13 | LL | let rma = &mut u.a; | -------- borrow of `u.b` occurs here diff --git a/src/test/ui/borrowck/two-phase-allow-access-during-reservation.nll_target.stderr b/src/test/ui/borrowck/two-phase-allow-access-during-reservation.nll_target.stderr index 9f31c3f87c3..bba3393fc14 100644 --- a/src/test/ui/borrowck/two-phase-allow-access-during-reservation.nll_target.stderr +++ b/src/test/ui/borrowck/two-phase-allow-access-during-reservation.nll_target.stderr @@ -1,5 +1,5 @@ error[E0503]: cannot use `i` because it was mutably borrowed - --> $DIR/two-phase-allow-access-during-reservation.rs:30:19 + --> $DIR/two-phase-allow-access-during-reservation.rs:28:19 | LL | /*1*/ let p = &mut i; // (reservation of `i` starts here) | ------ borrow of `i` occurs here @@ -11,7 +11,7 @@ LL | /*3*/ *p += 1; // (mutable borrow of `i` starts here, since `p` | ------- borrow later used here error[E0503]: cannot use `i` because it was mutably borrowed - --> $DIR/two-phase-allow-access-during-reservation.rs:35:19 + --> $DIR/two-phase-allow-access-during-reservation.rs:33:19 | LL | /*1*/ let p = &mut i; // (reservation of `i` starts here) | ------ borrow of `i` occurs here diff --git a/src/test/ui/borrowck/two-phase-allow-access-during-reservation.rs b/src/test/ui/borrowck/two-phase-allow-access-during-reservation.rs index 07169afefc9..3afa679ce39 100644 --- a/src/test/ui/borrowck/two-phase-allow-access-during-reservation.rs +++ b/src/test/ui/borrowck/two-phase-allow-access-during-reservation.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // revisions: nll_target // The following revisions are disabled due to missing support for two_phase_beyond_autoref diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference.nll_target.stderr b/src/test/ui/borrowck/two-phase-reservation-sharing-interference.nll_target.stderr index 7b64d9d4002..2cbdc0901bc 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference.nll_target.stderr +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference.nll_target.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `vec` as mutable because it is also borrowed as immutable - --> $DIR/two-phase-reservation-sharing-interference.rs:36:17 + --> $DIR/two-phase-reservation-sharing-interference.rs:34:17 | LL | let shared = &vec; | ---- immutable borrow occurs here diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs b/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs index de6f66c1c3f..f7392bfeaab 100644 --- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs +++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // revisions: nll_target // The following revisions are disabled due to missing support from two-phase beyond autorefs diff --git a/src/test/ui/commandline-argfile-missing.rs b/src/test/ui/commandline-argfile-missing.rs index 020c3ff3c7e..5a6465bd064 100644 --- a/src/test/ui/commandline-argfile-missing.rs +++ b/src/test/ui/commandline-argfile-missing.rs @@ -1,6 +1,5 @@ // Check to see if we can get parameters from an @argsfile file // -// ignore-tidy-linelength // normalize-stderr-test: "os error \d+" -> "os error $$ERR" // normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " // compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args diff --git a/src/test/ui/consts/issue-32829-2.rs b/src/test/ui/consts/issue-32829-2.rs index c93c84b5fb7..e0fcf278330 100644 --- a/src/test/ui/consts/issue-32829-2.rs +++ b/src/test/ui/consts/issue-32829-2.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - const bad : u32 = { { 5; diff --git a/src/test/ui/consts/issue-32829-2.stderr b/src/test/ui/consts/issue-32829-2.stderr index 8d7423f29ae..1d265875c5c 100644 --- a/src/test/ui/consts/issue-32829-2.stderr +++ b/src/test/ui/consts/issue-32829-2.stderr @@ -1,17 +1,17 @@ error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-32829-2.rs:12:9 + --> $DIR/issue-32829-2.rs:10:9 | LL | invalid(); | ^^^^^^^^^ error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-32829-2.rs:34:9 + --> $DIR/issue-32829-2.rs:32:9 | LL | invalid(); | ^^^^^^^^^ error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-32829-2.rs:56:9 + --> $DIR/issue-32829-2.rs:54:9 | LL | invalid(); | ^^^^^^^^^ diff --git a/src/test/ui/consts/offset_ub.rs b/src/test/ui/consts/offset_ub.rs index 4f943ed9ad1..7ce45ba9c4b 100644 --- a/src/test/ui/consts/offset_ub.rs +++ b/src/test/ui/consts/offset_ub.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![feature(const_ptr_offset)] use std::ptr; diff --git a/src/test/ui/consts/offset_ub.stderr b/src/test/ui/consts/offset_ub.stderr index 5e8b7a8e0b6..082142fbbb7 100644 --- a/src/test/ui/consts/offset_ub.stderr +++ b/src/test/ui/consts/offset_ub.stderr @@ -6,9 +6,9 @@ LL | unsafe { intrinsics::offset(self, count) } | | | overflowing in-bounds pointer arithmetic | inside `ptr::const_ptr::::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | inside `BEFORE_START` at $DIR/offset_ub.rs:7:46 + | inside `BEFORE_START` at $DIR/offset_ub.rs:6:46 | - ::: $DIR/offset_ub.rs:7:1 + ::: $DIR/offset_ub.rs:6:1 | LL | pub const BEFORE_START: *const u8 = unsafe { (&0u8 as *const u8).offset(-1) }; | ------------------------------------------------------------------------------ @@ -25,9 +25,9 @@ LL | unsafe { intrinsics::offset(self, count) } | | | inbounds test failed: pointer must be in-bounds at offset 2, but is outside bounds of allocN which has size 1 | inside `ptr::const_ptr::::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | inside `AFTER_END` at $DIR/offset_ub.rs:8:43 + | inside `AFTER_END` at $DIR/offset_ub.rs:7:43 | - ::: $DIR/offset_ub.rs:8:1 + ::: $DIR/offset_ub.rs:7:1 | LL | pub const AFTER_END: *const u8 = unsafe { (&0u8 as *const u8).offset(2) }; | -------------------------------------------------------------------------- @@ -43,9 +43,9 @@ LL | unsafe { intrinsics::offset(self, count) } | | | inbounds test failed: pointer must be in-bounds at offset 101, but is outside bounds of allocN which has size 100 | inside `ptr::const_ptr::::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | inside `AFTER_ARRAY` at $DIR/offset_ub.rs:9:45 + | inside `AFTER_ARRAY` at $DIR/offset_ub.rs:8:45 | - ::: $DIR/offset_ub.rs:9:1 + ::: $DIR/offset_ub.rs:8:1 | LL | pub const AFTER_ARRAY: *const u8 = unsafe { [0u8; 100].as_ptr().offset(101) }; | ------------------------------------------------------------------------------ @@ -61,9 +61,9 @@ LL | unsafe { intrinsics::offset(self, count) } | | | overflowing in-bounds pointer arithmetic | inside `ptr::const_ptr::::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | inside `OVERFLOW` at $DIR/offset_ub.rs:11:43 + | inside `OVERFLOW` at $DIR/offset_ub.rs:10:43 | - ::: $DIR/offset_ub.rs:11:1 + ::: $DIR/offset_ub.rs:10:1 | LL | pub const OVERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MAX) }; | ---------------------------------------------------------------------------------- @@ -79,9 +79,9 @@ LL | unsafe { intrinsics::offset(self, count) } | | | overflowing in-bounds pointer arithmetic | inside `ptr::const_ptr::::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | inside `UNDERFLOW` at $DIR/offset_ub.rs:12:44 + | inside `UNDERFLOW` at $DIR/offset_ub.rs:11:44 | - ::: $DIR/offset_ub.rs:12:1 + ::: $DIR/offset_ub.rs:11:1 | LL | pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) }; | ----------------------------------------------------------------------------------- @@ -97,9 +97,9 @@ LL | unsafe { intrinsics::offset(self, count) } | | | overflowing in-bounds pointer arithmetic | inside `ptr::const_ptr::::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | inside `OVERFLOW_ADDRESS_SPACE` at $DIR/offset_ub.rs:13:56 + | inside `OVERFLOW_ADDRESS_SPACE` at $DIR/offset_ub.rs:12:56 | - ::: $DIR/offset_ub.rs:13:1 + ::: $DIR/offset_ub.rs:12:1 | LL | pub const OVERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (usize::MAX as *const u8).offset(2) }; | --------------------------------------------------------------------------------------------- @@ -115,9 +115,9 @@ LL | unsafe { intrinsics::offset(self, count) } | | | overflowing in-bounds pointer arithmetic | inside `ptr::const_ptr::::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | inside `UNDERFLOW_ADDRESS_SPACE` at $DIR/offset_ub.rs:14:57 + | inside `UNDERFLOW_ADDRESS_SPACE` at $DIR/offset_ub.rs:13:57 | - ::: $DIR/offset_ub.rs:14:1 + ::: $DIR/offset_ub.rs:13:1 | LL | pub const UNDERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (1 as *const u8).offset(-2) }; | -------------------------------------------------------------------------------------- @@ -133,9 +133,9 @@ LL | unsafe { intrinsics::offset(self, count) } | | | inbounds test failed: pointer must be in-bounds at offset 1, but is outside bounds of allocN which has size 0 | inside `ptr::const_ptr::::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | inside `ZERO_SIZED_ALLOC` at $DIR/offset_ub.rs:16:50 + | inside `ZERO_SIZED_ALLOC` at $DIR/offset_ub.rs:15:50 | - ::: $DIR/offset_ub.rs:16:1 + ::: $DIR/offset_ub.rs:15:1 | LL | pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) }; | ------------------------------------------------------------------------------- @@ -151,9 +151,9 @@ LL | unsafe { intrinsics::offset(self, count) as *mut T } | | | unable to turn bytes into a pointer | inside `ptr::mut_ptr::::offset` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - | inside `DANGLING` at $DIR/offset_ub.rs:17:42 + | inside `DANGLING` at $DIR/offset_ub.rs:16:42 | - ::: $DIR/offset_ub.rs:17:1 + ::: $DIR/offset_ub.rs:16:1 | LL | pub const DANGLING: *const u8 = unsafe { ptr::NonNull::::dangling().as_ptr().offset(4) }; | --------------------------------------------------------------------------------------------- @@ -169,9 +169,9 @@ LL | unsafe { intrinsics::offset(self, count) } | | | inbounds test failed: 0x0 is not a valid pointer | inside `ptr::const_ptr::::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | inside `NULL_OFFSET_ZERO` at $DIR/offset_ub.rs:20:50 + | inside `NULL_OFFSET_ZERO` at $DIR/offset_ub.rs:19:50 | - ::: $DIR/offset_ub.rs:20:1 + ::: $DIR/offset_ub.rs:19:1 | LL | pub const NULL_OFFSET_ZERO: *const u8 = unsafe { ptr::null::().offset(0) }; | ------------------------------------------------------------------------------- @@ -187,9 +187,9 @@ LL | unsafe { intrinsics::offset(self, count) } | | | unable to turn bytes into a pointer | inside `ptr::const_ptr::::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | inside `UNDERFLOW_ABS` at $DIR/offset_ub.rs:23:47 + | inside `UNDERFLOW_ABS` at $DIR/offset_ub.rs:22:47 | - ::: $DIR/offset_ub.rs:23:1 + ::: $DIR/offset_ub.rs:22:1 | LL | pub const UNDERFLOW_ABS: *const u8 = unsafe { (usize::MAX as *const u8).offset(isize::MIN) }; | --------------------------------------------------------------------------------------------- diff --git a/src/test/ui/deprecation/deprecation-lint.rs b/src/test/ui/deprecation/deprecation-lint.rs index 560e2968886..b6c791c15fd 100644 --- a/src/test/ui/deprecation/deprecation-lint.rs +++ b/src/test/ui/deprecation/deprecation-lint.rs @@ -1,5 +1,4 @@ // aux-build:deprecation-lint.rs -// ignore-tidy-linelength #![deny(deprecated)] #![allow(warnings)] diff --git a/src/test/ui/deprecation/deprecation-lint.stderr b/src/test/ui/deprecation/deprecation-lint.stderr index 12c76f0f4a5..959cf93bac0 100644 --- a/src/test/ui/deprecation/deprecation-lint.stderr +++ b/src/test/ui/deprecation/deprecation-lint.stderr @@ -1,737 +1,737 @@ error: use of deprecated function `deprecation_lint::deprecated`: text - --> $DIR/deprecation-lint.rs:17:9 + --> $DIR/deprecation-lint.rs:16:9 | LL | deprecated(); | ^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/deprecation-lint.rs:4:9 + --> $DIR/deprecation-lint.rs:3:9 | LL | #![deny(deprecated)] | ^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:22:9 + --> $DIR/deprecation-lint.rs:21:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:24:9 + --> $DIR/deprecation-lint.rs:23:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated function `deprecation_lint::deprecated_text`: text - --> $DIR/deprecation-lint.rs:26:9 + --> $DIR/deprecation-lint.rs:25:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:31:9 + --> $DIR/deprecation-lint.rs:30:9 | LL | ... Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:33:9 + --> $DIR/deprecation-lint.rs:32:9 | LL | ... ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated struct `deprecation_lint::DeprecatedStruct`: text - --> $DIR/deprecation-lint.rs:35:17 + --> $DIR/deprecation-lint.rs:34:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ error: use of deprecated struct `deprecation_lint::DeprecatedUnitStruct`: text - --> $DIR/deprecation-lint.rs:39:17 + --> $DIR/deprecation-lint.rs:38:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ error: use of deprecated variant `deprecation_lint::Enum::DeprecatedVariant`: text - --> $DIR/deprecation-lint.rs:41:17 + --> $DIR/deprecation-lint.rs:40:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated struct `deprecation_lint::DeprecatedTupleStruct`: text - --> $DIR/deprecation-lint.rs:43:17 + --> $DIR/deprecation-lint.rs:42:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated struct `deprecation_lint::nested::DeprecatedStruct`: text - --> $DIR/deprecation-lint.rs:45:17 + --> $DIR/deprecation-lint.rs:44:17 | LL | let _ = nested::DeprecatedStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated struct `deprecation_lint::nested::DeprecatedUnitStruct`: text - --> $DIR/deprecation-lint.rs:49:17 + --> $DIR/deprecation-lint.rs:48:17 | LL | let _ = nested::DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated variant `deprecation_lint::nested::Enum::DeprecatedVariant`: text - --> $DIR/deprecation-lint.rs:51:17 + --> $DIR/deprecation-lint.rs:50:17 | LL | ... let _ = nested::Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated struct `deprecation_lint::nested::DeprecatedTupleStruct`: text - --> $DIR/deprecation-lint.rs:53:17 + --> $DIR/deprecation-lint.rs:52:17 | LL | ... let _ = nested::DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated function `deprecation_lint::deprecated_text`: text - --> $DIR/deprecation-lint.rs:60:25 + --> $DIR/deprecation-lint.rs:59:25 | LL | macro_test_arg!(deprecated_text()); | ^^^^^^^^^^^^^^^ error: use of deprecated function `deprecation_lint::deprecated_text`: text - --> $DIR/deprecation-lint.rs:61:41 + --> $DIR/deprecation-lint.rs:60:41 | LL | macro_test_arg!(macro_test_arg!(deprecated_text())); | ^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:66:9 + --> $DIR/deprecation-lint.rs:65:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:68:9 + --> $DIR/deprecation-lint.rs:67:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:70:9 + --> $DIR/deprecation-lint.rs:69:9 | LL | ... Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:72:9 + --> $DIR/deprecation-lint.rs:71:9 | LL | ... ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated trait `deprecation_lint::DeprecatedTrait`: text - --> $DIR/deprecation-lint.rs:82:10 + --> $DIR/deprecation-lint.rs:81:10 | LL | impl DeprecatedTrait for S {} | ^^^^^^^^^^^^^^^ error: use of deprecated trait `deprecation_lint::DeprecatedTrait`: text - --> $DIR/deprecation-lint.rs:83:24 + --> $DIR/deprecation-lint.rs:82:24 | LL | trait LocalTrait : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ error: use of deprecated struct `deprecation_lint::Deprecated`: text - --> $DIR/deprecation-lint.rs:114:17 + --> $DIR/deprecation-lint.rs:113:17 | LL | let x = Deprecated { | ^^^^^^^^^^ error: use of deprecated struct `deprecation_lint::Deprecated`: text - --> $DIR/deprecation-lint.rs:123:13 + --> $DIR/deprecation-lint.rs:122:13 | LL | let Deprecated { | ^^^^^^^^^^ error: use of deprecated struct `deprecation_lint::Deprecated`: text - --> $DIR/deprecation-lint.rs:129:13 + --> $DIR/deprecation-lint.rs:128:13 | LL | let Deprecated | ^^^^^^^^^^ error: use of deprecated struct `deprecation_lint::Deprecated2`: text - --> $DIR/deprecation-lint.rs:133:17 + --> $DIR/deprecation-lint.rs:132:17 | LL | let x = Deprecated2(1, 2, 3); | ^^^^^^^^^^^ error: use of deprecated struct `deprecation_lint::Deprecated2`: text - --> $DIR/deprecation-lint.rs:143:13 + --> $DIR/deprecation-lint.rs:142:13 | LL | let Deprecated2 | ^^^^^^^^^^^ error: use of deprecated struct `deprecation_lint::Deprecated2`: text - --> $DIR/deprecation-lint.rs:152:13 + --> $DIR/deprecation-lint.rs:151:13 | LL | let Deprecated2 | ^^^^^^^^^^^ error: use of deprecated function `deprecation_lint::deprecated_mod::deprecated`: text - --> $DIR/deprecation-lint.rs:163:9 + --> $DIR/deprecation-lint.rs:162:9 | LL | deprecated_mod::deprecated(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated function `this_crate::deprecated`: text - --> $DIR/deprecation-lint.rs:246:9 + --> $DIR/deprecation-lint.rs:245:9 | LL | deprecated(); | ^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:251:9 + --> $DIR/deprecation-lint.rs:250:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:253:9 + --> $DIR/deprecation-lint.rs:252:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated function `this_crate::deprecated_text`: text - --> $DIR/deprecation-lint.rs:255:9 + --> $DIR/deprecation-lint.rs:254:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:260:9 + --> $DIR/deprecation-lint.rs:259:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:262:9 + --> $DIR/deprecation-lint.rs:261:9 | LL | ... ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated function `this_crate::deprecated_future`: text - --> $DIR/deprecation-lint.rs:265:9 + --> $DIR/deprecation-lint.rs:264:9 | LL | deprecated_future(); | ^^^^^^^^^^^^^^^^^ error: use of deprecated function `this_crate::deprecated_future_text`: text - --> $DIR/deprecation-lint.rs:266:9 + --> $DIR/deprecation-lint.rs:265:9 | LL | deprecated_future_text(); | ^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated struct `this_crate::DeprecatedStruct`: text - --> $DIR/deprecation-lint.rs:268:17 + --> $DIR/deprecation-lint.rs:267:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ error: use of deprecated unit struct `this_crate::DeprecatedUnitStruct`: text - --> $DIR/deprecation-lint.rs:273:17 + --> $DIR/deprecation-lint.rs:272:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ error: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text - --> $DIR/deprecation-lint.rs:275:17 + --> $DIR/deprecation-lint.rs:274:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text - --> $DIR/deprecation-lint.rs:277:17 + --> $DIR/deprecation-lint.rs:276:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated struct `this_crate::nested::DeprecatedStruct`: text - --> $DIR/deprecation-lint.rs:279:17 + --> $DIR/deprecation-lint.rs:278:17 | LL | let _ = nested::DeprecatedStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated unit struct `this_crate::nested::DeprecatedUnitStruct`: text - --> $DIR/deprecation-lint.rs:284:17 + --> $DIR/deprecation-lint.rs:283:17 | LL | let _ = nested::DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated unit variant `this_crate::nested::Enum::DeprecatedVariant`: text - --> $DIR/deprecation-lint.rs:286:17 + --> $DIR/deprecation-lint.rs:285:17 | LL | ... let _ = nested::Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated tuple struct `this_crate::nested::DeprecatedTupleStruct`: text - --> $DIR/deprecation-lint.rs:288:17 + --> $DIR/deprecation-lint.rs:287:17 | LL | ... let _ = nested::DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:293:9 + --> $DIR/deprecation-lint.rs:292:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:295:9 + --> $DIR/deprecation-lint.rs:294:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:297:9 + --> $DIR/deprecation-lint.rs:296:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:299:9 + --> $DIR/deprecation-lint.rs:298:9 | LL | ... ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated function `this_crate::test_fn_closure_body::{closure#0}::bar` - --> $DIR/deprecation-lint.rs:317:13 + --> $DIR/deprecation-lint.rs:316:13 | LL | bar(); | ^^^ error: use of deprecated trait `this_crate::DeprecatedTrait`: text - --> $DIR/deprecation-lint.rs:336:10 + --> $DIR/deprecation-lint.rs:335:10 | LL | impl DeprecatedTrait for S { } | ^^^^^^^^^^^^^^^ error: use of deprecated trait `this_crate::DeprecatedTrait`: text - --> $DIR/deprecation-lint.rs:338:24 + --> $DIR/deprecation-lint.rs:337:24 | LL | trait LocalTrait : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ error: use of deprecated struct `this_crate2::Deprecated`: text - --> $DIR/deprecation-lint.rs:390:17 + --> $DIR/deprecation-lint.rs:389:17 | LL | let x = Deprecated { | ^^^^^^^^^^ error: use of deprecated struct `this_crate2::Deprecated`: text - --> $DIR/deprecation-lint.rs:399:13 + --> $DIR/deprecation-lint.rs:398:13 | LL | let Deprecated { | ^^^^^^^^^^ error: use of deprecated struct `this_crate2::Deprecated`: text - --> $DIR/deprecation-lint.rs:405:13 + --> $DIR/deprecation-lint.rs:404:13 | LL | let Deprecated | ^^^^^^^^^^ error: use of deprecated tuple struct `this_crate2::Deprecated2`: text - --> $DIR/deprecation-lint.rs:410:17 + --> $DIR/deprecation-lint.rs:409:17 | LL | let x = Deprecated2(1, 2, 3); | ^^^^^^^^^^^ error: use of deprecated tuple struct `this_crate2::Deprecated2`: text - --> $DIR/deprecation-lint.rs:420:13 + --> $DIR/deprecation-lint.rs:419:13 | LL | let Deprecated2 | ^^^^^^^^^^^ error: use of deprecated tuple struct `this_crate2::Deprecated2`: text - --> $DIR/deprecation-lint.rs:429:13 + --> $DIR/deprecation-lint.rs:428:13 | LL | let Deprecated2 | ^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text - --> $DIR/deprecation-lint.rs:18:13 + --> $DIR/deprecation-lint.rs:17:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text - --> $DIR/deprecation-lint.rs:19:9 + --> $DIR/deprecation-lint.rs:18:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text - --> $DIR/deprecation-lint.rs:20:9 + --> $DIR/deprecation-lint.rs:19:9 | LL | ::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:21:13 + --> $DIR/deprecation-lint.rs:20:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:23:9 + --> $DIR/deprecation-lint.rs:22:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text - --> $DIR/deprecation-lint.rs:27:13 + --> $DIR/deprecation-lint.rs:26:13 | LL | ... foo.method_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text - --> $DIR/deprecation-lint.rs:28:9 + --> $DIR/deprecation-lint.rs:27:9 | LL | ... Foo::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text - --> $DIR/deprecation-lint.rs:29:9 + --> $DIR/deprecation-lint.rs:28:9 | LL | ... ::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:30:13 + --> $DIR/deprecation-lint.rs:29:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:32:9 + --> $DIR/deprecation-lint.rs:31:9 | LL | ... ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated field `deprecation_lint::DeprecatedStruct::i`: text - --> $DIR/deprecation-lint.rs:36:13 + --> $DIR/deprecation-lint.rs:35:13 | LL | i: 0 | ^^^^ error: use of deprecated field `deprecation_lint::nested::DeprecatedStruct::i`: text - --> $DIR/deprecation-lint.rs:46:13 + --> $DIR/deprecation-lint.rs:45:13 | LL | i: 0 | ^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:65:13 + --> $DIR/deprecation-lint.rs:64:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:67:9 + --> $DIR/deprecation-lint.rs:66:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:69:13 + --> $DIR/deprecation-lint.rs:68:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:71:9 + --> $DIR/deprecation-lint.rs:70:9 | LL | ... ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:76:13 + --> $DIR/deprecation-lint.rs:75:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:77:13 + --> $DIR/deprecation-lint.rs:76:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated field `deprecation_lint::Stable::override2`: text - --> $DIR/deprecation-lint.rs:87:13 + --> $DIR/deprecation-lint.rs:86:13 | LL | override2: 3, | ^^^^^^^^^^^^ error: use of deprecated field `deprecation_lint::Stable::override2`: text - --> $DIR/deprecation-lint.rs:91:17 + --> $DIR/deprecation-lint.rs:90:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ error: use of deprecated field `deprecation_lint::Stable::override2`: text - --> $DIR/deprecation-lint.rs:95:13 + --> $DIR/deprecation-lint.rs:94:13 | LL | override2: _ | ^^^^^^^^^^^^ error: use of deprecated field `deprecation_lint::Stable2::2`: text - --> $DIR/deprecation-lint.rs:103:17 + --> $DIR/deprecation-lint.rs:102:17 | LL | let _ = x.2; | ^^^ error: use of deprecated field `deprecation_lint::Stable2::2`: text - --> $DIR/deprecation-lint.rs:108:20 + --> $DIR/deprecation-lint.rs:107:20 | LL | _) | ^ error: use of deprecated field `deprecation_lint::Deprecated::inherit`: text - --> $DIR/deprecation-lint.rs:116:13 + --> $DIR/deprecation-lint.rs:115:13 | LL | inherit: 1, | ^^^^^^^^^^ error: use of deprecated field `deprecation_lint::Deprecated::inherit`: text - --> $DIR/deprecation-lint.rs:120:17 + --> $DIR/deprecation-lint.rs:119:17 | LL | let _ = x.inherit; | ^^^^^^^^^ error: use of deprecated field `deprecation_lint::Deprecated::inherit`: text - --> $DIR/deprecation-lint.rs:125:13 + --> $DIR/deprecation-lint.rs:124:13 | LL | inherit: _, | ^^^^^^^^^^ error: use of deprecated field `deprecation_lint::Deprecated2::0`: text - --> $DIR/deprecation-lint.rs:136:17 + --> $DIR/deprecation-lint.rs:135:17 | LL | let _ = x.0; | ^^^ error: use of deprecated field `deprecation_lint::Deprecated2::1`: text - --> $DIR/deprecation-lint.rs:138:17 + --> $DIR/deprecation-lint.rs:137:17 | LL | let _ = x.1; | ^^^ error: use of deprecated field `deprecation_lint::Deprecated2::2`: text - --> $DIR/deprecation-lint.rs:140:17 + --> $DIR/deprecation-lint.rs:139:17 | LL | let _ = x.2; | ^^^ error: use of deprecated field `deprecation_lint::Deprecated2::0`: text - --> $DIR/deprecation-lint.rs:145:14 + --> $DIR/deprecation-lint.rs:144:14 | LL | (_, | ^ error: use of deprecated field `deprecation_lint::Deprecated2::1`: text - --> $DIR/deprecation-lint.rs:147:14 + --> $DIR/deprecation-lint.rs:146:14 | LL | _, | ^ error: use of deprecated field `deprecation_lint::Deprecated2::2`: text - --> $DIR/deprecation-lint.rs:149:14 + --> $DIR/deprecation-lint.rs:148:14 | LL | _) | ^ error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text - --> $DIR/deprecation-lint.rs:247:13 + --> $DIR/deprecation-lint.rs:246:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text - --> $DIR/deprecation-lint.rs:248:9 + --> $DIR/deprecation-lint.rs:247:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text - --> $DIR/deprecation-lint.rs:249:9 + --> $DIR/deprecation-lint.rs:248:9 | LL | ::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:250:13 + --> $DIR/deprecation-lint.rs:249:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:252:9 + --> $DIR/deprecation-lint.rs:251:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text - --> $DIR/deprecation-lint.rs:256:13 + --> $DIR/deprecation-lint.rs:255:13 | LL | ... foo.method_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text - --> $DIR/deprecation-lint.rs:257:9 + --> $DIR/deprecation-lint.rs:256:9 | LL | ... Foo::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text - --> $DIR/deprecation-lint.rs:258:9 + --> $DIR/deprecation-lint.rs:257:9 | LL | ... ::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:259:13 + --> $DIR/deprecation-lint.rs:258:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:261:9 + --> $DIR/deprecation-lint.rs:260:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated field `this_crate::DeprecatedStruct::i`: text - --> $DIR/deprecation-lint.rs:270:13 + --> $DIR/deprecation-lint.rs:269:13 | LL | i: 0 | ^^^^ error: use of deprecated field `this_crate::nested::DeprecatedStruct::i`: text - --> $DIR/deprecation-lint.rs:281:13 + --> $DIR/deprecation-lint.rs:280:13 | LL | i: 0 | ^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:292:13 + --> $DIR/deprecation-lint.rs:291:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:294:9 + --> $DIR/deprecation-lint.rs:293:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:296:13 + --> $DIR/deprecation-lint.rs:295:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:298:9 + --> $DIR/deprecation-lint.rs:297:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/deprecation-lint.rs:303:13 + --> $DIR/deprecation-lint.rs:302:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/deprecation-lint.rs:304:13 + --> $DIR/deprecation-lint.rs:303:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated field `this_crate2::Stable::override2`: text - --> $DIR/deprecation-lint.rs:363:13 + --> $DIR/deprecation-lint.rs:362:13 | LL | override2: 3, | ^^^^^^^^^^^^ error: use of deprecated field `this_crate2::Stable::override2`: text - --> $DIR/deprecation-lint.rs:367:17 + --> $DIR/deprecation-lint.rs:366:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ error: use of deprecated field `this_crate2::Stable::override2`: text - --> $DIR/deprecation-lint.rs:371:13 + --> $DIR/deprecation-lint.rs:370:13 | LL | override2: _ | ^^^^^^^^^^^^ error: use of deprecated field `this_crate2::Stable2::2`: text - --> $DIR/deprecation-lint.rs:379:17 + --> $DIR/deprecation-lint.rs:378:17 | LL | let _ = x.2; | ^^^ error: use of deprecated field `this_crate2::Stable2::2`: text - --> $DIR/deprecation-lint.rs:384:20 + --> $DIR/deprecation-lint.rs:383:20 | LL | _) | ^ error: use of deprecated field `this_crate2::Deprecated::inherit`: text - --> $DIR/deprecation-lint.rs:392:13 + --> $DIR/deprecation-lint.rs:391:13 | LL | inherit: 1, | ^^^^^^^^^^ error: use of deprecated field `this_crate2::Deprecated::inherit`: text - --> $DIR/deprecation-lint.rs:396:17 + --> $DIR/deprecation-lint.rs:395:17 | LL | let _ = x.inherit; | ^^^^^^^^^ error: use of deprecated field `this_crate2::Deprecated::inherit`: text - --> $DIR/deprecation-lint.rs:401:13 + --> $DIR/deprecation-lint.rs:400:13 | LL | inherit: _, | ^^^^^^^^^^ error: use of deprecated field `this_crate2::Deprecated2::0`: text - --> $DIR/deprecation-lint.rs:413:17 + --> $DIR/deprecation-lint.rs:412:17 | LL | let _ = x.0; | ^^^ error: use of deprecated field `this_crate2::Deprecated2::1`: text - --> $DIR/deprecation-lint.rs:415:17 + --> $DIR/deprecation-lint.rs:414:17 | LL | let _ = x.1; | ^^^ error: use of deprecated field `this_crate2::Deprecated2::2`: text - --> $DIR/deprecation-lint.rs:417:17 + --> $DIR/deprecation-lint.rs:416:17 | LL | let _ = x.2; | ^^^ error: use of deprecated field `this_crate2::Deprecated2::0`: text - --> $DIR/deprecation-lint.rs:422:14 + --> $DIR/deprecation-lint.rs:421:14 | LL | (_, | ^ error: use of deprecated field `this_crate2::Deprecated2::1`: text - --> $DIR/deprecation-lint.rs:424:14 + --> $DIR/deprecation-lint.rs:423:14 | LL | _, | ^ error: use of deprecated field `this_crate2::Deprecated2::2`: text - --> $DIR/deprecation-lint.rs:426:14 + --> $DIR/deprecation-lint.rs:425:14 | LL | _) | ^ diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.rs b/src/test/ui/deprecation/rustc_deprecation-in-future.rs index 11f7960b757..3715f8eb225 100644 --- a/src/test/ui/deprecation/rustc_deprecation-in-future.rs +++ b/src/test/ui/deprecation/rustc_deprecation-in-future.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![deny(deprecated_in_future)] #![feature(staged_api)] diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr index b5a7dd3c28d..1c3339a8a9d 100644 --- a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr +++ b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr @@ -1,17 +1,17 @@ error: use of unit struct `S1` that will be deprecated in future version 99.99.99: effectively never - --> $DIR/rustc_deprecation-in-future.rs:18:13 + --> $DIR/rustc_deprecation-in-future.rs:16:13 | LL | let _ = S1; | ^^ | note: the lint level is defined here - --> $DIR/rustc_deprecation-in-future.rs:3:9 + --> $DIR/rustc_deprecation-in-future.rs:1:9 | LL | #![deny(deprecated_in_future)] | ^^^^^^^^^^^^^^^^^^^^ error: use of unit struct `S2` that will be deprecated in a future Rust version: literally never - --> $DIR/rustc_deprecation-in-future.rs:19:13 + --> $DIR/rustc_deprecation-in-future.rs:17:13 | LL | let _ = S2; | ^^ diff --git a/src/test/ui/error-codes/E0063.rs b/src/test/ui/error-codes/E0063.rs index 58527cc0c5d..48c9c13f018 100644 --- a/src/test/ui/error-codes/E0063.rs +++ b/src/test/ui/error-codes/E0063.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - struct SingleFoo { x: i32 } diff --git a/src/test/ui/error-codes/E0063.stderr b/src/test/ui/error-codes/E0063.stderr index 5dc4927071b..235e204025a 100644 --- a/src/test/ui/error-codes/E0063.stderr +++ b/src/test/ui/error-codes/E0063.stderr @@ -1,23 +1,23 @@ error[E0063]: missing field `x` in initializer of `SingleFoo` - --> $DIR/E0063.rs:32:13 + --> $DIR/E0063.rs:30:13 | LL | let w = SingleFoo { }; | ^^^^^^^^^ missing `x` error[E0063]: missing fields `y` and `z` in initializer of `PluralFoo` - --> $DIR/E0063.rs:34:13 + --> $DIR/E0063.rs:32:13 | LL | let x = PluralFoo {x: 1}; | ^^^^^^^^^ missing `y` and `z` error[E0063]: missing fields `a`, `b`, `y` and 1 other field in initializer of `TruncatedFoo` - --> $DIR/E0063.rs:36:13 + --> $DIR/E0063.rs:34:13 | LL | let y = TruncatedFoo{x:1}; | ^^^^^^^^^^^^ missing `a`, `b`, `y` and 1 other field error[E0063]: missing fields `a`, `b`, `c` and 2 other fields in initializer of `TruncatedPluralFoo` - --> $DIR/E0063.rs:38:13 + --> $DIR/E0063.rs:36:13 | LL | let z = TruncatedPluralFoo{x:1}; | ^^^^^^^^^^^^^^^^^^ missing `a`, `b`, `c` and 2 other fields diff --git a/src/test/ui/export-fully-qualified.rs b/src/test/ui/export-fully-qualified.rs index 40f26c7095f..4e73a2c5488 100644 --- a/src/test/ui/export-fully-qualified.rs +++ b/src/test/ui/export-fully-qualified.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // In this test baz isn't resolved when called as foo.baz even though // it's called from inside foo. This is somewhat surprising and may // want to change eventually. diff --git a/src/test/ui/export-fully-qualified.stderr b/src/test/ui/export-fully-qualified.stderr index a8af0c7c9b8..7ee352e1232 100644 --- a/src/test/ui/export-fully-qualified.stderr +++ b/src/test/ui/export-fully-qualified.stderr @@ -1,5 +1,5 @@ error[E0433]: failed to resolve: use of undeclared crate or module `foo` - --> $DIR/export-fully-qualified.rs:8:20 + --> $DIR/export-fully-qualified.rs:6:20 | LL | pub fn bar() { foo::baz(); } | ^^^ use of undeclared crate or module `foo` diff --git a/src/test/ui/feature-gates/feature-gate-abi.rs b/src/test/ui/feature-gates/feature-gate-abi.rs index 31f09cc61f9..3883106a3af 100644 --- a/src/test/ui/feature-gates/feature-gate-abi.rs +++ b/src/test/ui/feature-gates/feature-gate-abi.rs @@ -1,5 +1,4 @@ // only-x86_64 -// ignore-tidy-linelength // gate-test-intrinsics // gate-test-platform_intrinsics // gate-test-abi_vectorcall diff --git a/src/test/ui/feature-gates/feature-gate-abi.stderr b/src/test/ui/feature-gates/feature-gate-abi.stderr index 25f0c259d11..eeeb349c662 100644 --- a/src/test/ui/feature-gates/feature-gate-abi.stderr +++ b/src/test/ui/feature-gates/feature-gate-abi.stderr @@ -1,5 +1,5 @@ error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:13:8 + --> $DIR/feature-gate-abi.rs:12:8 | LL | extern "rust-intrinsic" fn f1() {} | ^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | extern "rust-intrinsic" fn f1() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:15:8 + --> $DIR/feature-gate-abi.rs:14:8 | LL | extern "platform-intrinsic" fn f2() {} | ^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | extern "platform-intrinsic" fn f2() {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:17:8 + --> $DIR/feature-gate-abi.rs:16:8 | LL | extern "vectorcall" fn f3() {} | ^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | extern "vectorcall" fn f3() {} = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:18:8 + --> $DIR/feature-gate-abi.rs:17:8 | LL | extern "rust-call" fn f4(_: ()) {} | ^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | extern "rust-call" fn f4(_: ()) {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:19:8 + --> $DIR/feature-gate-abi.rs:18:8 | LL | extern "msp430-interrupt" fn f5() {} | ^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | extern "msp430-interrupt" fn f5() {} = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:20:8 + --> $DIR/feature-gate-abi.rs:19:8 | LL | extern "ptx-kernel" fn f6() {} | ^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | extern "ptx-kernel" fn f6() {} = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:21:8 + --> $DIR/feature-gate-abi.rs:20:8 | LL | extern "x86-interrupt" fn f7() {} | ^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | extern "x86-interrupt" fn f7() {} = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:22:8 + --> $DIR/feature-gate-abi.rs:21:8 | LL | extern "thiscall" fn f8() {} | ^^^^^^^^^^ @@ -68,7 +68,7 @@ LL | extern "thiscall" fn f8() {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:23:8 + --> $DIR/feature-gate-abi.rs:22:8 | LL | extern "amdgpu-kernel" fn f9() {} | ^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL | extern "amdgpu-kernel" fn f9() {} = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:24:8 + --> $DIR/feature-gate-abi.rs:23:8 | LL | extern "efiapi" fn f10() {} | ^^^^^^^^ @@ -86,7 +86,7 @@ LL | extern "efiapi" fn f10() {} = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:28:12 + --> $DIR/feature-gate-abi.rs:27:12 | LL | extern "rust-intrinsic" fn m1(); | ^^^^^^^^^^^^^^^^ @@ -94,7 +94,7 @@ LL | extern "rust-intrinsic" fn m1(); = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:30:12 + --> $DIR/feature-gate-abi.rs:29:12 | LL | extern "platform-intrinsic" fn m2(); | ^^^^^^^^^^^^^^^^^^^^ @@ -103,7 +103,7 @@ LL | extern "platform-intrinsic" fn m2(); = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:32:12 + --> $DIR/feature-gate-abi.rs:31:12 | LL | extern "vectorcall" fn m3(); | ^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | extern "vectorcall" fn m3(); = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:33:12 + --> $DIR/feature-gate-abi.rs:32:12 | LL | extern "rust-call" fn m4(_: ()); | ^^^^^^^^^^^ @@ -120,7 +120,7 @@ LL | extern "rust-call" fn m4(_: ()); = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:34:12 + --> $DIR/feature-gate-abi.rs:33:12 | LL | extern "msp430-interrupt" fn m5(); | ^^^^^^^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL | extern "msp430-interrupt" fn m5(); = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:35:12 + --> $DIR/feature-gate-abi.rs:34:12 | LL | extern "ptx-kernel" fn m6(); | ^^^^^^^^^^^^ @@ -138,7 +138,7 @@ LL | extern "ptx-kernel" fn m6(); = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:36:12 + --> $DIR/feature-gate-abi.rs:35:12 | LL | extern "x86-interrupt" fn m7(); | ^^^^^^^^^^^^^^^ @@ -147,7 +147,7 @@ LL | extern "x86-interrupt" fn m7(); = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:37:12 + --> $DIR/feature-gate-abi.rs:36:12 | LL | extern "thiscall" fn m8(); | ^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | extern "thiscall" fn m8(); = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:38:12 + --> $DIR/feature-gate-abi.rs:37:12 | LL | extern "amdgpu-kernel" fn m9(); | ^^^^^^^^^^^^^^^ @@ -164,7 +164,7 @@ LL | extern "amdgpu-kernel" fn m9(); = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:39:12 + --> $DIR/feature-gate-abi.rs:38:12 | LL | extern "efiapi" fn m10(); | ^^^^^^^^ @@ -173,7 +173,7 @@ LL | extern "efiapi" fn m10(); = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:41:12 + --> $DIR/feature-gate-abi.rs:40:12 | LL | extern "vectorcall" fn dm3() {} | ^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL | extern "vectorcall" fn dm3() {} = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:42:12 + --> $DIR/feature-gate-abi.rs:41:12 | LL | extern "rust-call" fn dm4(_: ()) {} | ^^^^^^^^^^^ @@ -190,7 +190,7 @@ LL | extern "rust-call" fn dm4(_: ()) {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:43:12 + --> $DIR/feature-gate-abi.rs:42:12 | LL | extern "msp430-interrupt" fn dm5() {} | ^^^^^^^^^^^^^^^^^^ @@ -199,7 +199,7 @@ LL | extern "msp430-interrupt" fn dm5() {} = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:44:12 + --> $DIR/feature-gate-abi.rs:43:12 | LL | extern "ptx-kernel" fn dm6() {} | ^^^^^^^^^^^^ @@ -208,7 +208,7 @@ LL | extern "ptx-kernel" fn dm6() {} = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:45:12 + --> $DIR/feature-gate-abi.rs:44:12 | LL | extern "x86-interrupt" fn dm7() {} | ^^^^^^^^^^^^^^^ @@ -217,7 +217,7 @@ LL | extern "x86-interrupt" fn dm7() {} = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:46:12 + --> $DIR/feature-gate-abi.rs:45:12 | LL | extern "thiscall" fn dm8() {} | ^^^^^^^^^^ @@ -225,7 +225,7 @@ LL | extern "thiscall" fn dm8() {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:47:12 + --> $DIR/feature-gate-abi.rs:46:12 | LL | extern "amdgpu-kernel" fn dm9() {} | ^^^^^^^^^^^^^^^ @@ -234,7 +234,7 @@ LL | extern "amdgpu-kernel" fn dm9() {} = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:48:12 + --> $DIR/feature-gate-abi.rs:47:12 | LL | extern "efiapi" fn dm10() {} | ^^^^^^^^ @@ -243,7 +243,7 @@ LL | extern "efiapi" fn dm10() {} = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:55:12 + --> $DIR/feature-gate-abi.rs:54:12 | LL | extern "rust-intrinsic" fn m1() {} | ^^^^^^^^^^^^^^^^ @@ -251,7 +251,7 @@ LL | extern "rust-intrinsic" fn m1() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:57:12 + --> $DIR/feature-gate-abi.rs:56:12 | LL | extern "platform-intrinsic" fn m2() {} | ^^^^^^^^^^^^^^^^^^^^ @@ -260,7 +260,7 @@ LL | extern "platform-intrinsic" fn m2() {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:59:12 + --> $DIR/feature-gate-abi.rs:58:12 | LL | extern "vectorcall" fn m3() {} | ^^^^^^^^^^^^ @@ -268,7 +268,7 @@ LL | extern "vectorcall" fn m3() {} = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:60:12 + --> $DIR/feature-gate-abi.rs:59:12 | LL | extern "rust-call" fn m4(_: ()) {} | ^^^^^^^^^^^ @@ -277,7 +277,7 @@ LL | extern "rust-call" fn m4(_: ()) {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:61:12 + --> $DIR/feature-gate-abi.rs:60:12 | LL | extern "msp430-interrupt" fn m5() {} | ^^^^^^^^^^^^^^^^^^ @@ -286,7 +286,7 @@ LL | extern "msp430-interrupt" fn m5() {} = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:62:12 + --> $DIR/feature-gate-abi.rs:61:12 | LL | extern "ptx-kernel" fn m6() {} | ^^^^^^^^^^^^ @@ -295,7 +295,7 @@ LL | extern "ptx-kernel" fn m6() {} = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:63:12 + --> $DIR/feature-gate-abi.rs:62:12 | LL | extern "x86-interrupt" fn m7() {} | ^^^^^^^^^^^^^^^ @@ -304,7 +304,7 @@ LL | extern "x86-interrupt" fn m7() {} = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:64:12 + --> $DIR/feature-gate-abi.rs:63:12 | LL | extern "thiscall" fn m8() {} | ^^^^^^^^^^ @@ -312,7 +312,7 @@ LL | extern "thiscall" fn m8() {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:65:12 + --> $DIR/feature-gate-abi.rs:64:12 | LL | extern "amdgpu-kernel" fn m9() {} | ^^^^^^^^^^^^^^^ @@ -321,7 +321,7 @@ LL | extern "amdgpu-kernel" fn m9() {} = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:66:12 + --> $DIR/feature-gate-abi.rs:65:12 | LL | extern "efiapi" fn m10() {} | ^^^^^^^^ @@ -330,7 +330,7 @@ LL | extern "efiapi" fn m10() {} = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:71:12 + --> $DIR/feature-gate-abi.rs:70:12 | LL | extern "rust-intrinsic" fn im1() {} | ^^^^^^^^^^^^^^^^ @@ -338,7 +338,7 @@ LL | extern "rust-intrinsic" fn im1() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:73:12 + --> $DIR/feature-gate-abi.rs:72:12 | LL | extern "platform-intrinsic" fn im2() {} | ^^^^^^^^^^^^^^^^^^^^ @@ -347,7 +347,7 @@ LL | extern "platform-intrinsic" fn im2() {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:75:12 + --> $DIR/feature-gate-abi.rs:74:12 | LL | extern "vectorcall" fn im3() {} | ^^^^^^^^^^^^ @@ -355,7 +355,7 @@ LL | extern "vectorcall" fn im3() {} = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:76:12 + --> $DIR/feature-gate-abi.rs:75:12 | LL | extern "rust-call" fn im4(_: ()) {} | ^^^^^^^^^^^ @@ -364,7 +364,7 @@ LL | extern "rust-call" fn im4(_: ()) {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:77:12 + --> $DIR/feature-gate-abi.rs:76:12 | LL | extern "msp430-interrupt" fn im5() {} | ^^^^^^^^^^^^^^^^^^ @@ -373,7 +373,7 @@ LL | extern "msp430-interrupt" fn im5() {} = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:78:12 + --> $DIR/feature-gate-abi.rs:77:12 | LL | extern "ptx-kernel" fn im6() {} | ^^^^^^^^^^^^ @@ -382,7 +382,7 @@ LL | extern "ptx-kernel" fn im6() {} = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:79:12 + --> $DIR/feature-gate-abi.rs:78:12 | LL | extern "x86-interrupt" fn im7() {} | ^^^^^^^^^^^^^^^ @@ -391,7 +391,7 @@ LL | extern "x86-interrupt" fn im7() {} = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:80:12 + --> $DIR/feature-gate-abi.rs:79:12 | LL | extern "thiscall" fn im8() {} | ^^^^^^^^^^ @@ -399,7 +399,7 @@ LL | extern "thiscall" fn im8() {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:81:12 + --> $DIR/feature-gate-abi.rs:80:12 | LL | extern "amdgpu-kernel" fn im9() {} | ^^^^^^^^^^^^^^^ @@ -408,7 +408,7 @@ LL | extern "amdgpu-kernel" fn im9() {} = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:82:12 + --> $DIR/feature-gate-abi.rs:81:12 | LL | extern "efiapi" fn im10() {} | ^^^^^^^^ @@ -417,7 +417,7 @@ LL | extern "efiapi" fn im10() {} = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:86:18 + --> $DIR/feature-gate-abi.rs:85:18 | LL | type A1 = extern "rust-intrinsic" fn(); | ^^^^^^^^^^^^^^^^ @@ -425,7 +425,7 @@ LL | type A1 = extern "rust-intrinsic" fn(); = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:87:18 + --> $DIR/feature-gate-abi.rs:86:18 | LL | type A2 = extern "platform-intrinsic" fn(); | ^^^^^^^^^^^^^^^^^^^^ @@ -434,7 +434,7 @@ LL | type A2 = extern "platform-intrinsic" fn(); = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:88:18 + --> $DIR/feature-gate-abi.rs:87:18 | LL | type A3 = extern "vectorcall" fn(); | ^^^^^^^^^^^^ @@ -442,7 +442,7 @@ LL | type A3 = extern "vectorcall" fn(); = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:89:18 + --> $DIR/feature-gate-abi.rs:88:18 | LL | type A4 = extern "rust-call" fn(_: ()); | ^^^^^^^^^^^ @@ -451,7 +451,7 @@ LL | type A4 = extern "rust-call" fn(_: ()); = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:90:18 + --> $DIR/feature-gate-abi.rs:89:18 | LL | type A5 = extern "msp430-interrupt" fn(); | ^^^^^^^^^^^^^^^^^^ @@ -460,7 +460,7 @@ LL | type A5 = extern "msp430-interrupt" fn(); = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:91:18 + --> $DIR/feature-gate-abi.rs:90:18 | LL | type A6 = extern "ptx-kernel" fn (); | ^^^^^^^^^^^^ @@ -469,7 +469,7 @@ LL | type A6 = extern "ptx-kernel" fn (); = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:92:18 + --> $DIR/feature-gate-abi.rs:91:18 | LL | type A7 = extern "x86-interrupt" fn(); | ^^^^^^^^^^^^^^^ @@ -478,7 +478,7 @@ LL | type A7 = extern "x86-interrupt" fn(); = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:93:18 + --> $DIR/feature-gate-abi.rs:92:18 | LL | type A8 = extern "thiscall" fn(); | ^^^^^^^^^^ @@ -486,7 +486,7 @@ LL | type A8 = extern "thiscall" fn(); = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:94:18 + --> $DIR/feature-gate-abi.rs:93:18 | LL | type A9 = extern "amdgpu-kernel" fn(); | ^^^^^^^^^^^^^^^ @@ -495,7 +495,7 @@ LL | type A9 = extern "amdgpu-kernel" fn(); = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:95:19 + --> $DIR/feature-gate-abi.rs:94:19 | LL | type A10 = extern "efiapi" fn(); | ^^^^^^^^ @@ -504,7 +504,7 @@ LL | type A10 = extern "efiapi" fn(); = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:98:8 + --> $DIR/feature-gate-abi.rs:97:8 | LL | extern "rust-intrinsic" {} | ^^^^^^^^^^^^^^^^ @@ -512,7 +512,7 @@ LL | extern "rust-intrinsic" {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable error[E0658]: platform intrinsics are experimental and possibly buggy - --> $DIR/feature-gate-abi.rs:99:8 + --> $DIR/feature-gate-abi.rs:98:8 | LL | extern "platform-intrinsic" {} | ^^^^^^^^^^^^^^^^^^^^ @@ -521,7 +521,7 @@ LL | extern "platform-intrinsic" {} = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable error[E0658]: vectorcall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:100:8 + --> $DIR/feature-gate-abi.rs:99:8 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^ @@ -529,7 +529,7 @@ LL | extern "vectorcall" {} = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:101:8 + --> $DIR/feature-gate-abi.rs:100:8 | LL | extern "rust-call" {} | ^^^^^^^^^^^ @@ -538,7 +538,7 @@ LL | extern "rust-call" {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: msp430-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:102:8 + --> $DIR/feature-gate-abi.rs:101:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ @@ -547,7 +547,7 @@ LL | extern "msp430-interrupt" {} = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable error[E0658]: PTX ABIs are experimental and subject to change - --> $DIR/feature-gate-abi.rs:103:8 + --> $DIR/feature-gate-abi.rs:102:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ @@ -556,7 +556,7 @@ LL | extern "ptx-kernel" {} = help: add `#![feature(abi_ptx)]` to the crate attributes to enable error[E0658]: x86-interrupt ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:104:8 + --> $DIR/feature-gate-abi.rs:103:8 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^ @@ -565,7 +565,7 @@ LL | extern "x86-interrupt" {} = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable error[E0658]: thiscall is experimental and subject to change - --> $DIR/feature-gate-abi.rs:105:8 + --> $DIR/feature-gate-abi.rs:104:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ @@ -573,7 +573,7 @@ LL | extern "thiscall" {} = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable error[E0658]: amdgpu-kernel ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:106:8 + --> $DIR/feature-gate-abi.rs:105:8 | LL | extern "amdgpu-kernel" {} | ^^^^^^^^^^^^^^^ @@ -582,7 +582,7 @@ LL | extern "amdgpu-kernel" {} = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable error[E0658]: efiapi ABI is experimental and subject to change - --> $DIR/feature-gate-abi.rs:107:8 + --> $DIR/feature-gate-abi.rs:106:8 | LL | extern "efiapi" {} | ^^^^^^^^ @@ -591,49 +591,49 @@ LL | extern "efiapi" {} = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:28:32 + --> $DIR/feature-gate-abi.rs:27:32 | LL | extern "rust-intrinsic" fn m1(); | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:30:36 + --> $DIR/feature-gate-abi.rs:29:36 | LL | extern "platform-intrinsic" fn m2(); | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:13:33 + --> $DIR/feature-gate-abi.rs:12:33 | LL | extern "rust-intrinsic" fn f1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:15:37 + --> $DIR/feature-gate-abi.rs:14:37 | LL | extern "platform-intrinsic" fn f2() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:55:37 + --> $DIR/feature-gate-abi.rs:54:37 | LL | extern "rust-intrinsic" fn m1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:57:41 + --> $DIR/feature-gate-abi.rs:56:41 | LL | extern "platform-intrinsic" fn m2() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:71:38 + --> $DIR/feature-gate-abi.rs:70:38 | LL | extern "rust-intrinsic" fn im1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:73:42 + --> $DIR/feature-gate-abi.rs:72:42 | LL | extern "platform-intrinsic" fn im2() {} | ^^ diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs index 9f5c92349e0..04f816ea501 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // Test that `#[rustc_*]` attributes are gated by `rustc_attrs` feature gate. #[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr index 82dec1fd4cf..822368a5946 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr @@ -1,5 +1,5 @@ error[E0658]: the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable - --> $DIR/feature-gate-rustc-attrs-1.rs:5:1 + --> $DIR/feature-gate-rustc-attrs-1.rs:3:1 | LL | #[rustc_variance] | ^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[rustc_variance] = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error[E0658]: the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable - --> $DIR/feature-gate-rustc-attrs-1.rs:6:1 + --> $DIR/feature-gate-rustc-attrs-1.rs:4:1 | LL | #[rustc_error] | ^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | #[rustc_error] = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error[E0658]: the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable niche optimizations in libcore and will never be stable - --> $DIR/feature-gate-rustc-attrs-1.rs:7:1 + --> $DIR/feature-gate-rustc-attrs-1.rs:5:1 | LL | #[rustc_nonnull_optimization_guaranteed] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs index 6404b2c3115..07167fa695e 100644 --- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs +++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs @@ -8,7 +8,6 @@ // which would mess up the treatment of other cases in // issue-43106-gating-of-builtin-attrs.rs) -// ignore-tidy-linelength #![macro_export] //~^ ERROR: `macro_export` attribute cannot be used at crate level diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr index 3ca1bd2ea7e..33a5021cde4 100644 --- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr +++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr @@ -1,5 +1,5 @@ error: attribute must be of the form `#[inline]` or `#[inline(always|never)]` - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:41:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:40:5 | LL | #[inline = "2100"] fn f() { } | ^^^^^^^^^^^^^^^^^^ @@ -9,67 +9,67 @@ LL | #[inline = "2100"] fn f() { } = note: for more information, see issue #57571 error: `main` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:110:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:1 | LL | #[main] | ^^^^^^^ error: `main` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:112:17 | LL | mod inner { #![main] } | ^^^^^^^^ error: `main` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:118:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:117:5 | LL | #[main] struct S; | ^^^^^^^ error: `main` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:121:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:120:5 | LL | #[main] type T = S; | ^^^^^^^ error: `main` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:124:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:123:5 | LL | #[main] impl S { } | ^^^^^^^ error: `start` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:128:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:127:1 | LL | #[start] | ^^^^^^^^ error: `start` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:131:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:130:17 | LL | mod inner { #![start] } | ^^^^^^^^^ error: `start` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:136:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:135:5 | LL | #[start] struct S; | ^^^^^^^^ error: `start` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:139:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:138:5 | LL | #[start] type T = S; | ^^^^^^^^ error: `start` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:142:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:141:5 | LL | #[start] impl S { } | ^^^^^^^^ error[E0518]: attribute should be applied to function or closure - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:32:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:31:1 | LL | #[inline] | ^^^^^^^^^ @@ -84,7 +84,7 @@ LL | | } | |_- not a function or closure error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:60:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:59:1 | LL | #[no_link] | ^^^^^^^^^^ @@ -99,7 +99,7 @@ LL | | } | |_- not an `extern crate` item error: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:86:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:85:1 | LL | #[export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,133 +114,133 @@ LL | | } | |_- not a function or static error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:26:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1 | LL | #![no_link] | ^^^^^^^^^^^ error: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:28:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:27:1 | LL | #![export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0518]: attribute should be applied to function or closure - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:30:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:29:1 | LL | #![inline] | ^^^^^^^^^^ error: `macro_export` attribute cannot be used at crate level - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:13:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1 | LL | #![macro_export] | ^^^^^^^^^^^^^^^^ error: `main` attribute cannot be used at crate level - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:15:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:14:1 | LL | #![main] | ^^^^^^^^ error: `start` attribute cannot be used at crate level - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:17:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:16:1 | LL | #![start] | ^^^^^^^^^ error: `repr` attribute cannot be used at crate level - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:19:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:18:1 | LL | #![repr()] | ^^^^^^^^^^ error: `path` attribute cannot be used at crate level - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:21:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:20:1 | LL | #![path = "3800"] | ^^^^^^^^^^^^^^^^^ error: `automatically_derived` attribute cannot be used at crate level - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:23:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:22:1 | LL | #![automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0518]: attribute should be applied to function or closure - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:37:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:36:17 | LL | mod inner { #![inline] } | ------------^^^^^^^^^^-- not a function or closure error[E0518]: attribute should be applied to function or closure - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:47:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:46:5 | LL | #[inline] struct S; | ^^^^^^^^^ --------- not a function or closure error[E0518]: attribute should be applied to function or closure - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:51:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:50:5 | LL | #[inline] type T = S; | ^^^^^^^^^ ----------- not a function or closure error[E0518]: attribute should be applied to function or closure - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:55:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:54:5 | LL | #[inline] impl S { } | ^^^^^^^^^ ---------- not a function or closure error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:65:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:64:17 | LL | mod inner { #![no_link] } | ------------^^^^^^^^^^^-- not an `extern crate` item error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:69:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:68:5 | LL | #[no_link] fn f() { } | ^^^^^^^^^^ ---------- not an `extern crate` item error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:73:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:72:5 | LL | #[no_link] struct S; | ^^^^^^^^^^ --------- not an `extern crate` item error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:77:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:76:5 | LL | #[no_link]type T = S; | ^^^^^^^^^^----------- not an `extern crate` item error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:81:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:80:5 | LL | #[no_link] impl S { } | ^^^^^^^^^^ ---------- not an `extern crate` item error: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:91:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:90:17 | LL | mod inner { #![export_name="2200"] } | ------------^^^^^^^^^^^^^^^^^^^^^^-- not a function or static error: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:97:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:96:5 | LL | #[export_name = "2200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^ --------- not a function or static error: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:101:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:100:5 | LL | #[export_name = "2200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a function or static error: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:105:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:104:5 | LL | #[export_name = "2200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^ ---------- not a function or static diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index 21f40524f63..19a60f1bcff 100644 --- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -34,7 +34,6 @@ // occurrences in the source text. // check-pass -// ignore-tidy-linelength #![feature(test, plugin_registrar)] #![warn(unused_attributes, unknown_lints)] diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index c864ccc8686..c207c05455f 100644 --- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -1,179 +1,179 @@ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:53:9 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:52:9 | LL | #![warn(x5400)] | ^^^^^ | note: the lint level is defined here - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:40:28 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:39:28 | LL | #![warn(unused_attributes, unknown_lints)] | ^^^^^^^^^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:54:10 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:53:10 | LL | #![allow(x5300)] | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:11 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:54:11 | LL | #![forbid(x5200)] | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:56:9 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:9 | LL | #![deny(x5100)] | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:111:8 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:110:8 | LL | #[warn(x5400)] | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:114:25 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:113:25 | LL | mod inner { #![warn(x5400)] } | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:117:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:116:12 | LL | #[warn(x5400)] fn f() { } | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:120:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:119:12 | LL | #[warn(x5400)] struct S; | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:123:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:122:12 | LL | #[warn(x5400)] type T = S; | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:126:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:125:12 | LL | #[warn(x5400)] impl S { } | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:130:9 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:129:9 | LL | #[allow(x5300)] | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:133:26 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:132:26 | LL | mod inner { #![allow(x5300)] } | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:136:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:135:13 | LL | #[allow(x5300)] fn f() { } | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:139:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:138:13 | LL | #[allow(x5300)] struct S; | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:142:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:141:13 | LL | #[allow(x5300)] type T = S; | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:145:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:144:13 | LL | #[allow(x5300)] impl S { } | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:149:10 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:148:10 | LL | #[forbid(x5200)] | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:152:27 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:151:27 | LL | mod inner { #![forbid(x5200)] } | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:155:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:154:14 | LL | #[forbid(x5200)] fn f() { } | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:158:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:157:14 | LL | #[forbid(x5200)] struct S; | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:161:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:160:14 | LL | #[forbid(x5200)] type T = S; | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:164:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:163:14 | LL | #[forbid(x5200)] impl S { } | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:168:8 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:167:8 | LL | #[deny(x5100)] | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:171:25 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:170:25 | LL | mod inner { #![deny(x5100)] } | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:174:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:173:12 | LL | #[deny(x5100)] fn f() { } | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:177:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:176:12 | LL | #[deny(x5100)] struct S; | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:180:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:179:12 | LL | #[deny(x5100)] type T = S; | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:183:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:182:12 | LL | #[deny(x5100)] impl S { } | ^^^^^ warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:441:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:440:17 | LL | mod inner { #![macro_escape] } | ^^^^^^^^^^^^^^^^ @@ -181,13 +181,13 @@ LL | mod inner { #![macro_escape] } = help: try an outer attribute: `#[macro_use]` warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:438:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:437:1 | LL | #[macro_escape] | ^^^^^^^^^^^^^^^ warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:228:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:227:17 | LL | mod inner { #![plugin_registrar] } | ^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version @@ -195,49 +195,49 @@ LL | mod inner { #![plugin_registrar] } = note: `#[warn(deprecated)]` on by default warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:236:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:235:5 | LL | #[plugin_registrar] struct S; | ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:241:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:240:5 | LL | #[plugin_registrar] type T = S; | ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:246:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:245:5 | LL | #[plugin_registrar] impl S { } | ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:223:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:222:1 | LL | #[plugin_registrar] | ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:46:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:45:1 | LL | #![plugin_registrar] | ^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version warning: use of deprecated attribute `crate_id`: no longer used. - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:91:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:90:1 | LL | #![crate_id = "10"] | ^^^^^^^^^^^^^^^^^^^ help: remove this attribute warning: use of deprecated attribute `no_start`: no longer used. - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:100:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:99:1 | LL | #![no_start] | ^^^^^^^^^^^^ help: remove this attribute warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:333:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:332:1 | LL | #[no_mangle] | ^^^^^^^^^^^^ @@ -252,14 +252,14 @@ LL | | } | |_- not a function or static | note: the lint level is defined here - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:40:9 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:39:9 | LL | #![warn(unused_attributes, unknown_lints)] | ^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:500:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:499:1 | LL | #[cold] | ^^^^^^^ @@ -276,7 +276,7 @@ LL | | } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:529:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:528:1 | LL | #[link_name = "1900"] | ^^^^^^^^^^^^^^^^^^^^^ @@ -293,7 +293,7 @@ LL | | } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:568:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:567:1 | LL | #[link_section = "1800"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -310,7 +310,7 @@ LL | | } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:68:1 | LL | #![cold] | ^^^^^^^^ @@ -318,7 +318,7 @@ LL | #![cold] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:73:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:1 | LL | #![link_name = "1900"] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -326,7 +326,7 @@ LL | #![link_name = "1900"] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:76:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:75:1 | LL | #![link_section = "1800"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -334,7 +334,7 @@ LL | #![link_section = "1800"] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:338:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:337:17 | LL | mod inner { #![no_mangle] } | ------------^^^^^^^^^^^^^-- not a function or static @@ -342,7 +342,7 @@ LL | mod inner { #![no_mangle] } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:345:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:344:5 | LL | #[no_mangle] struct S; | ^^^^^^^^^^^^ --------- not a function or static @@ -350,7 +350,7 @@ LL | #[no_mangle] struct S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:350:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:349:5 | LL | #[no_mangle] type T = S; | ^^^^^^^^^^^^ ----------- not a function or static @@ -358,7 +358,7 @@ LL | #[no_mangle] type T = S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:355:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:354:5 | LL | #[no_mangle] impl S { } | ^^^^^^^^^^^^ ---------- not a function or static @@ -366,7 +366,7 @@ LL | #[no_mangle] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:506:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:505:17 | LL | mod inner { #![cold] } | ------------^^^^^^^^-- not a function @@ -374,7 +374,7 @@ LL | mod inner { #![cold] } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:513:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:5 | LL | #[cold] struct S; | ^^^^^^^ --------- not a function @@ -382,7 +382,7 @@ LL | #[cold] struct S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:518:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:517:5 | LL | #[cold] type T = S; | ^^^^^^^ ----------- not a function @@ -390,7 +390,7 @@ LL | #[cold] type T = S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:523:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:522:5 | LL | #[cold] impl S { } | ^^^^^^^ ---------- not a function @@ -398,7 +398,7 @@ LL | #[cold] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:535:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:534:5 | LL | #[link_name = "1900"] | ^^^^^^^^^^^^^^^^^^^^^ @@ -408,13 +408,13 @@ LL | extern "C" { } | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! help: try `#[link(name = "1900")]` instead - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:535:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:534:5 | LL | #[link_name = "1900"] | ^^^^^^^^^^^^^^^^^^^^^ warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:542:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:541:17 | LL | mod inner { #![link_name="1900"] } | ------------^^^^^^^^^^^^^^^^^^^^-- not a foreign function or static @@ -422,7 +422,7 @@ LL | mod inner { #![link_name="1900"] } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:546:5 | LL | #[link_name = "1900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^ ---------- not a foreign function or static @@ -430,7 +430,7 @@ LL | #[link_name = "1900"] fn f() { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:552:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:5 | LL | #[link_name = "1900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^ --------- not a foreign function or static @@ -438,7 +438,7 @@ LL | #[link_name = "1900"] struct S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:557:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:556:5 | LL | #[link_name = "1900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^ ----------- not a foreign function or static @@ -446,7 +446,7 @@ LL | #[link_name = "1900"] type T = S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:562:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:561:5 | LL | #[link_name = "1900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^ ---------- not a foreign function or static @@ -454,7 +454,7 @@ LL | #[link_name = "1900"] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:574:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:573:17 | LL | mod inner { #![link_section="1800"] } | ------------^^^^^^^^^^^^^^^^^^^^^^^-- not a function or static @@ -462,7 +462,7 @@ LL | mod inner { #![link_section="1800"] } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:581:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:580:5 | LL | #[link_section = "1800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^ --------- not a function or static @@ -470,7 +470,7 @@ LL | #[link_section = "1800"] struct S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:586:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:585:5 | LL | #[link_section = "1800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a function or static @@ -478,7 +478,7 @@ LL | #[link_section = "1800"] type T = S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:591:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:590:5 | LL | #[link_section = "1800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^ ---------- not a function or static @@ -486,7 +486,7 @@ LL | #[link_section = "1800"] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: the feature `rust1` has been stable since 1.0.0 and no longer requires an attribute to enable - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:96:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:95:12 | LL | #![feature(rust1)] | ^^^^^ @@ -494,847 +494,847 @@ LL | #![feature(rust1)] = note: `#[warn(stable_features)]` on by default warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:46:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:45:1 | LL | #![plugin_registrar] | ^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:60:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:59:1 | LL | #![should_panic] | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:61:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:60:1 | LL | #![ignore] | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:67:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1 | LL | #![proc_macro_derive()] | ^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:191:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:190:5 | LL | #[macro_use] fn f() { } | ^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:194:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:193:5 | LL | #[macro_use] struct S; | ^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:197:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:196:5 | LL | #[macro_use] type T = S; | ^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:200:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:199:5 | LL | #[macro_use] impl S { } | ^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:204:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:203:1 | LL | #[macro_export] | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:207:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:206:17 | LL | mod inner { #![macro_export] } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:210:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:209:5 | LL | #[macro_export] fn f() { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:213:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:212:5 | LL | #[macro_export] struct S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:216:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:215:5 | LL | #[macro_export] type T = S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:219:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:218:5 | LL | #[macro_export] impl S { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:223:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:222:1 | LL | #[plugin_registrar] | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:228:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:227:17 | LL | mod inner { #![plugin_registrar] } | ^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:236:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:235:5 | LL | #[plugin_registrar] struct S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:241:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:240:5 | LL | #[plugin_registrar] type T = S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:246:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:245:5 | LL | #[plugin_registrar] impl S { } | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:301:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:300:5 | LL | #[path = "3800"] fn f() { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:304:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:303:5 | LL | #[path = "3800"] struct S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:307:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:306:5 | LL | #[path = "3800"] type T = S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:310:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:309:5 | LL | #[path = "3800"] impl S { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:314:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:313:1 | LL | #[automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:317:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:316:17 | LL | mod inner { #![automatically_derived] } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:320:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:319:5 | LL | #[automatically_derived] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:323:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:322:5 | LL | #[automatically_derived] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:326:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:325:5 | LL | #[automatically_derived] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:329:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:328:5 | LL | #[automatically_derived] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:360:1 | LL | #[should_panic] | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:363:17 | LL | mod inner { #![should_panic] } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:367:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:366:5 | LL | #[should_panic] fn f() { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:370:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:369:5 | LL | #[should_panic] struct S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:373:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:372:5 | LL | #[should_panic] type T = S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:376:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:375:5 | LL | #[should_panic] impl S { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:379:1 | LL | #[ignore] | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:383:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:382:17 | LL | mod inner { #![ignore] } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:386:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:385:5 | LL | #[ignore] fn f() { } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:389:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:388:5 | LL | #[ignore] struct S; | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:392:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:391:5 | LL | #[ignore] type T = S; | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:395:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:394:5 | LL | #[ignore] impl S { } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:399:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:398:1 | LL | #[no_implicit_prelude] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:402:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:401:17 | LL | mod inner { #![no_implicit_prelude] } | ^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:405:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:404:5 | LL | #[no_implicit_prelude] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:408:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:407:5 | LL | #[no_implicit_prelude] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:411:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:410:5 | LL | #[no_implicit_prelude] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:414:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:413:5 | LL | #[no_implicit_prelude] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:418:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:417:1 | LL | #[reexport_test_harness_main = "2900"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:421:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:420:17 | LL | mod inner { #![reexport_test_harness_main="2900"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:424:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:423:5 | LL | #[reexport_test_harness_main = "2900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:427:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:426:5 | LL | #[reexport_test_harness_main = "2900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:430:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:429:5 | LL | #[reexport_test_harness_main = "2900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:433:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:432:5 | LL | #[reexport_test_harness_main = "2900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:445:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:444:5 | LL | #[macro_escape] fn f() { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:448:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:447:5 | LL | #[macro_escape] struct S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:451:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:450:5 | LL | #[macro_escape] type T = S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:454:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:453:5 | LL | #[macro_escape] impl S { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:457:1 | LL | #[no_std] | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:457:1 | LL | #[no_std] | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:462:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:461:17 | LL | mod inner { #![no_std] } | ^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:462:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:461:17 | LL | mod inner { #![no_std] } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:465:5 | LL | #[no_std] fn f() { } | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:465:5 | LL | #[no_std] fn f() { } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:470:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:469:5 | LL | #[no_std] struct S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:470:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:469:5 | LL | #[no_std] struct S; | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:474:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:473:5 | LL | #[no_std] type T = S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:474:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:473:5 | LL | #[no_std] type T = S; | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:478:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:477:5 | LL | #[no_std] impl S { } | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:478:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:477:5 | LL | #[no_std] impl S { } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:659:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:658:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:659:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:658:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:662:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:662:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:666:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:666:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:670:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:670:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:674:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:674:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:678:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:678:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:683:1 | LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:683:1 | LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:17 | LL | mod inner { #![crate_type="0800"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:17 | LL | mod inner { #![crate_type="0800"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:691:5 | LL | #[crate_type = "0800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:691:5 | LL | #[crate_type = "0800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:695:5 | LL | #[crate_type = "0800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:695:5 | LL | #[crate_type = "0800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:699:5 | LL | #[crate_type = "0800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:699:5 | LL | #[crate_type = "0800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:703:5 | LL | #[crate_type = "0800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:703:5 | LL | #[crate_type = "0800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:720:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:720:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:728:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:728:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:735:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:734:1 | LL | #[no_main] | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:735:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:734:1 | LL | #[no_main] | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:739:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:17 | LL | mod inner { #![no_main] } | ^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:739:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:738:17 | LL | mod inner { #![no_main] } | ^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:5 | LL | #[no_main] fn f() { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:5 | LL | #[no_main] fn f() { } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5 | LL | #[no_main] struct S; | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5 | LL | #[no_main] struct S; | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:751:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:5 | LL | #[no_main] type T = S; | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:751:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:5 | LL | #[no_main] type T = S; | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:5 | LL | #[no_main] impl S { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:5 | LL | #[no_main] impl S { } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:773:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:772:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:773:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:772:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:777:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:777:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:781:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:781:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:785:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:785:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:788:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:788:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:792:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:792:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:805:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:805:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:809:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:809:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:813:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:813:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:817:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:817:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs index 5bf3ec733f5..d3056fb8851 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.rs +++ b/src/test/ui/impl-trait/bound-normalization-fail.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // edition:2018 #![feature(impl_trait_in_bindings)] diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr index 6958cd97a4a..ba3a2e7f8d4 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.stderr +++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr @@ -1,5 +1,5 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bound-normalization-fail.rs:4:12 + --> $DIR/bound-normalization-fail.rs:3:12 | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #![feature(impl_trait_in_bindings)] = note: see issue #63065 for more information error[E0271]: type mismatch resolving ` as FooLike>::Output == ::Assoc` - --> $DIR/bound-normalization-fail.rs:27:32 + --> $DIR/bound-normalization-fail.rs:26:32 | LL | fn foo_fail() -> impl FooLike { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()` @@ -21,13 +21,13 @@ LL | fn foo_fail>() -> impl FooLike { | ^^^^^^^^^^^^ error[E0760]: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - --> $DIR/bound-normalization-fail.rs:43:41 + --> $DIR/bound-normalization-fail.rs:42:41 | LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0271]: type mismatch resolving ` as FooLike>::Output == >::Assoc` - --> $DIR/bound-normalization-fail.rs:43:41 + --> $DIR/bound-normalization-fail.rs:42:41 | LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()` diff --git a/src/test/ui/impl-trait/issue-55872-1.full_tait.stderr b/src/test/ui/impl-trait/issue-55872-1.full_tait.stderr index 67a500f34d8..286dd7aafb4 100644 --- a/src/test/ui/impl-trait/issue-55872-1.full_tait.stderr +++ b/src/test/ui/impl-trait/issue-55872-1.full_tait.stderr @@ -1,5 +1,5 @@ warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-55872-1.rs:4:32 + --> $DIR/issue-55872-1.rs:3:32 | LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] | ^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: see issue #63063 for more information error[E0276]: impl has stricter requirements than trait - --> $DIR/issue-55872-1.rs:18:5 + --> $DIR/issue-55872-1.rs:17:5 | LL | fn foo() -> Self::E; | ----------------------- definition of `foo` from trait @@ -17,7 +17,7 @@ LL | fn foo() -> Self::E { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Default` error[E0277]: the trait bound `S: Copy` is not satisfied in `(S, T)` - --> $DIR/issue-55872-1.rs:14:14 + --> $DIR/issue-55872-1.rs:13:14 | LL | type E = impl Copy; | ^^^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `S` @@ -29,7 +29,7 @@ LL | impl Bar for S { | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: Copy` is not satisfied in `(S, T)` - --> $DIR/issue-55872-1.rs:14:14 + --> $DIR/issue-55872-1.rs:13:14 | LL | type E = impl Copy; | ^^^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `T` @@ -41,7 +41,7 @@ LL | fn foo() -> Self::E { | ^^^^^^^^^^^^^^^^^^^ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872-1.rs:18:37 + --> $DIR/issue-55872-1.rs:17:37 | LL | fn foo() -> Self::E { | _____________________________________^ diff --git a/src/test/ui/impl-trait/issue-55872-1.min_tait.stderr b/src/test/ui/impl-trait/issue-55872-1.min_tait.stderr index 90225d249d7..653299f4cbc 100644 --- a/src/test/ui/impl-trait/issue-55872-1.min_tait.stderr +++ b/src/test/ui/impl-trait/issue-55872-1.min_tait.stderr @@ -1,5 +1,5 @@ error[E0276]: impl has stricter requirements than trait - --> $DIR/issue-55872-1.rs:18:5 + --> $DIR/issue-55872-1.rs:17:5 | LL | fn foo() -> Self::E; | ----------------------- definition of `foo` from trait @@ -8,7 +8,7 @@ LL | fn foo() -> Self::E { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Default` error[E0277]: the trait bound `S: Copy` is not satisfied in `(S, T)` - --> $DIR/issue-55872-1.rs:14:14 + --> $DIR/issue-55872-1.rs:13:14 | LL | type E = impl Copy; | ^^^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `S` @@ -20,7 +20,7 @@ LL | impl Bar for S { | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: Copy` is not satisfied in `(S, T)` - --> $DIR/issue-55872-1.rs:14:14 + --> $DIR/issue-55872-1.rs:13:14 | LL | type E = impl Copy; | ^^^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `T` @@ -32,7 +32,7 @@ LL | fn foo() -> Self::E { | ^^^^^^^^^^^^^^^^^^^ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872-1.rs:18:37 + --> $DIR/issue-55872-1.rs:17:37 | LL | fn foo() -> Self::E { | _____________________________________^ diff --git a/src/test/ui/impl-trait/issue-55872-1.rs b/src/test/ui/impl-trait/issue-55872-1.rs index e5e437cd84b..a9e9c9b5beb 100644 --- a/src/test/ui/impl-trait/issue-55872-1.rs +++ b/src/test/ui/impl-trait/issue-55872-1.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // revisions: min_tait full_tait #![feature(min_type_alias_impl_trait)] #![cfg_attr(full_tait, feature(type_alias_impl_trait))] diff --git a/src/test/ui/impl-trait/issue-55872-2.full_tait.stderr b/src/test/ui/impl-trait/issue-55872-2.full_tait.stderr index 14a5c0ba97e..a8fc681a093 100644 --- a/src/test/ui/impl-trait/issue-55872-2.full_tait.stderr +++ b/src/test/ui/impl-trait/issue-55872-2.full_tait.stderr @@ -1,5 +1,5 @@ warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-55872-2.rs:7:32 + --> $DIR/issue-55872-2.rs:6:32 | LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] | ^^^^^^^^^^^^^^^^^^^^^ @@ -8,13 +8,13 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: see issue #63063 for more information error[E0277]: the trait bound `impl Future: Copy` is not satisfied - --> $DIR/issue-55872-2.rs:17:14 + --> $DIR/issue-55872-2.rs:16:14 | LL | type E = impl std::marker::Copy; | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future` error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872-2.rs:19:28 + --> $DIR/issue-55872-2.rs:18:28 | LL | fn foo() -> Self::E { | ____________________________^ diff --git a/src/test/ui/impl-trait/issue-55872-2.min_tait.stderr b/src/test/ui/impl-trait/issue-55872-2.min_tait.stderr index c8df502345a..57f81443dcc 100644 --- a/src/test/ui/impl-trait/issue-55872-2.min_tait.stderr +++ b/src/test/ui/impl-trait/issue-55872-2.min_tait.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `impl Future: Copy` is not satisfied - --> $DIR/issue-55872-2.rs:17:14 + --> $DIR/issue-55872-2.rs:16:14 | LL | type E = impl std::marker::Copy; | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future` error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872-2.rs:19:28 + --> $DIR/issue-55872-2.rs:18:28 | LL | fn foo() -> Self::E { | ____________________________^ diff --git a/src/test/ui/impl-trait/issue-55872-2.rs b/src/test/ui/impl-trait/issue-55872-2.rs index 9c2e9b860c4..cd72b2eec3c 100644 --- a/src/test/ui/impl-trait/issue-55872-2.rs +++ b/src/test/ui/impl-trait/issue-55872-2.rs @@ -1,5 +1,4 @@ // edition:2018 -// ignore-tidy-linelength // ignore-compare-mode-chalk // revisions: min_tait full_tait diff --git a/src/test/ui/impl-trait/issue-55872.full_tait.stderr b/src/test/ui/impl-trait/issue-55872.full_tait.stderr index 5a35689a737..e549fec1c22 100644 --- a/src/test/ui/impl-trait/issue-55872.full_tait.stderr +++ b/src/test/ui/impl-trait/issue-55872.full_tait.stderr @@ -1,5 +1,5 @@ warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-55872.rs:5:32 + --> $DIR/issue-55872.rs:4:32 | LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] | ^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: see issue #63063 for more information error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872.rs:17:28 + --> $DIR/issue-55872.rs:16:28 | LL | fn foo() -> Self::E { | ____________________________^ diff --git a/src/test/ui/impl-trait/issue-55872.min_tait.stderr b/src/test/ui/impl-trait/issue-55872.min_tait.stderr index 9baf2834643..341dba95cad 100644 --- a/src/test/ui/impl-trait/issue-55872.min_tait.stderr +++ b/src/test/ui/impl-trait/issue-55872.min_tait.stderr @@ -1,5 +1,5 @@ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872.rs:17:28 + --> $DIR/issue-55872.rs:16:28 | LL | fn foo() -> Self::E { | ____________________________^ diff --git a/src/test/ui/impl-trait/issue-55872.rs b/src/test/ui/impl-trait/issue-55872.rs index 9a31cf521b3..e3fc523fecc 100644 --- a/src/test/ui/impl-trait/issue-55872.rs +++ b/src/test/ui/impl-trait/issue-55872.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // ignore-compare-mode-chalk // revisions: min_tait full_tait #![feature(min_type_alias_impl_trait)] diff --git a/src/test/ui/imports/extern-prelude-extern-crate-fail.rs b/src/test/ui/imports/extern-prelude-extern-crate-fail.rs index 4a0c6120201..feb1ab09dc9 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-fail.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-fail.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // aux-build:two_macros.rs // compile-flags:--extern non_existent diff --git a/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr b/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr index 2d7a1bf468e..011ea020508 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr +++ b/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr @@ -1,5 +1,5 @@ error: macro-expanded `extern crate` items cannot shadow names passed with `--extern` - --> $DIR/extern-prelude-extern-crate-fail.rs:18:9 + --> $DIR/extern-prelude-extern-crate-fail.rs:16:9 | LL | extern crate std as non_existent; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | define_std_as_non_existent!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0433]: failed to resolve: use of undeclared crate or module `two_macros` - --> $DIR/extern-prelude-extern-crate-fail.rs:12:9 + --> $DIR/extern-prelude-extern-crate-fail.rs:10:9 | LL | two_macros::m!(); | ^^^^^^^^^^ use of undeclared crate or module `two_macros` diff --git a/src/test/ui/issues/issue-3214.rs b/src/test/ui/issues/issue-3214.rs index 9bb164f1ddd..ccfaf23b4b9 100644 --- a/src/test/ui/issues/issue-3214.rs +++ b/src/test/ui/issues/issue-3214.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - fn foo() { struct Foo { x: T, //~ ERROR can't use generic parameters from outer function diff --git a/src/test/ui/issues/issue-3214.stderr b/src/test/ui/issues/issue-3214.stderr index c2268924bc4..0da095b7fda 100644 --- a/src/test/ui/issues/issue-3214.stderr +++ b/src/test/ui/issues/issue-3214.stderr @@ -1,5 +1,5 @@ error[E0401]: can't use generic parameters from outer function - --> $DIR/issue-3214.rs:5:12 + --> $DIR/issue-3214.rs:3:12 | LL | fn foo() { | --- - type parameter from outer function @@ -10,7 +10,7 @@ LL | x: T, | ^ use of generic parameter from outer function error[E0107]: this struct takes 0 type arguments but 1 type argument was supplied - --> $DIR/issue-3214.rs:8:22 + --> $DIR/issue-3214.rs:6:22 | LL | impl Drop for Foo { | ^^^--- help: remove these generics @@ -18,13 +18,13 @@ LL | impl Drop for Foo { | expected 0 type arguments | note: struct defined here, with 0 type parameters - --> $DIR/issue-3214.rs:4:12 + --> $DIR/issue-3214.rs:2:12 | LL | struct Foo { | ^^^ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-3214.rs:8:10 + --> $DIR/issue-3214.rs:6:10 | LL | impl Drop for Foo { | ^ unconstrained type parameter diff --git a/src/test/ui/issues/issue-45157.rs b/src/test/ui/issues/issue-45157.rs index bd18784289f..8d2bf22a03c 100644 --- a/src/test/ui/issues/issue-45157.rs +++ b/src/test/ui/issues/issue-45157.rs @@ -1,6 +1,5 @@ #![allow(unused)] -// ignore-tidy-linelength #[derive(Clone, Copy, Default)] struct S { diff --git a/src/test/ui/issues/issue-45157.stderr b/src/test/ui/issues/issue-45157.stderr index 1b879e0b48c..57fd8d49c88 100644 --- a/src/test/ui/issues/issue-45157.stderr +++ b/src/test/ui/issues/issue-45157.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `u` (via `u.z.c`) as immutable because it is also borrowed as mutable (via `u.s.a`) - --> $DIR/issue-45157.rs:28:20 + --> $DIR/issue-45157.rs:27:20 | LL | let mref = &mut u.s.a; | ---------- mutable borrow occurs here (via `u.s.a`) diff --git a/src/test/ui/issues/issue-47725.rs b/src/test/ui/issues/issue-47725.rs index 21108da5006..9ec55be5872 100644 --- a/src/test/ui/issues/issue-47725.rs +++ b/src/test/ui/issues/issue-47725.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![warn(unused_attributes)] //~ NOTE lint level is defined here #[link_name = "foo"] diff --git a/src/test/ui/issues/issue-47725.stderr b/src/test/ui/issues/issue-47725.stderr index b1e8d3292eb..c7a9bfe317f 100644 --- a/src/test/ui/issues/issue-47725.stderr +++ b/src/test/ui/issues/issue-47725.stderr @@ -1,11 +1,11 @@ error: malformed `link_name` attribute input - --> $DIR/issue-47725.rs:18:1 + --> $DIR/issue-47725.rs:17:1 | LL | #[link_name] | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]` warning: attribute should be applied to a foreign function or static - --> $DIR/issue-47725.rs:4:1 + --> $DIR/issue-47725.rs:3:1 | LL | #[link_name = "foo"] | ^^^^^^^^^^^^^^^^^^^^ @@ -14,14 +14,14 @@ LL | struct Foo; | ----------- not a foreign function or static | note: the lint level is defined here - --> $DIR/issue-47725.rs:2:9 + --> $DIR/issue-47725.rs:1:9 | LL | #![warn(unused_attributes)] | ^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-47725.rs:9:1 + --> $DIR/issue-47725.rs:8:1 | LL | #[link_name = "foobar"] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,13 +33,13 @@ LL | | } | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! help: try `#[link(name = "foobar")]` instead - --> $DIR/issue-47725.rs:9:1 + --> $DIR/issue-47725.rs:8:1 | LL | #[link_name = "foobar"] | ^^^^^^^^^^^^^^^^^^^^^^^ warning: attribute should be applied to a foreign function or static - --> $DIR/issue-47725.rs:18:1 + --> $DIR/issue-47725.rs:17:1 | LL | #[link_name] | ^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | | } | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! help: try `#[link(name = "...")]` instead - --> $DIR/issue-47725.rs:18:1 + --> $DIR/issue-47725.rs:17:1 | LL | #[link_name] | ^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-53251.rs b/src/test/ui/issues/issue-53251.rs index 309b9800b7d..937271d42f4 100644 --- a/src/test/ui/issues/issue-53251.rs +++ b/src/test/ui/issues/issue-53251.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - struct S; impl S { diff --git a/src/test/ui/issues/issue-53251.stderr b/src/test/ui/issues/issue-53251.stderr index 5d1a6d4a522..1676c508a4d 100644 --- a/src/test/ui/issues/issue-53251.stderr +++ b/src/test/ui/issues/issue-53251.stderr @@ -1,5 +1,5 @@ error[E0107]: this associated function takes 0 type arguments but 1 type argument was supplied - --> $DIR/issue-53251.rs:13:20 + --> $DIR/issue-53251.rs:11:20 | LL | S::f::(); | ^------- help: remove these generics @@ -10,14 +10,14 @@ LL | impl_add!(a b); | --------------- in this macro invocation | note: associated function defined here, with 0 type parameters - --> $DIR/issue-53251.rs:6:8 + --> $DIR/issue-53251.rs:4:8 | LL | fn f() {} | ^ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0107]: this associated function takes 0 type arguments but 1 type argument was supplied - --> $DIR/issue-53251.rs:13:20 + --> $DIR/issue-53251.rs:11:20 | LL | S::f::(); | ^------- help: remove these generics @@ -28,7 +28,7 @@ LL | impl_add!(a b); | --------------- in this macro invocation | note: associated function defined here, with 0 type parameters - --> $DIR/issue-53251.rs:6:8 + --> $DIR/issue-53251.rs:4:8 | LL | fn f() {} | ^ diff --git a/src/test/ui/issues/issue-54044.rs b/src/test/ui/issues/issue-54044.rs index 3f0b8bc5e38..809ea7a87db 100644 --- a/src/test/ui/issues/issue-54044.rs +++ b/src/test/ui/issues/issue-54044.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength #![deny(unused_attributes)] //~ NOTE lint level is defined here #[cold] diff --git a/src/test/ui/issues/issue-54044.stderr b/src/test/ui/issues/issue-54044.stderr index a13e84bbee1..0200a6a629d 100644 --- a/src/test/ui/issues/issue-54044.stderr +++ b/src/test/ui/issues/issue-54044.stderr @@ -1,5 +1,5 @@ error: attribute should be applied to a function - --> $DIR/issue-54044.rs:4:1 + --> $DIR/issue-54044.rs:3:1 | LL | #[cold] | ^^^^^^^ @@ -8,14 +8,14 @@ LL | struct Foo; | ----------- not a function | note: the lint level is defined here - --> $DIR/issue-54044.rs:2:9 + --> $DIR/issue-54044.rs:1:9 | LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: attribute should be applied to a function - --> $DIR/issue-54044.rs:10:5 + --> $DIR/issue-54044.rs:9:5 | LL | #[cold] | ^^^^^^^ diff --git a/src/test/ui/issues/issue-60622.rs b/src/test/ui/issues/issue-60622.rs index 1d9bd2dd2dc..1018c88ae55 100644 --- a/src/test/ui/issues/issue-60622.rs +++ b/src/test/ui/issues/issue-60622.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![deny(warnings)] struct Borked {} diff --git a/src/test/ui/issues/issue-60622.stderr b/src/test/ui/issues/issue-60622.stderr index 47f2f181f2d..f970a63e4b2 100644 --- a/src/test/ui/issues/issue-60622.stderr +++ b/src/test/ui/issues/issue-60622.stderr @@ -1,5 +1,5 @@ error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/issue-60622.rs:12:11 + --> $DIR/issue-60622.rs:10:11 | LL | fn a(&self) {} | - the late bound lifetime parameter is introduced here @@ -8,7 +8,7 @@ LL | b.a::<'_, T>(); | ^^ | note: the lint level is defined here - --> $DIR/issue-60622.rs:3:9 + --> $DIR/issue-60622.rs:1:9 | LL | #![deny(warnings)] | ^^^^^^^^ @@ -17,7 +17,7 @@ LL | #![deny(warnings)] = note: for more information, see issue #42868 error[E0107]: this associated function takes 0 type arguments but 1 type argument was supplied - --> $DIR/issue-60622.rs:12:7 + --> $DIR/issue-60622.rs:10:7 | LL | b.a::<'_, T>(); | ^ --- help: remove this type argument @@ -25,7 +25,7 @@ LL | b.a::<'_, T>(); | expected 0 type arguments | note: associated function defined here, with 0 type parameters - --> $DIR/issue-60622.rs:8:8 + --> $DIR/issue-60622.rs:6:8 | LL | fn a(&self) {} | ^ diff --git a/src/test/ui/issues/issue-82833-slice-miscompile.rs b/src/test/ui/issues/issue-82833-slice-miscompile.rs index b14e5f6fb12..8cf6a3137e2 100644 --- a/src/test/ui/issues/issue-82833-slice-miscompile.rs +++ b/src/test/ui/issues/issue-82833-slice-miscompile.rs @@ -1,6 +1,5 @@ // run-pass // compile-flags: -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Copt-level=0 -Cdebuginfo=2 -// ignore-tidy-linelength // Make sure LLVM does not miscompile this. diff --git a/src/test/ui/kinds-of-primitive-impl.rs b/src/test/ui/kinds-of-primitive-impl.rs index cbd4d7ae904..b045b050d77 100644 --- a/src/test/ui/kinds-of-primitive-impl.rs +++ b/src/test/ui/kinds-of-primitive-impl.rs @@ -1,6 +1,3 @@ -// ignore-tidy-linelength - - impl u8 { //~^ error: only a single inherent implementation marked with `#[lang = "u8"]` is allowed for the `u8` primitive pub const B: u8 = 0; diff --git a/src/test/ui/kinds-of-primitive-impl.stderr b/src/test/ui/kinds-of-primitive-impl.stderr index d19c85b17f9..f1fb2953083 100644 --- a/src/test/ui/kinds-of-primitive-impl.stderr +++ b/src/test/ui/kinds-of-primitive-impl.stderr @@ -1,5 +1,5 @@ error[E0390]: only a single inherent implementation marked with `#[lang = "u8"]` is allowed for the `u8` primitive - --> $DIR/kinds-of-primitive-impl.rs:4:1 + --> $DIR/kinds-of-primitive-impl.rs:1:1 | LL | / impl u8 { LL | | @@ -10,7 +10,7 @@ LL | | } = help: consider using a trait to implement this constant error[E0390]: only a single inherent implementation marked with `#[lang = "str"]` is allowed for the `str` primitive - --> $DIR/kinds-of-primitive-impl.rs:9:1 + --> $DIR/kinds-of-primitive-impl.rs:6:1 | LL | / impl str { LL | | @@ -22,7 +22,7 @@ LL | | } = help: consider using a trait to implement these methods error[E0390]: only a single inherent implementation marked with `#[lang = "char"]` is allowed for the `char` primitive - --> $DIR/kinds-of-primitive-impl.rs:15:1 + --> $DIR/kinds-of-primitive-impl.rs:12:1 | LL | / impl char { LL | | diff --git a/src/test/ui/lint/lint-stability-deprecated.rs b/src/test/ui/lint/lint-stability-deprecated.rs index a6fde11495c..5bdddf71418 100644 --- a/src/test/ui/lint/lint-stability-deprecated.rs +++ b/src/test/ui/lint/lint-stability-deprecated.rs @@ -3,7 +3,6 @@ // aux-build:inherited_stability.rs // aux-build:stability_cfg1.rs // aux-build:stability-cfg2.rs -// ignore-tidy-linelength #![warn(deprecated)] #![feature(staged_api, unstable_test_feature)] diff --git a/src/test/ui/lint/lint-stability-deprecated.stderr b/src/test/ui/lint/lint-stability-deprecated.stderr index d8dd83b0d06..47dc8e4a63c 100644 --- a/src/test/ui/lint/lint-stability-deprecated.stderr +++ b/src/test/ui/lint/lint-stability-deprecated.stderr @@ -1,653 +1,653 @@ warning: use of deprecated function `lint_stability::deprecated`: text - --> $DIR/lint-stability-deprecated.rs:25:9 + --> $DIR/lint-stability-deprecated.rs:24:9 | LL | deprecated(); | ^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/lint-stability-deprecated.rs:7:9 + --> $DIR/lint-stability-deprecated.rs:6:9 | LL | #![warn(deprecated)] | ^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:30:9 + --> $DIR/lint-stability-deprecated.rs:29:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:32:9 + --> $DIR/lint-stability-deprecated.rs:31:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated function `lint_stability::deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:34:9 + --> $DIR/lint-stability-deprecated.rs:33:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:39:9 + --> $DIR/lint-stability-deprecated.rs:38:9 | LL | ... Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:41:9 + --> $DIR/lint-stability-deprecated.rs:40:9 | LL | ... ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated function `lint_stability::deprecated_unstable`: text - --> $DIR/lint-stability-deprecated.rs:43:9 + --> $DIR/lint-stability-deprecated.rs:42:9 | LL | deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text - --> $DIR/lint-stability-deprecated.rs:48:9 + --> $DIR/lint-stability-deprecated.rs:47:9 | LL | ... Trait::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text - --> $DIR/lint-stability-deprecated.rs:50:9 + --> $DIR/lint-stability-deprecated.rs:49:9 | LL | ... ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:52:9 + --> $DIR/lint-stability-deprecated.rs:51:9 | LL | deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:57:9 + --> $DIR/lint-stability-deprecated.rs:56:9 | LL | ... Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:59:9 + --> $DIR/lint-stability-deprecated.rs:58:9 | LL | ... ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated struct `lint_stability::DeprecatedStruct`: text - --> $DIR/lint-stability-deprecated.rs:109:17 + --> $DIR/lint-stability-deprecated.rs:108:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ warning: use of deprecated struct `lint_stability::DeprecatedUnstableStruct`: text - --> $DIR/lint-stability-deprecated.rs:112:17 + --> $DIR/lint-stability-deprecated.rs:111:17 | LL | let _ = DeprecatedUnstableStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated struct `lint_stability::DeprecatedUnitStruct`: text - --> $DIR/lint-stability-deprecated.rs:119:17 + --> $DIR/lint-stability-deprecated.rs:118:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated struct `lint_stability::DeprecatedUnstableUnitStruct`: text - --> $DIR/lint-stability-deprecated.rs:120:17 + --> $DIR/lint-stability-deprecated.rs:119:17 | LL | let _ = DeprecatedUnstableUnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated variant `lint_stability::Enum::DeprecatedVariant`: text - --> $DIR/lint-stability-deprecated.rs:124:17 + --> $DIR/lint-stability-deprecated.rs:123:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated variant `lint_stability::Enum::DeprecatedUnstableVariant`: text - --> $DIR/lint-stability-deprecated.rs:125:17 + --> $DIR/lint-stability-deprecated.rs:124:17 | LL | let _ = Enum::DeprecatedUnstableVariant; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated struct `lint_stability::DeprecatedTupleStruct`: text - --> $DIR/lint-stability-deprecated.rs:129:17 + --> $DIR/lint-stability-deprecated.rs:128:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated struct `lint_stability::DeprecatedUnstableTupleStruct`: text - --> $DIR/lint-stability-deprecated.rs:130:17 + --> $DIR/lint-stability-deprecated.rs:129:17 | LL | let _ = DeprecatedUnstableTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated function `lint_stability::deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:139:25 + --> $DIR/lint-stability-deprecated.rs:138:25 | LL | macro_test_arg!(deprecated_text()); | ^^^^^^^^^^^^^^^ warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:140:25 + --> $DIR/lint-stability-deprecated.rs:139:25 | LL | macro_test_arg!(deprecated_unstable_text()); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated function `lint_stability::deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:141:41 + --> $DIR/lint-stability-deprecated.rs:140:41 | LL | macro_test_arg!(macro_test_arg!(deprecated_text())); | ^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:146:9 + --> $DIR/lint-stability-deprecated.rs:145:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:148:9 + --> $DIR/lint-stability-deprecated.rs:147:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:150:9 + --> $DIR/lint-stability-deprecated.rs:149:9 | LL | ... Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:152:9 + --> $DIR/lint-stability-deprecated.rs:151:9 | LL | ... ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text - --> $DIR/lint-stability-deprecated.rs:154:9 + --> $DIR/lint-stability-deprecated.rs:153:9 | LL | ... Trait::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text - --> $DIR/lint-stability-deprecated.rs:156:9 + --> $DIR/lint-stability-deprecated.rs:155:9 | LL | ... ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:158:9 + --> $DIR/lint-stability-deprecated.rs:157:9 | LL | ... Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:160:9 + --> $DIR/lint-stability-deprecated.rs:159:9 | LL | ... ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text - --> $DIR/lint-stability-deprecated.rs:188:10 + --> $DIR/lint-stability-deprecated.rs:187:10 | LL | impl DeprecatedTrait for S {} | ^^^^^^^^^^^^^^^ warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text - --> $DIR/lint-stability-deprecated.rs:190:25 + --> $DIR/lint-stability-deprecated.rs:189:25 | LL | trait LocalTrait2 : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ warning: use of deprecated function `inheritance::inherited_stability::unstable_mod::deprecated`: text - --> $DIR/lint-stability-deprecated.rs:209:9 + --> $DIR/lint-stability-deprecated.rs:208:9 | LL | unstable_mod::deprecated(); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated function `this_crate::deprecated`: text - --> $DIR/lint-stability-deprecated.rs:331:9 + --> $DIR/lint-stability-deprecated.rs:330:9 | LL | deprecated(); | ^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:336:9 + --> $DIR/lint-stability-deprecated.rs:335:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:338:9 + --> $DIR/lint-stability-deprecated.rs:337:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated function `this_crate::deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:340:9 + --> $DIR/lint-stability-deprecated.rs:339:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:345:9 + --> $DIR/lint-stability-deprecated.rs:344:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:347:9 + --> $DIR/lint-stability-deprecated.rs:346:9 | LL | ... ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated struct `this_crate::DeprecatedStruct`: text - --> $DIR/lint-stability-deprecated.rs:385:17 + --> $DIR/lint-stability-deprecated.rs:384:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ warning: use of deprecated unit struct `this_crate::DeprecatedUnitStruct`: text - --> $DIR/lint-stability-deprecated.rs:392:17 + --> $DIR/lint-stability-deprecated.rs:391:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text - --> $DIR/lint-stability-deprecated.rs:396:17 + --> $DIR/lint-stability-deprecated.rs:395:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text - --> $DIR/lint-stability-deprecated.rs:400:17 + --> $DIR/lint-stability-deprecated.rs:399:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:407:9 + --> $DIR/lint-stability-deprecated.rs:406:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:409:9 + --> $DIR/lint-stability-deprecated.rs:408:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:411:9 + --> $DIR/lint-stability-deprecated.rs:410:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:413:9 + --> $DIR/lint-stability-deprecated.rs:412:9 | LL | ... ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated function `this_crate::test_fn_body::fn_in_body`: text - --> $DIR/lint-stability-deprecated.rs:440:9 + --> $DIR/lint-stability-deprecated.rs:439:9 | LL | fn_in_body(); | ^^^^^^^^^^ warning: use of deprecated trait `this_crate::DeprecatedTrait`: text - --> $DIR/lint-stability-deprecated.rs:460:10 + --> $DIR/lint-stability-deprecated.rs:459:10 | LL | impl DeprecatedTrait for S { } | ^^^^^^^^^^^^^^^ warning: use of deprecated trait `this_crate::DeprecatedTrait`: text - --> $DIR/lint-stability-deprecated.rs:462:24 + --> $DIR/lint-stability-deprecated.rs:461:24 | LL | trait LocalTrait : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ warning: use of deprecated function `this_crate::MethodTester::test_method_body::fn_in_body`: text - --> $DIR/lint-stability-deprecated.rs:448:13 + --> $DIR/lint-stability-deprecated.rs:447:13 | LL | fn_in_body(); | ^^^^^^^^^^ warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text - --> $DIR/lint-stability-deprecated.rs:98:48 + --> $DIR/lint-stability-deprecated.rs:97:48 | LL | struct S2(T::TypeDeprecated); | ^^^^^^^^^^^^^^^^^ warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text - --> $DIR/lint-stability-deprecated.rs:103:13 + --> $DIR/lint-stability-deprecated.rs:102:13 | LL | TypeDeprecated = u16, | ^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:26:13 + --> $DIR/lint-stability-deprecated.rs:25:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:27:9 + --> $DIR/lint-stability-deprecated.rs:26:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:28:9 + --> $DIR/lint-stability-deprecated.rs:27:9 | LL | ::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:29:13 + --> $DIR/lint-stability-deprecated.rs:28:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:31:9 + --> $DIR/lint-stability-deprecated.rs:30:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:35:13 + --> $DIR/lint-stability-deprecated.rs:34:13 | LL | ... foo.method_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:36:9 + --> $DIR/lint-stability-deprecated.rs:35:9 | LL | ... Foo::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:37:9 + --> $DIR/lint-stability-deprecated.rs:36:9 | LL | ... ::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:38:13 + --> $DIR/lint-stability-deprecated.rs:37:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:40:9 + --> $DIR/lint-stability-deprecated.rs:39:9 | LL | ... ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text - --> $DIR/lint-stability-deprecated.rs:44:13 + --> $DIR/lint-stability-deprecated.rs:43:13 | LL | ... foo.method_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text - --> $DIR/lint-stability-deprecated.rs:45:9 + --> $DIR/lint-stability-deprecated.rs:44:9 | LL | ... Foo::method_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text - --> $DIR/lint-stability-deprecated.rs:46:9 + --> $DIR/lint-stability-deprecated.rs:45:9 | LL | ... ::method_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text - --> $DIR/lint-stability-deprecated.rs:47:13 + --> $DIR/lint-stability-deprecated.rs:46:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text - --> $DIR/lint-stability-deprecated.rs:49:9 + --> $DIR/lint-stability-deprecated.rs:48:9 | LL | ... ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:53:13 + --> $DIR/lint-stability-deprecated.rs:52:13 | LL | ... foo.method_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:54:9 + --> $DIR/lint-stability-deprecated.rs:53:9 | LL | ... Foo::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:55:9 + --> $DIR/lint-stability-deprecated.rs:54:9 | LL | ... ::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:56:13 + --> $DIR/lint-stability-deprecated.rs:55:13 | LL | ... foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:58:9 + --> $DIR/lint-stability-deprecated.rs:57:9 | LL | ... ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated field `lint_stability::DeprecatedStruct::i`: text - --> $DIR/lint-stability-deprecated.rs:110:13 + --> $DIR/lint-stability-deprecated.rs:109:13 | LL | i: 0 | ^^^^ warning: use of deprecated field `lint_stability::DeprecatedUnstableStruct::i`: text - --> $DIR/lint-stability-deprecated.rs:114:13 + --> $DIR/lint-stability-deprecated.rs:113:13 | LL | i: 0 | ^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:145:13 + --> $DIR/lint-stability-deprecated.rs:144:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:147:9 + --> $DIR/lint-stability-deprecated.rs:146:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:149:13 + --> $DIR/lint-stability-deprecated.rs:148:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:151:9 + --> $DIR/lint-stability-deprecated.rs:150:9 | LL | ... ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text - --> $DIR/lint-stability-deprecated.rs:153:13 + --> $DIR/lint-stability-deprecated.rs:152:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text - --> $DIR/lint-stability-deprecated.rs:155:9 + --> $DIR/lint-stability-deprecated.rs:154:9 | LL | ... ::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:157:13 + --> $DIR/lint-stability-deprecated.rs:156:13 | LL | ... foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:159:9 + --> $DIR/lint-stability-deprecated.rs:158:9 | LL | ... ::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:176:13 + --> $DIR/lint-stability-deprecated.rs:175:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:177:13 + --> $DIR/lint-stability-deprecated.rs:176:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text - --> $DIR/lint-stability-deprecated.rs:178:13 + --> $DIR/lint-stability-deprecated.rs:177:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - --> $DIR/lint-stability-deprecated.rs:179:13 + --> $DIR/lint-stability-deprecated.rs:178:13 | LL | ... foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:332:13 + --> $DIR/lint-stability-deprecated.rs:331:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:333:9 + --> $DIR/lint-stability-deprecated.rs:332:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:334:9 + --> $DIR/lint-stability-deprecated.rs:333:9 | LL | ::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:335:13 + --> $DIR/lint-stability-deprecated.rs:334:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:337:9 + --> $DIR/lint-stability-deprecated.rs:336:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:341:13 + --> $DIR/lint-stability-deprecated.rs:340:13 | LL | ... foo.method_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:342:9 + --> $DIR/lint-stability-deprecated.rs:341:9 | LL | ... Foo::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:343:9 + --> $DIR/lint-stability-deprecated.rs:342:9 | LL | ... ::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:344:13 + --> $DIR/lint-stability-deprecated.rs:343:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:346:9 + --> $DIR/lint-stability-deprecated.rs:345:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated field `this_crate::DeprecatedStruct::i`: text - --> $DIR/lint-stability-deprecated.rs:387:13 + --> $DIR/lint-stability-deprecated.rs:386:13 | LL | i: 0 | ^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:406:13 + --> $DIR/lint-stability-deprecated.rs:405:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:408:9 + --> $DIR/lint-stability-deprecated.rs:407:9 | LL | ::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:410:13 + --> $DIR/lint-stability-deprecated.rs:409:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:412:9 + --> $DIR/lint-stability-deprecated.rs:411:9 | LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text - --> $DIR/lint-stability-deprecated.rs:429:13 + --> $DIR/lint-stability-deprecated.rs:428:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - --> $DIR/lint-stability-deprecated.rs:430:13 + --> $DIR/lint-stability-deprecated.rs:429:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text - --> $DIR/lint-stability-deprecated.rs:98:48 + --> $DIR/lint-stability-deprecated.rs:97:48 | LL | struct S2(T::TypeDeprecated); | ^^^^^^^^^^^^^^^^^ warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text - --> $DIR/lint-stability-deprecated.rs:103:13 + --> $DIR/lint-stability-deprecated.rs:102:13 | LL | TypeDeprecated = u16, | ^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text - --> $DIR/lint-stability-deprecated.rs:103:13 + --> $DIR/lint-stability-deprecated.rs:102:13 | LL | TypeDeprecated = u16, | ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/lint/uninitialized-zeroed.rs b/src/test/ui/lint/uninitialized-zeroed.rs index 78d3060886d..122933c3c4e 100644 --- a/src/test/ui/lint/uninitialized-zeroed.rs +++ b/src/test/ui/lint/uninitialized-zeroed.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // This test checks that calling `mem::{uninitialized,zeroed}` with certain types results // in a lint. diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr index de1b6c76176..0af185ef61b 100644 --- a/src/test/ui/lint/uninitialized-zeroed.stderr +++ b/src/test/ui/lint/uninitialized-zeroed.stderr @@ -1,5 +1,5 @@ error: the type `&T` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:41:32 + --> $DIR/uninitialized-zeroed.rs:40:32 | LL | let _val: &'static T = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -8,14 +8,14 @@ LL | let _val: &'static T = mem::zeroed(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:7:9 + --> $DIR/uninitialized-zeroed.rs:6:9 | LL | #![deny(invalid_value)] | ^^^^^^^^^^^^^ = note: references must be non-null error: the type `&T` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:42:32 + --> $DIR/uninitialized-zeroed.rs:41:32 | LL | let _val: &'static T = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | let _val: &'static T = mem::uninitialized(); = note: references must be non-null error: the type `Wrap<&T>` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:44:38 + --> $DIR/uninitialized-zeroed.rs:43:38 | LL | let _val: Wrap<&'static T> = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -35,13 +35,13 @@ LL | let _val: Wrap<&'static T> = mem::zeroed(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: references must be non-null (in this struct field) - --> $DIR/uninitialized-zeroed.rs:18:18 + --> $DIR/uninitialized-zeroed.rs:17:18 | LL | struct Wrap { wrapped: T } | ^^^^^^^^^^ error: the type `Wrap<&T>` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:45:38 + --> $DIR/uninitialized-zeroed.rs:44:38 | LL | let _val: Wrap<&'static T> = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -50,13 +50,13 @@ LL | let _val: Wrap<&'static T> = mem::uninitialized(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: references must be non-null (in this struct field) - --> $DIR/uninitialized-zeroed.rs:18:18 + --> $DIR/uninitialized-zeroed.rs:17:18 | LL | struct Wrap { wrapped: T } | ^^^^^^^^^^ error: the type `!` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:52:23 + --> $DIR/uninitialized-zeroed.rs:51:23 | LL | let _val: ! = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | let _val: ! = mem::zeroed(); = note: the `!` type has no valid value error: the type `!` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:53:23 + --> $DIR/uninitialized-zeroed.rs:52:23 | LL | let _val: ! = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | let _val: ! = mem::uninitialized(); = note: the `!` type has no valid value error: the type `(i32, !)` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:55:30 + --> $DIR/uninitialized-zeroed.rs:54:30 | LL | let _val: (i32, !) = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _val: (i32, !) = mem::zeroed(); = note: the `!` type has no valid value error: the type `(i32, !)` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:56:30 + --> $DIR/uninitialized-zeroed.rs:55:30 | LL | let _val: (i32, !) = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | let _val: (i32, !) = mem::uninitialized(); = note: the `!` type has no valid value error: the type `Void` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:58:26 + --> $DIR/uninitialized-zeroed.rs:57:26 | LL | let _val: Void = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | let _val: Void = mem::zeroed(); = note: enums with no variants have no valid value error: the type `Void` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:59:26 + --> $DIR/uninitialized-zeroed.rs:58:26 | LL | let _val: Void = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | let _val: Void = mem::uninitialized(); = note: enums with no variants have no valid value error: the type `&i32` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:61:34 + --> $DIR/uninitialized-zeroed.rs:60:34 | LL | let _val: &'static i32 = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | let _val: &'static i32 = mem::zeroed(); = note: references must be non-null error: the type `&i32` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:62:34 + --> $DIR/uninitialized-zeroed.rs:61:34 | LL | let _val: &'static i32 = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | let _val: &'static i32 = mem::uninitialized(); = note: references must be non-null error: the type `Ref` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:64:25 + --> $DIR/uninitialized-zeroed.rs:63:25 | LL | let _val: Ref = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -153,13 +153,13 @@ LL | let _val: Ref = mem::zeroed(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: references must be non-null (in this struct field) - --> $DIR/uninitialized-zeroed.rs:15:12 + --> $DIR/uninitialized-zeroed.rs:14:12 | LL | struct Ref(&'static i32); | ^^^^^^^^^^^^ error: the type `Ref` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:65:25 + --> $DIR/uninitialized-zeroed.rs:64:25 | LL | let _val: Ref = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -168,13 +168,13 @@ LL | let _val: Ref = mem::uninitialized(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: references must be non-null (in this struct field) - --> $DIR/uninitialized-zeroed.rs:15:12 + --> $DIR/uninitialized-zeroed.rs:14:12 | LL | struct Ref(&'static i32); | ^^^^^^^^^^^^ error: the type `fn()` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:67:26 + --> $DIR/uninitialized-zeroed.rs:66:26 | LL | let _val: fn() = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -185,7 +185,7 @@ LL | let _val: fn() = mem::zeroed(); = note: function pointers must be non-null error: the type `fn()` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:68:26 + --> $DIR/uninitialized-zeroed.rs:67:26 | LL | let _val: fn() = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -196,7 +196,7 @@ LL | let _val: fn() = mem::uninitialized(); = note: function pointers must be non-null error: the type `Wrap` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:70:32 + --> $DIR/uninitialized-zeroed.rs:69:32 | LL | let _val: Wrap = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -205,13 +205,13 @@ LL | let _val: Wrap = mem::zeroed(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: function pointers must be non-null (in this struct field) - --> $DIR/uninitialized-zeroed.rs:18:18 + --> $DIR/uninitialized-zeroed.rs:17:18 | LL | struct Wrap { wrapped: T } | ^^^^^^^^^^ error: the type `Wrap` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:71:32 + --> $DIR/uninitialized-zeroed.rs:70:32 | LL | let _val: Wrap = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -220,13 +220,13 @@ LL | let _val: Wrap = mem::uninitialized(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: function pointers must be non-null (in this struct field) - --> $DIR/uninitialized-zeroed.rs:18:18 + --> $DIR/uninitialized-zeroed.rs:17:18 | LL | struct Wrap { wrapped: T } | ^^^^^^^^^^ error: the type `WrapEnum` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:73:36 + --> $DIR/uninitialized-zeroed.rs:72:36 | LL | let _val: WrapEnum = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -235,13 +235,13 @@ LL | let _val: WrapEnum = mem::zeroed(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: function pointers must be non-null (in this enum field) - --> $DIR/uninitialized-zeroed.rs:19:28 + --> $DIR/uninitialized-zeroed.rs:18:28 | LL | enum WrapEnum { Wrapped(T) } | ^ error: the type `WrapEnum` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:74:36 + --> $DIR/uninitialized-zeroed.rs:73:36 | LL | let _val: WrapEnum = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -250,13 +250,13 @@ LL | let _val: WrapEnum = mem::uninitialized(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: function pointers must be non-null (in this enum field) - --> $DIR/uninitialized-zeroed.rs:19:28 + --> $DIR/uninitialized-zeroed.rs:18:28 | LL | enum WrapEnum { Wrapped(T) } | ^ error: the type `Wrap<(RefPair, i32)>` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:76:42 + --> $DIR/uninitialized-zeroed.rs:75:42 | LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -265,13 +265,13 @@ LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: references must be non-null (in this struct field) - --> $DIR/uninitialized-zeroed.rs:16:16 + --> $DIR/uninitialized-zeroed.rs:15:16 | LL | struct RefPair((&'static i32, i32)); | ^^^^^^^^^^^^^^^^^^^ error: the type `Wrap<(RefPair, i32)>` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:77:42 + --> $DIR/uninitialized-zeroed.rs:76:42 | LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -280,13 +280,13 @@ LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: references must be non-null (in this struct field) - --> $DIR/uninitialized-zeroed.rs:16:16 + --> $DIR/uninitialized-zeroed.rs:15:16 | LL | struct RefPair((&'static i32, i32)); | ^^^^^^^^^^^^^^^^^^^ error: the type `NonNull` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:79:34 + --> $DIR/uninitialized-zeroed.rs:78:34 | LL | let _val: NonNull = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -297,7 +297,7 @@ LL | let _val: NonNull = mem::zeroed(); = note: `std::ptr::NonNull` must be non-null error: the type `NonNull` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:80:34 + --> $DIR/uninitialized-zeroed.rs:79:34 | LL | let _val: NonNull = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -308,7 +308,7 @@ LL | let _val: NonNull = mem::uninitialized(); = note: `std::ptr::NonNull` must be non-null error: the type `*const dyn Send` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:82:37 + --> $DIR/uninitialized-zeroed.rs:81:37 | LL | let _val: *const dyn Send = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -319,7 +319,7 @@ LL | let _val: *const dyn Send = mem::zeroed(); = note: the vtable of a wide raw pointer must be non-null error: the type `*const dyn Send` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:83:37 + --> $DIR/uninitialized-zeroed.rs:82:37 | LL | let _val: *const dyn Send = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -330,7 +330,7 @@ LL | let _val: *const dyn Send = mem::uninitialized(); = note: the vtable of a wide raw pointer must be non-null error: the type `bool` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:87:26 + --> $DIR/uninitialized-zeroed.rs:86:26 | LL | let _val: bool = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -341,7 +341,7 @@ LL | let _val: bool = mem::uninitialized(); = note: booleans must be either `true` or `false` error: the type `Wrap` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:90:32 + --> $DIR/uninitialized-zeroed.rs:89:32 | LL | let _val: Wrap = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -350,13 +350,13 @@ LL | let _val: Wrap = mem::uninitialized(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: characters must be a valid Unicode codepoint (in this struct field) - --> $DIR/uninitialized-zeroed.rs:18:18 + --> $DIR/uninitialized-zeroed.rs:17:18 | LL | struct Wrap { wrapped: T } | ^^^^^^^^^^ error: the type `NonBig` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:93:28 + --> $DIR/uninitialized-zeroed.rs:92:28 | LL | let _val: NonBig = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -367,7 +367,7 @@ LL | let _val: NonBig = mem::uninitialized(); = note: `NonBig` must be initialized inside its custom valid range error: the type `Fruit` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:96:27 + --> $DIR/uninitialized-zeroed.rs:95:27 | LL | let _val: Fruit = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -376,7 +376,7 @@ LL | let _val: Fruit = mem::uninitialized(); | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | note: enums have to be initialized to a variant - --> $DIR/uninitialized-zeroed.rs:27:1 + --> $DIR/uninitialized-zeroed.rs:26:1 | LL | / enum Fruit { LL | | Apple, @@ -385,7 +385,7 @@ LL | | } | |_^ error: the type `&i32` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:99:34 + --> $DIR/uninitialized-zeroed.rs:98:34 | LL | let _val: &'static i32 = mem::transmute(0usize); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -396,7 +396,7 @@ LL | let _val: &'static i32 = mem::transmute(0usize); = note: references must be non-null error: the type `&[i32]` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:100:36 + --> $DIR/uninitialized-zeroed.rs:99:36 | LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -407,7 +407,7 @@ LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); = note: references must be non-null error: the type `NonZeroU32` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:101:32 + --> $DIR/uninitialized-zeroed.rs:100:32 | LL | let _val: NonZeroU32 = mem::transmute(0); | ^^^^^^^^^^^^^^^^^ @@ -418,7 +418,7 @@ LL | let _val: NonZeroU32 = mem::transmute(0); = note: `std::num::NonZeroU32` must be non-null error: the type `NonNull` does not permit zero-initialization - --> $DIR/uninitialized-zeroed.rs:104:34 + --> $DIR/uninitialized-zeroed.rs:103:34 | LL | let _val: NonNull = MaybeUninit::zeroed().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -429,7 +429,7 @@ LL | let _val: NonNull = MaybeUninit::zeroed().assume_init(); = note: `std::ptr::NonNull` must be non-null error: the type `NonNull` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:105:34 + --> $DIR/uninitialized-zeroed.rs:104:34 | LL | let _val: NonNull = MaybeUninit::uninit().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -440,7 +440,7 @@ LL | let _val: NonNull = MaybeUninit::uninit().assume_init(); = note: `std::ptr::NonNull` must be non-null error: the type `bool` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:106:26 + --> $DIR/uninitialized-zeroed.rs:105:26 | LL | let _val: bool = MaybeUninit::uninit().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs b/src/test/ui/loops/loops-reject-duplicate-labels-2.rs index a0f3aeffe9f..3a860f508ff 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs +++ b/src/test/ui/loops/loops-reject-duplicate-labels-2.rs @@ -1,6 +1,5 @@ // check-pass -// ignore-tidy-linelength // Issue #21633: reject duplicate loop labels in function bodies. // diff --git a/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr b/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr index 724c36e5203..6c53d04e107 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr +++ b/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr @@ -1,5 +1,5 @@ warning: label name `'fl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:14:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:13:7 | LL | { 'fl: for _ in 0..10 { break; } } | --- first declared here @@ -7,7 +7,7 @@ LL | { 'fl: loop { break; } } | ^^^ label `'fl` already in scope warning: label name `'lf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:16:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:15:7 | LL | { 'lf: loop { break; } } | --- first declared here @@ -15,7 +15,7 @@ LL | { 'lf: for _ in 0..10 { break; } } | ^^^ label `'lf` already in scope warning: label name `'wl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:18:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:17:7 | LL | { 'wl: while 2 > 1 { break; } } | --- first declared here @@ -23,7 +23,7 @@ LL | { 'wl: loop { break; } } | ^^^ label `'wl` already in scope warning: label name `'lw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:20:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:19:7 | LL | { 'lw: loop { break; } } | --- first declared here @@ -31,7 +31,7 @@ LL | { 'lw: while 2 > 1 { break; } } | ^^^ label `'lw` already in scope warning: label name `'fw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:22:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:21:7 | LL | { 'fw: for _ in 0..10 { break; } } | --- first declared here @@ -39,7 +39,7 @@ LL | { 'fw: while 2 > 1 { break; } } | ^^^ label `'fw` already in scope warning: label name `'wf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:24:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:23:7 | LL | { 'wf: while 2 > 1 { break; } } | --- first declared here @@ -47,7 +47,7 @@ LL | { 'wf: for _ in 0..10 { break; } } | ^^^ label `'wf` already in scope warning: label name `'tl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:26:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:25:7 | LL | { 'tl: while let Some(_) = None:: { break; } } | --- first declared here @@ -55,7 +55,7 @@ LL | { 'tl: loop { break; } } | ^^^ label `'tl` already in scope warning: label name `'lt` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:28:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:27:7 | LL | { 'lt: loop { break; } } | --- first declared here diff --git a/src/test/ui/loops/loops-reject-duplicate-labels.rs b/src/test/ui/loops/loops-reject-duplicate-labels.rs index a501ac18588..d9334ce3857 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels.rs +++ b/src/test/ui/loops/loops-reject-duplicate-labels.rs @@ -1,6 +1,5 @@ // check-pass -// ignore-tidy-linelength // Issue #21633: reject duplicate loop labels in function bodies. // This is testing the exact cases that are in the issue description. diff --git a/src/test/ui/loops/loops-reject-duplicate-labels.stderr b/src/test/ui/loops/loops-reject-duplicate-labels.stderr index 2d112812017..5bdf64849f3 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels.stderr +++ b/src/test/ui/loops/loops-reject-duplicate-labels.stderr @@ -1,5 +1,5 @@ warning: label name `'fl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:11:5 + --> $DIR/loops-reject-duplicate-labels.rs:10:5 | LL | 'fl: for _ in 0..10 { break; } | --- first declared here @@ -7,7 +7,7 @@ LL | 'fl: loop { break; } | ^^^ label `'fl` already in scope warning: label name `'lf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:14:5 + --> $DIR/loops-reject-duplicate-labels.rs:13:5 | LL | 'lf: loop { break; } | --- first declared here @@ -15,7 +15,7 @@ LL | 'lf: for _ in 0..10 { break; } | ^^^ label `'lf` already in scope warning: label name `'wl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:16:5 + --> $DIR/loops-reject-duplicate-labels.rs:15:5 | LL | 'wl: while 2 > 1 { break; } | --- first declared here @@ -23,7 +23,7 @@ LL | 'wl: loop { break; } | ^^^ label `'wl` already in scope warning: label name `'lw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:18:5 + --> $DIR/loops-reject-duplicate-labels.rs:17:5 | LL | 'lw: loop { break; } | --- first declared here @@ -31,7 +31,7 @@ LL | 'lw: while 2 > 1 { break; } | ^^^ label `'lw` already in scope warning: label name `'fw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:20:5 + --> $DIR/loops-reject-duplicate-labels.rs:19:5 | LL | 'fw: for _ in 0..10 { break; } | --- first declared here @@ -39,7 +39,7 @@ LL | 'fw: while 2 > 1 { break; } | ^^^ label `'fw` already in scope warning: label name `'wf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:22:5 + --> $DIR/loops-reject-duplicate-labels.rs:21:5 | LL | 'wf: while 2 > 1 { break; } | --- first declared here @@ -47,7 +47,7 @@ LL | 'wf: for _ in 0..10 { break; } | ^^^ label `'wf` already in scope warning: label name `'tl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:24:5 + --> $DIR/loops-reject-duplicate-labels.rs:23:5 | LL | 'tl: while let Some(_) = None:: { break; } | --- first declared here @@ -55,7 +55,7 @@ LL | 'tl: loop { break; } | ^^^ label `'tl` already in scope warning: label name `'lt` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:26:5 + --> $DIR/loops-reject-duplicate-labels.rs:25:5 | LL | 'lt: loop { break; } | --- first declared here diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.fixed b/src/test/ui/macros/macro-or-patterns-back-compat.fixed index 4e8b057457c..f089f0fda4e 100644 --- a/src/test/ui/macros/macro-or-patterns-back-compat.fixed +++ b/src/test/ui/macros/macro-or-patterns-back-compat.fixed @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // run-rustfix #![feature(edition_macro_pats)] diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.rs b/src/test/ui/macros/macro-or-patterns-back-compat.rs index 023abae36d0..0252581d5f1 100644 --- a/src/test/ui/macros/macro-or-patterns-back-compat.rs +++ b/src/test/ui/macros/macro-or-patterns-back-compat.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // run-rustfix #![feature(edition_macro_pats)] diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.stderr b/src/test/ui/macros/macro-or-patterns-back-compat.stderr index 29bbd696033..d8f19fa5807 100644 --- a/src/test/ui/macros/macro-or-patterns-back-compat.stderr +++ b/src/test/ui/macros/macro-or-patterns-back-compat.stderr @@ -1,29 +1,29 @@ error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro - --> $DIR/macro-or-patterns-back-compat.rs:7:21 + --> $DIR/macro-or-patterns-back-compat.rs:6:21 | LL | macro_rules! foo { ($x:pat | $y:pat) => {} } | ^^^^^^ help: use pat2015 to preserve semantics: `$x:pat2015` | note: the lint level is defined here - --> $DIR/macro-or-patterns-back-compat.rs:5:9 + --> $DIR/macro-or-patterns-back-compat.rs:4:9 | LL | #![deny(or_patterns_back_compat)] | ^^^^^^^^^^^^^^^^^^^^^^^ error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro - --> $DIR/macro-or-patterns-back-compat.rs:8:23 + --> $DIR/macro-or-patterns-back-compat.rs:7:23 | LL | macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} } | ^^^^^^ help: use pat2015 to preserve semantics: `$x:pat2015` error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro - --> $DIR/macro-or-patterns-back-compat.rs:11:21 + --> $DIR/macro-or-patterns-back-compat.rs:10:21 | LL | macro_rules! ogg { ($x:pat | $y:pat2015) => {} } | ^^^^^^ help: use pat2015 to preserve semantics: `$x:pat2015` error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro - --> $DIR/macro-or-patterns-back-compat.rs:13:26 + --> $DIR/macro-or-patterns-back-compat.rs:12:26 | LL | ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => { | ^^^^^^^^ help: use pat2015 to preserve semantics: `$pat:pat2015` diff --git a/src/test/ui/methods/method-call-lifetime-args-fail.rs b/src/test/ui/methods/method-call-lifetime-args-fail.rs index 8a840ba62cc..af173851252 100644 --- a/src/test/ui/methods/method-call-lifetime-args-fail.rs +++ b/src/test/ui/methods/method-call-lifetime-args-fail.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - struct S; impl S { diff --git a/src/test/ui/methods/method-call-lifetime-args-fail.stderr b/src/test/ui/methods/method-call-lifetime-args-fail.stderr index 34a2e3dec2e..2907309c27c 100644 --- a/src/test/ui/methods/method-call-lifetime-args-fail.stderr +++ b/src/test/ui/methods/method-call-lifetime-args-fail.stderr @@ -1,5 +1,5 @@ error[E0107]: this associated function takes 2 lifetime arguments but only 1 lifetime argument was supplied - --> $DIR/method-call-lifetime-args-fail.rs:18:7 + --> $DIR/method-call-lifetime-args-fail.rs:16:7 | LL | S.early::<'static>(); | ^^^^^ ------- supplied 1 lifetime argument @@ -7,7 +7,7 @@ LL | S.early::<'static>(); | expected 2 lifetime arguments | note: associated function defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/method-call-lifetime-args-fail.rs:8:8 + --> $DIR/method-call-lifetime-args-fail.rs:6:8 | LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} } | ^^^^^ -- -- @@ -17,7 +17,7 @@ LL | S.early::<'static, 'b>(); | ^^^^ error[E0107]: this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied - --> $DIR/method-call-lifetime-args-fail.rs:20:7 + --> $DIR/method-call-lifetime-args-fail.rs:18:7 | LL | S.early::<'static, 'static, 'static>(); | ^^^^^ --------- help: remove this lifetime argument @@ -25,19 +25,31 @@ LL | S.early::<'static, 'static, 'static>(); | expected 2 lifetime arguments | note: associated function defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/method-call-lifetime-args-fail.rs:8:8 + --> $DIR/method-call-lifetime-args-fail.rs:6:8 | LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} } | ^^^^^ -- -- error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/method-call-lifetime-args-fail.rs:29:15 + --> $DIR/method-call-lifetime-args-fail.rs:27:15 | LL | S::late::<'static>(S, &0, &0); | ^^^^^^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:6:13 + --> $DIR/method-call-lifetime-args-fail.rs:4:13 + | +LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} + | ^^ + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/method-call-lifetime-args-fail.rs:29:15 + | +LL | S::late::<'static, 'static>(S, &0, &0); + | ^^^^^^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/method-call-lifetime-args-fail.rs:4:13 | LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} | ^^ @@ -45,59 +57,59 @@ LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present --> $DIR/method-call-lifetime-args-fail.rs:31:15 | -LL | S::late::<'static, 'static>(S, &0, &0); - | ^^^^^^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:6:13 - | -LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} - | ^^ - -error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/method-call-lifetime-args-fail.rs:33:15 - | LL | S::late::<'static, 'static, 'static>(S, &0, &0); | ^^^^^^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:6:13 + --> $DIR/method-call-lifetime-args-fail.rs:4:13 | LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} | ^^ error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/method-call-lifetime-args-fail.rs:36:21 + --> $DIR/method-call-lifetime-args-fail.rs:34:21 | LL | S::late_early::<'static, 'static>(S, &0); | ^^^^^^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:9:19 + --> $DIR/method-call-lifetime-args-fail.rs:7:19 | LL | fn late_early<'a, 'b>(self, _: &'a u8) -> &'b u8 { loop {} } | ^^ error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/method-call-lifetime-args-fail.rs:38:21 + --> $DIR/method-call-lifetime-args-fail.rs:36:21 | LL | S::late_early::<'static, 'static, 'static>(S, &0); | ^^^^^^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:9:19 + --> $DIR/method-call-lifetime-args-fail.rs:7:19 | LL | fn late_early<'a, 'b>(self, _: &'a u8) -> &'b u8 { loop {} } | ^^ error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/method-call-lifetime-args-fail.rs:42:24 + --> $DIR/method-call-lifetime-args-fail.rs:40:24 | LL | S::late_implicit::<'static>(S, &0, &0); | ^^^^^^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:7:31 + --> $DIR/method-call-lifetime-args-fail.rs:5:31 + | +LL | fn late_implicit(self, _: &u8, _: &u8) {} + | ^ + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/method-call-lifetime-args-fail.rs:42:24 + | +LL | S::late_implicit::<'static, 'static>(S, &0, &0); + | ^^^^^^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/method-call-lifetime-args-fail.rs:5:31 | LL | fn late_implicit(self, _: &u8, _: &u8) {} | ^ @@ -105,101 +117,89 @@ LL | fn late_implicit(self, _: &u8, _: &u8) {} error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present --> $DIR/method-call-lifetime-args-fail.rs:44:24 | -LL | S::late_implicit::<'static, 'static>(S, &0, &0); - | ^^^^^^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:7:31 - | -LL | fn late_implicit(self, _: &u8, _: &u8) {} - | ^ - -error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/method-call-lifetime-args-fail.rs:46:24 - | LL | S::late_implicit::<'static, 'static, 'static>(S, &0, &0); | ^^^^^^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:7:31 + --> $DIR/method-call-lifetime-args-fail.rs:5:31 | LL | fn late_implicit(self, _: &u8, _: &u8) {} | ^ error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/method-call-lifetime-args-fail.rs:49:30 + --> $DIR/method-call-lifetime-args-fail.rs:47:30 | LL | S::late_implicit_early::<'static, 'static>(S, &0); | ^^^^^^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:10:41 + --> $DIR/method-call-lifetime-args-fail.rs:8:41 | LL | fn late_implicit_early<'b>(self, _: &u8) -> &'b u8 { loop {} } | ^ error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/method-call-lifetime-args-fail.rs:51:30 + --> $DIR/method-call-lifetime-args-fail.rs:49:30 | LL | S::late_implicit_early::<'static, 'static, 'static>(S, &0); | ^^^^^^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:10:41 + --> $DIR/method-call-lifetime-args-fail.rs:8:41 | LL | fn late_implicit_early<'b>(self, _: &u8) -> &'b u8 { loop {} } | ^ error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/method-call-lifetime-args-fail.rs:54:35 + --> $DIR/method-call-lifetime-args-fail.rs:52:35 | LL | S::late_implicit_self_early::<'static, 'static>(&S); | ^^^^^^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:11:37 + --> $DIR/method-call-lifetime-args-fail.rs:9:37 | LL | fn late_implicit_self_early<'b>(&self) -> &'b u8 { loop {} } | ^ error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/method-call-lifetime-args-fail.rs:56:35 + --> $DIR/method-call-lifetime-args-fail.rs:54:35 | LL | S::late_implicit_self_early::<'static, 'static, 'static>(&S); | ^^^^^^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:11:37 + --> $DIR/method-call-lifetime-args-fail.rs:9:37 | LL | fn late_implicit_self_early<'b>(&self) -> &'b u8 { loop {} } | ^ error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/method-call-lifetime-args-fail.rs:59:28 + --> $DIR/method-call-lifetime-args-fail.rs:57:28 | LL | S::late_unused_early::<'static, 'static>(S); | ^^^^^^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:12:26 + --> $DIR/method-call-lifetime-args-fail.rs:10:26 | LL | fn late_unused_early<'a, 'b>(self) -> &'b u8 { loop {} } | ^^ error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/method-call-lifetime-args-fail.rs:61:28 + --> $DIR/method-call-lifetime-args-fail.rs:59:28 | LL | S::late_unused_early::<'static, 'static, 'static>(S); | ^^^^^^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/method-call-lifetime-args-fail.rs:12:26 + --> $DIR/method-call-lifetime-args-fail.rs:10:26 | LL | fn late_unused_early<'a, 'b>(self) -> &'b u8 { loop {} } | ^^ error[E0107]: this associated function takes 2 lifetime arguments but only 1 lifetime argument was supplied - --> $DIR/method-call-lifetime-args-fail.rs:65:8 + --> $DIR/method-call-lifetime-args-fail.rs:63:8 | LL | S::early::<'static>(S); | ^^^^^ ------- supplied 1 lifetime argument @@ -207,7 +207,7 @@ LL | S::early::<'static>(S); | expected 2 lifetime arguments | note: associated function defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/method-call-lifetime-args-fail.rs:8:8 + --> $DIR/method-call-lifetime-args-fail.rs:6:8 | LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} } | ^^^^^ -- -- @@ -217,7 +217,7 @@ LL | S::early::<'static, 'b>(S); | ^^^^ error[E0107]: this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied - --> $DIR/method-call-lifetime-args-fail.rs:67:8 + --> $DIR/method-call-lifetime-args-fail.rs:65:8 | LL | S::early::<'static, 'static, 'static>(S); | ^^^^^ --------- help: remove this lifetime argument @@ -225,7 +225,7 @@ LL | S::early::<'static, 'static, 'static>(S); | expected 2 lifetime arguments | note: associated function defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/method-call-lifetime-args-fail.rs:8:8 + --> $DIR/method-call-lifetime-args-fail.rs:6:8 | LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} } | ^^^^^ -- -- diff --git a/src/test/ui/nll/issue-51268.rs b/src/test/ui/nll/issue-51268.rs index 12d0449abb1..dcdedf7d4c5 100644 --- a/src/test/ui/nll/issue-51268.rs +++ b/src/test/ui/nll/issue-51268.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - struct Bar; impl Bar { diff --git a/src/test/ui/nll/issue-51268.stderr b/src/test/ui/nll/issue-51268.stderr index 420c94f8e1b..e6dadc9f6ce 100644 --- a/src/test/ui/nll/issue-51268.stderr +++ b/src/test/ui/nll/issue-51268.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `self.thing` as mutable because it is also borrowed as immutable - --> $DIR/issue-51268.rs:16:9 + --> $DIR/issue-51268.rs:14:9 | LL | self.thing.bar(|| { | ^ --- -- immutable borrow occurs here diff --git a/src/test/ui/nll/issue-57100.rs b/src/test/ui/nll/issue-57100.rs index c7f3e9d7303..f15929334bb 100644 --- a/src/test/ui/nll/issue-57100.rs +++ b/src/test/ui/nll/issue-57100.rs @@ -1,6 +1,5 @@ #![allow(unused)] -// ignore-tidy-linelength // This tests the error messages for borrows of union fields when the unions are embedded in other // structs or unions. diff --git a/src/test/ui/nll/issue-57100.stderr b/src/test/ui/nll/issue-57100.stderr index 5f733c14036..523c3e8d0a2 100644 --- a/src/test/ui/nll/issue-57100.stderr +++ b/src/test/ui/nll/issue-57100.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `r.r2_union.f3_union` (via `r.r2_union.f3_union.s2_leaf.l1_u8`) as immutable because it is also borrowed as mutable (via `r.r2_union.f3_union.s1_leaf.l1_u8`) - --> $DIR/issue-57100.rs:43:20 + --> $DIR/issue-57100.rs:42:20 | LL | let mref = &mut r.r2_union.f3_union.s1_leaf.l1_u8; | -------------------------------------- mutable borrow occurs here (via `r.r2_union.f3_union.s1_leaf.l1_u8`) @@ -13,7 +13,7 @@ LL | println!("{} {}", mref, nref) = note: `r.r2_union.f3_union.s2_leaf.l1_u8` is a field of the union `Second`, so it overlaps the field `r.r2_union.f3_union.s1_leaf.l1_u8` error[E0502]: cannot borrow `r.r2_union` (via `r.r2_union.f1_leaf.l1_u8`) as immutable because it is also borrowed as mutable (via `r.r2_union.f2_leaf.l1_u8`) - --> $DIR/issue-57100.rs:61:20 + --> $DIR/issue-57100.rs:60:20 | LL | let mref = &mut r.r2_union.f2_leaf.l1_u8; | ----------------------------- mutable borrow occurs here (via `r.r2_union.f2_leaf.l1_u8`) diff --git a/src/test/ui/non-ice-error-on-worker-io-fail.rs b/src/test/ui/non-ice-error-on-worker-io-fail.rs index 30779fc65c0..134e7d420e3 100644 --- a/src/test/ui/non-ice-error-on-worker-io-fail.rs +++ b/src/test/ui/non-ice-error-on-worker-io-fail.rs @@ -24,7 +24,6 @@ // On Linux, we get an error like the below // normalize-stderr-test "couldn't create a temp dir.*" -> "io error modifying /does-not-exist/" -// ignore-tidy-linelength // ignore-windows - this is a unix-specific test // ignore-emscripten - the file-system issues do not replicate here // ignore-wasm - the file-system issues do not replicate here diff --git a/src/test/ui/panic-runtime/two-panic-runtimes.rs b/src/test/ui/panic-runtime/two-panic-runtimes.rs index c968b5ea1e1..7ec658ebcf2 100644 --- a/src/test/ui/panic-runtime/two-panic-runtimes.rs +++ b/src/test/ui/panic-runtime/two-panic-runtimes.rs @@ -1,7 +1,6 @@ // build-fail // dont-check-compiler-stderr // error-pattern:cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2 -// ignore-tidy-linelength // aux-build:panic-runtime-unwind.rs // aux-build:panic-runtime-unwind2.rs // aux-build:panic-runtime-lang-items.rs diff --git a/src/test/ui/panic-runtime/unwind-tables-panic-required.rs b/src/test/ui/panic-runtime/unwind-tables-panic-required.rs index 6393a27046b..79e91879051 100644 --- a/src/test/ui/panic-runtime/unwind-tables-panic-required.rs +++ b/src/test/ui/panic-runtime/unwind-tables-panic-required.rs @@ -3,7 +3,6 @@ // // dont-check-compiler-stderr // compile-flags: -C panic=unwind -C force-unwind-tables=no -// ignore-tidy-linelength // // error-pattern: panic=unwind requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no`. diff --git a/src/test/ui/panic-runtime/unwind-tables-target-required.rs b/src/test/ui/panic-runtime/unwind-tables-target-required.rs index 14c17893764..3abb52b675a 100644 --- a/src/test/ui/panic-runtime/unwind-tables-target-required.rs +++ b/src/test/ui/panic-runtime/unwind-tables-target-required.rs @@ -3,7 +3,6 @@ // // only-x86_64-windows-msvc // compile-flags: -C force-unwind-tables=no -// ignore-tidy-linelength // // error-pattern: target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no`. diff --git a/src/test/ui/parser/duplicate-visibility.rs b/src/test/ui/parser/duplicate-visibility.rs index 97f19b3da45..87ba230eab5 100644 --- a/src/test/ui/parser/duplicate-visibility.rs +++ b/src/test/ui/parser/duplicate-visibility.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - fn main() {} extern "C" { diff --git a/src/test/ui/parser/duplicate-visibility.stderr b/src/test/ui/parser/duplicate-visibility.stderr index 6ac27078ea3..d9815fc7395 100644 --- a/src/test/ui/parser/duplicate-visibility.stderr +++ b/src/test/ui/parser/duplicate-visibility.stderr @@ -1,5 +1,5 @@ error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found keyword `pub` - --> $DIR/duplicate-visibility.rs:6:9 + --> $DIR/duplicate-visibility.rs:4:9 | LL | extern "C" { | - while parsing this item list starting here diff --git a/src/test/ui/parser/issue-66357-unexpected-unreachable.rs b/src/test/ui/parser/issue-66357-unexpected-unreachable.rs index 5ec143fae23..aed428bfc2a 100644 --- a/src/test/ui/parser/issue-66357-unexpected-unreachable.rs +++ b/src/test/ui/parser/issue-66357-unexpected-unreachable.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // The problem in #66357 was that the call trace: // // - parse_fn_block_decl diff --git a/src/test/ui/parser/issue-66357-unexpected-unreachable.stderr b/src/test/ui/parser/issue-66357-unexpected-unreachable.stderr index c3810999d23..332711df72f 100644 --- a/src/test/ui/parser/issue-66357-unexpected-unreachable.stderr +++ b/src/test/ui/parser/issue-66357-unexpected-unreachable.stderr @@ -1,11 +1,11 @@ error: expected one of `,` or `:`, found `(` - --> $DIR/issue-66357-unexpected-unreachable.rs:14:13 + --> $DIR/issue-66357-unexpected-unreachable.rs:12:13 | LL | fn f() { |[](* } | ^ expected one of `,` or `:` error: expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*` - --> $DIR/issue-66357-unexpected-unreachable.rs:14:14 + --> $DIR/issue-66357-unexpected-unreachable.rs:12:14 | LL | fn f() { |[](* } | -^ help: `)` may belong here diff --git a/src/test/ui/parser/unicode-quote-chars.rs b/src/test/ui/parser/unicode-quote-chars.rs index eeaea3628bb..868d2b227b7 100644 --- a/src/test/ui/parser/unicode-quote-chars.rs +++ b/src/test/ui/parser/unicode-quote-chars.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - fn main() { println!(“hello world”); //~^ ERROR unknown start of token: \u{201c} diff --git a/src/test/ui/parser/unicode-quote-chars.stderr b/src/test/ui/parser/unicode-quote-chars.stderr index d9ec92b3f8a..04ea0c6e95f 100644 --- a/src/test/ui/parser/unicode-quote-chars.stderr +++ b/src/test/ui/parser/unicode-quote-chars.stderr @@ -1,5 +1,5 @@ error: unknown start of token: \u{201c} - --> $DIR/unicode-quote-chars.rs:4:14 + --> $DIR/unicode-quote-chars.rs:2:14 | LL | println!(“hello world”); | ^ @@ -10,7 +10,7 @@ LL | println!("hello world"); | ^^^^^^^^^^^^^ error: unknown start of token: \u{201d} - --> $DIR/unicode-quote-chars.rs:4:26 + --> $DIR/unicode-quote-chars.rs:2:26 | LL | println!(“hello world”); | ^ @@ -21,7 +21,7 @@ LL | println!(“hello world"); | ^ error: expected `,`, found `world` - --> $DIR/unicode-quote-chars.rs:4:21 + --> $DIR/unicode-quote-chars.rs:2:21 | LL | println!(“hello world”); | ^^^^^ expected `,` diff --git a/src/test/ui/pattern/usefulness/refutable-pattern-errors.rs b/src/test/ui/pattern/usefulness/refutable-pattern-errors.rs index 75658c490c4..7c9aa51e748 100644 --- a/src/test/ui/pattern/usefulness/refutable-pattern-errors.rs +++ b/src/test/ui/pattern/usefulness/refutable-pattern-errors.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - fn func((1, (Some(1), 2..=3)): (isize, (Option, isize))) { } //~^ ERROR refutable pattern in function argument: `(_, _)` not covered diff --git a/src/test/ui/pattern/usefulness/refutable-pattern-errors.stderr b/src/test/ui/pattern/usefulness/refutable-pattern-errors.stderr index 99af71cadfc..74ec646e31c 100644 --- a/src/test/ui/pattern/usefulness/refutable-pattern-errors.stderr +++ b/src/test/ui/pattern/usefulness/refutable-pattern-errors.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in function argument: `(_, _)` not covered - --> $DIR/refutable-pattern-errors.rs:3:9 + --> $DIR/refutable-pattern-errors.rs:1:9 | LL | fn func((1, (Some(1), 2..=3)): (isize, (Option, isize))) { } | ^^^^^^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered @@ -7,7 +7,7 @@ LL | fn func((1, (Some(1), 2..=3)): (isize, (Option, isize))) { } = note: the matched value is of type `(isize, (Option, isize))` error[E0005]: refutable pattern in local binding: `(i32::MIN..=0_i32, _)` and `(2_i32..=i32::MAX, _)` not covered - --> $DIR/refutable-pattern-errors.rs:7:9 + --> $DIR/refutable-pattern-errors.rs:5:9 | LL | let (1, (Some(1), 2..=3)) = (1, (None, 2)); | ^^^^^^^^^^^^^^^^^^^^^ patterns `(i32::MIN..=0_i32, _)` and `(2_i32..=i32::MAX, _)` not covered diff --git a/src/test/ui/privacy/associated-item-privacy-trait.rs b/src/test/ui/privacy/associated-item-privacy-trait.rs index b4e98debcf3..c07aeed99c7 100644 --- a/src/test/ui/privacy/associated-item-privacy-trait.rs +++ b/src/test/ui/privacy/associated-item-privacy-trait.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![feature(decl_macro, associated_type_defaults)] #![allow(unused, private_in_public)] diff --git a/src/test/ui/privacy/associated-item-privacy-trait.stderr b/src/test/ui/privacy/associated-item-privacy-trait.stderr index 8e58a2fa08d..e36ce8d5415 100644 --- a/src/test/ui/privacy/associated-item-privacy-trait.stderr +++ b/src/test/ui/privacy/associated-item-privacy-trait.stderr @@ -1,5 +1,5 @@ error: type `for<'r> fn(&'r priv_trait::Pub) {::method}` is private - --> $DIR/associated-item-privacy-trait.rs:17:21 + --> $DIR/associated-item-privacy-trait.rs:15:21 | LL | let value = ::method; | ^^^^^^^^^^^^^^^^^^^^^^^ private type @@ -10,7 +10,7 @@ LL | priv_trait::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `for<'r> fn(&'r priv_trait::Pub) {::method}` is private - --> $DIR/associated-item-privacy-trait.rs:19:9 + --> $DIR/associated-item-privacy-trait.rs:17:9 | LL | value; | ^^^^^ private type @@ -21,7 +21,7 @@ LL | priv_trait::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `for<'r> fn(&'r Self) {::method}` is private - --> $DIR/associated-item-privacy-trait.rs:21:13 + --> $DIR/associated-item-privacy-trait.rs:19:13 | LL | Pub.method(); | ^^^^^^ private type @@ -32,7 +32,7 @@ LL | priv_trait::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: associated constant `::CONST` is private - --> $DIR/associated-item-privacy-trait.rs:23:9 + --> $DIR/associated-item-privacy-trait.rs:21:9 | LL | ::CONST; | ^^^^^^^^^^^^^^^^^^^^^^ private associated constant @@ -43,7 +43,7 @@ LL | priv_trait::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: associated type `::AssocTy` is private - --> $DIR/associated-item-privacy-trait.rs:25:16 + --> $DIR/associated-item-privacy-trait.rs:23:16 | LL | let _: ::AssocTy; | ^^^^^^^^^^^^^^^^^^^^^^^^ private associated type @@ -54,7 +54,7 @@ LL | priv_trait::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `PrivTr` is private - --> $DIR/associated-item-privacy-trait.rs:27:34 + --> $DIR/associated-item-privacy-trait.rs:25:34 | LL | pub type InSignatureTy = ::AssocTy; | ^^^^^^^^^^^^^^^^^^^^^^^^ private trait @@ -65,7 +65,7 @@ LL | priv_trait::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `PrivTr` is private - --> $DIR/associated-item-privacy-trait.rs:29:34 + --> $DIR/associated-item-privacy-trait.rs:27:34 | LL | pub trait InSignatureTr: PrivTr {} | ^^^^^^ private trait @@ -76,7 +76,7 @@ LL | priv_trait::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: trait `PrivTr` is private - --> $DIR/associated-item-privacy-trait.rs:31:14 + --> $DIR/associated-item-privacy-trait.rs:29:14 | LL | impl PrivTr for u8 {} | ^^^^^^ private trait @@ -87,7 +87,7 @@ LL | priv_trait::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_signature::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:48:21 + --> $DIR/associated-item-privacy-trait.rs:46:21 | LL | let value = ::method; | ^^^^^^^^^^^^^^^^^^^^^^ private type @@ -98,7 +98,7 @@ LL | priv_signature::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_signature::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:50:9 + --> $DIR/associated-item-privacy-trait.rs:48:9 | LL | value; | ^^^^^ private type @@ -109,7 +109,7 @@ LL | priv_signature::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_signature::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:52:13 + --> $DIR/associated-item-privacy-trait.rs:50:13 | LL | Pub.method(loop {}); | ^^^^^^ private type @@ -120,7 +120,7 @@ LL | priv_signature::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:69:21 + --> $DIR/associated-item-privacy-trait.rs:67:21 | LL | let value = ::method::; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ private type @@ -131,7 +131,7 @@ LL | priv_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:71:9 + --> $DIR/associated-item-privacy-trait.rs:69:9 | LL | value; | ^^^^^ private type @@ -142,7 +142,7 @@ LL | priv_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:73:9 + --> $DIR/associated-item-privacy-trait.rs:71:9 | LL | Pub.method::(); | ^^^^^^^^^^^^^^^^^^^^ private type @@ -153,7 +153,7 @@ LL | priv_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:93:21 + --> $DIR/associated-item-privacy-trait.rs:91:21 | LL | let value = ::method; | ^^^^^^^^^^^^^^^^^^^^^^ private type @@ -164,7 +164,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:95:9 + --> $DIR/associated-item-privacy-trait.rs:93:9 | LL | value; | ^^^^^ private type @@ -175,7 +175,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:97:21 + --> $DIR/associated-item-privacy-trait.rs:95:21 | LL | let value = >::method; | ^^^^^^^^^^^^^^^^^^^^^^^^^ private type @@ -186,7 +186,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:99:9 + --> $DIR/associated-item-privacy-trait.rs:97:9 | LL | value; | ^^^^^ private type @@ -197,7 +197,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:101:9 + --> $DIR/associated-item-privacy-trait.rs:99:9 | LL | Pub.method(); | ^^^^^^^^^^^^ private type @@ -208,7 +208,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:104:21 + --> $DIR/associated-item-privacy-trait.rs:102:21 | LL | let value = >::method; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ private type @@ -219,7 +219,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:106:9 + --> $DIR/associated-item-privacy-trait.rs:104:9 | LL | value; | ^^^^^ private type @@ -230,7 +230,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:108:9 + --> $DIR/associated-item-privacy-trait.rs:106:9 | LL | Priv.method(); | ^^^^^^^^^^^^^ private type @@ -241,7 +241,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:111:9 + --> $DIR/associated-item-privacy-trait.rs:109:9 | LL | ::CONST; | ^^^^^^^^^^^^^^^^^^^^^ private type @@ -252,7 +252,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:113:9 + --> $DIR/associated-item-privacy-trait.rs:111:9 | LL | >::CONST; | ^^^^^^^^^^^^^^^^^^^^^^^^ private type @@ -263,7 +263,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:115:9 + --> $DIR/associated-item-privacy-trait.rs:113:9 | LL | >::CONST; | ^^^^^^^^^^^^^^^^^^^^^^^^^ private type @@ -274,7 +274,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:119:30 + --> $DIR/associated-item-privacy-trait.rs:117:30 | LL | let _: >::AssocTy; | ^ private type @@ -285,7 +285,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:121:17 + --> $DIR/associated-item-privacy-trait.rs:119:17 | LL | let _: >::AssocTy; | ^^^^ private type @@ -296,7 +296,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:124:35 + --> $DIR/associated-item-privacy-trait.rs:122:35 | LL | pub type InSignatureTy1 = ::AssocTy; | ^^^^^^^^^^^^^^^^^^^^^^^ private type @@ -307,7 +307,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:126:35 + --> $DIR/associated-item-privacy-trait.rs:124:35 | LL | pub type InSignatureTy2 = >::AssocTy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ private type @@ -318,7 +318,7 @@ LL | priv_parent_substs::mac!(); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: type `priv_parent_substs::Priv` is private - --> $DIR/associated-item-privacy-trait.rs:128:14 + --> $DIR/associated-item-privacy-trait.rs:126:14 | LL | impl PubTr for u8 {} | ^^^^^ private type diff --git a/src/test/ui/proc-macro/meta-macro-hygiene.rs b/src/test/ui/proc-macro/meta-macro-hygiene.rs index 7e839f747f3..2536b2fa902 100644 --- a/src/test/ui/proc-macro/meta-macro-hygiene.rs +++ b/src/test/ui/proc-macro/meta-macro-hygiene.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // aux-build:make-macro.rs // aux-build:meta-macro.rs // edition:2018 diff --git a/src/test/ui/proc-macro/meta-macro-hygiene.stdout b/src/test/ui/proc-macro/meta-macro-hygiene.stdout index aa51fc8240d..b7a37ab10ed 100644 --- a/src/test/ui/proc-macro/meta-macro-hygiene.stdout +++ b/src/test/ui/proc-macro/meta-macro-hygiene.stdout @@ -1,8 +1,7 @@ Def site: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) -Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:24:37: 24:43 (#4) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:24:43: 24:45 (#4) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:43: 24:45 (#4) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:24:45: 24:50 (#4) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:50: 24:51 (#4) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:24:51: 24:53 (#4) }] +Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:23:37: 23:43 (#4) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:23:43: 23:45 (#4) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:23:43: 23:45 (#4) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:23:45: 23:50 (#4) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:23:50: 23:51 (#4) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:23:51: 23:53 (#4) }] Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Punct { ch: ':', spacing: Joint, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Punct { ch: ':', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Ident { ident: "dummy", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Punct { ch: '!', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }] #![feature /* 0#0 */(prelude_import)] -// ignore-tidy-linelength // aux-build:make-macro.rs // aux-build:meta-macro.rs // edition:2018 diff --git a/src/test/ui/regions/regions-enum-not-wf.rs b/src/test/ui/regions/regions-enum-not-wf.rs index 6de08f66d75..8b491ee4e30 100644 --- a/src/test/ui/regions/regions-enum-not-wf.rs +++ b/src/test/ui/regions/regions-enum-not-wf.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // Various examples of structs whose fields are not well-formed. #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-enum-not-wf.stderr b/src/test/ui/regions/regions-enum-not-wf.stderr index 36686eaf92f..553a3e71c16 100644 --- a/src/test/ui/regions/regions-enum-not-wf.stderr +++ b/src/test/ui/regions/regions-enum-not-wf.stderr @@ -1,5 +1,5 @@ error[E0309]: the parameter type `T` may not live long enough - --> $DIR/regions-enum-not-wf.rs:19:18 + --> $DIR/regions-enum-not-wf.rs:17:18 | LL | enum Ref1<'a, T> { | - help: consider adding an explicit lifetime bound...: `T: 'a` @@ -7,7 +7,7 @@ LL | Ref1Variant1(RequireOutlives<'a, T>), | ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds error[E0309]: the parameter type `T` may not live long enough - --> $DIR/regions-enum-not-wf.rs:24:25 + --> $DIR/regions-enum-not-wf.rs:22:25 | LL | enum Ref2<'a, T> { | - help: consider adding an explicit lifetime bound...: `T: 'a` @@ -16,7 +16,7 @@ LL | Ref2Variant2(isize, RequireOutlives<'a, T>), | ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds error[E0309]: the parameter type `T` may not live long enough - --> $DIR/regions-enum-not-wf.rs:37:23 + --> $DIR/regions-enum-not-wf.rs:35:23 | LL | enum RefDouble<'a, 'b, T> { | - help: consider adding an explicit lifetime bound...: `T: 'b` diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.rs b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.rs index 6de08f66d75..8b491ee4e30 100644 --- a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.rs +++ b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // Various examples of structs whose fields are not well-formed. #![allow(dead_code)] diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr index 36686eaf92f..553a3e71c16 100644 --- a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr @@ -1,5 +1,5 @@ error[E0309]: the parameter type `T` may not live long enough - --> $DIR/regions-enum-not-wf.rs:19:18 + --> $DIR/regions-enum-not-wf.rs:17:18 | LL | enum Ref1<'a, T> { | - help: consider adding an explicit lifetime bound...: `T: 'a` @@ -7,7 +7,7 @@ LL | Ref1Variant1(RequireOutlives<'a, T>), | ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds error[E0309]: the parameter type `T` may not live long enough - --> $DIR/regions-enum-not-wf.rs:24:25 + --> $DIR/regions-enum-not-wf.rs:22:25 | LL | enum Ref2<'a, T> { | - help: consider adding an explicit lifetime bound...: `T: 'a` @@ -16,7 +16,7 @@ LL | Ref2Variant2(isize, RequireOutlives<'a, T>), | ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds error[E0309]: the parameter type `T` may not live long enough - --> $DIR/regions-enum-not-wf.rs:37:23 + --> $DIR/regions-enum-not-wf.rs:35:23 | LL | enum RefDouble<'a, 'b, T> { | - help: consider adding an explicit lifetime bound...: `T: 'b` diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs index 4d23a1911a3..9736d1b964d 100644 --- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs @@ -1,6 +1,5 @@ // build-fail // ignore-emscripten -// ignore-tidy-linelength #![feature(repr_simd, platform_intrinsics)] #![allow(non_camel_case_types)] #[repr(simd)] diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.stderr index 1ed472a485d..0e88540bcc8 100644 --- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.stderr +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.stderr @@ -1,11 +1,11 @@ error[E0511]: invalid monomorphization of `simd_saturating_add` intrinsic: expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type - --> $DIR/simd-intrinsic-generic-arithmetic-saturating.rs:34:9 + --> $DIR/simd-intrinsic-generic-arithmetic-saturating.rs:33:9 | LL | simd_saturating_add(z, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_saturating_sub` intrinsic: expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type - --> $DIR/simd-intrinsic-generic-arithmetic-saturating.rs:36:9 + --> $DIR/simd-intrinsic-generic-arithmetic-saturating.rs:35:9 | LL | simd_saturating_sub(z, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation.rs b/src/test/ui/simd/simd-type-generic-monomorphisation.rs index 0275f0ce4c1..12f9d65d77a 100644 --- a/src/test/ui/simd/simd-type-generic-monomorphisation.rs +++ b/src/test/ui/simd/simd-type-generic-monomorphisation.rs @@ -2,7 +2,6 @@ #![feature(repr_simd, platform_intrinsics)] -// ignore-tidy-linelength // error-pattern:monomorphising SIMD type `Simd2` with a non-primitive-scalar (integer/float/pointer) element type `X` diff --git a/src/test/ui/simd/simd-type.rs b/src/test/ui/simd/simd-type.rs index 73d032a0c8e..d82c70b8d82 100644 --- a/src/test/ui/simd/simd-type.rs +++ b/src/test/ui/simd/simd-type.rs @@ -1,7 +1,6 @@ #![feature(repr_simd)] #![allow(non_camel_case_types)] -// ignore-tidy-linelength #[repr(simd)] struct empty; //~ ERROR SIMD vector cannot be empty diff --git a/src/test/ui/simd/simd-type.stderr b/src/test/ui/simd/simd-type.stderr index 823f10f5daf..4e4a19ea32a 100644 --- a/src/test/ui/simd/simd-type.stderr +++ b/src/test/ui/simd/simd-type.stderr @@ -1,35 +1,35 @@ error[E0075]: SIMD vector cannot be empty - --> $DIR/simd-type.rs:7:1 + --> $DIR/simd-type.rs:6:1 | LL | struct empty; | ^^^^^^^^^^^^^ error[E0075]: SIMD vector cannot be empty - --> $DIR/simd-type.rs:10:1 + --> $DIR/simd-type.rs:9:1 | LL | struct empty2([f32; 0]); | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0076]: SIMD vector should be homogeneous - --> $DIR/simd-type.rs:16:1 + --> $DIR/simd-type.rs:15:1 | LL | struct i64f64(i64, f64); | ^^^^^^^^^^^^^^^^^^^^^^^^ SIMD elements must have the same type error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type - --> $DIR/simd-type.rs:21:1 + --> $DIR/simd-type.rs:20:1 | LL | struct FooV(Foo, Foo); | ^^^^^^^^^^^^^^^^^^^^^^ error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type - --> $DIR/simd-type.rs:24:1 + --> $DIR/simd-type.rs:23:1 | LL | struct FooV2([Foo; 2]); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0075]: SIMD vector cannot have more than 32768 elements - --> $DIR/simd-type.rs:27:1 + --> $DIR/simd-type.rs:26:1 | LL | struct TooBig([f32; 65536]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/single-primitive-inherent-impl.rs b/src/test/ui/single-primitive-inherent-impl.rs index baa23396c16..75c62feec32 100644 --- a/src/test/ui/single-primitive-inherent-impl.rs +++ b/src/test/ui/single-primitive-inherent-impl.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![crate_type = "lib"] #![feature(lang_items)] #![no_std] diff --git a/src/test/ui/single-primitive-inherent-impl.stderr b/src/test/ui/single-primitive-inherent-impl.stderr index 50a0d5bef86..349a12eac05 100644 --- a/src/test/ui/single-primitive-inherent-impl.stderr +++ b/src/test/ui/single-primitive-inherent-impl.stderr @@ -1,5 +1,5 @@ error[E0390]: only a single inherent implementation marked with `#[lang = "str"]` is allowed for the `str` primitive - --> $DIR/single-primitive-inherent-impl.rs:11:1 + --> $DIR/single-primitive-inherent-impl.rs:9:1 | LL | / impl str { LL | | diff --git a/src/test/ui/stability-attribute/generics-default-stability-where.rs b/src/test/ui/stability-attribute/generics-default-stability-where.rs index 3fd14e25d0e..4afbca26264 100644 --- a/src/test/ui/stability-attribute/generics-default-stability-where.rs +++ b/src/test/ui/stability-attribute/generics-default-stability-where.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // aux-build:unstable_generic_param.rs extern crate unstable_generic_param; diff --git a/src/test/ui/stability-attribute/generics-default-stability-where.stderr b/src/test/ui/stability-attribute/generics-default-stability-where.stderr index 19fa09f311b..61253adc892 100644 --- a/src/test/ui/stability-attribute/generics-default-stability-where.stderr +++ b/src/test/ui/stability-attribute/generics-default-stability-where.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability-where.rs:8:45 + --> $DIR/generics-default-stability-where.rs:7:45 | LL | impl Trait3 for T where T: Trait2 { | ^^^^^ diff --git a/src/test/ui/stability-attribute/generics-default-stability.rs b/src/test/ui/stability-attribute/generics-default-stability.rs index d6f28e3e447..67f2334efc8 100644 --- a/src/test/ui/stability-attribute/generics-default-stability.rs +++ b/src/test/ui/stability-attribute/generics-default-stability.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // aux-build:unstable_generic_param.rs #![feature(unstable_default6)] diff --git a/src/test/ui/stability-attribute/generics-default-stability.stderr b/src/test/ui/stability-attribute/generics-default-stability.stderr index 45194413cce..99523f8eb64 100644 --- a/src/test/ui/stability-attribute/generics-default-stability.stderr +++ b/src/test/ui/stability-attribute/generics-default-stability.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:17:13 + --> $DIR/generics-default-stability.rs:16:13 | LL | impl Trait1 for S { | ^^^^^ @@ -7,7 +7,7 @@ LL | impl Trait1 for S { = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:21:13 + --> $DIR/generics-default-stability.rs:20:13 | LL | impl Trait1 for S { | ^^^^^ @@ -15,7 +15,7 @@ LL | impl Trait1 for S { = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:25:13 + --> $DIR/generics-default-stability.rs:24:13 | LL | impl Trait2 for S { | ^^^^^ @@ -23,7 +23,7 @@ LL | impl Trait2 for S { = help: add `#![feature(unstable_default)]` to the crate attributes to enable warning: use of deprecated struct `unstable_generic_param::Struct4`: test - --> $DIR/generics-default-stability.rs:84:29 + --> $DIR/generics-default-stability.rs:83:29 | LL | let _: Struct4 = Struct4 { field: 1 }; | ^^^^^^^ @@ -31,217 +31,217 @@ LL | let _: Struct4 = Struct4 { field: 1 }; = note: `#[warn(deprecated)]` on by default warning: use of deprecated struct `unstable_generic_param::Struct4`: test - --> $DIR/generics-default-stability.rs:84:12 + --> $DIR/generics-default-stability.rs:83:12 | LL | let _: Struct4 = Struct4 { field: 1 }; | ^^^^^^^^^^^^^^ warning: use of deprecated struct `unstable_generic_param::Struct4`: test - --> $DIR/generics-default-stability.rs:89:12 + --> $DIR/generics-default-stability.rs:88:12 | LL | let _: Struct4 = STRUCT4; | ^^^^^^^ warning: use of deprecated struct `unstable_generic_param::Struct4`: test - --> $DIR/generics-default-stability.rs:90:12 + --> $DIR/generics-default-stability.rs:89:12 | LL | let _: Struct4 = STRUCT4; | ^^^^^^^^^^^^^^ warning: use of deprecated struct `unstable_generic_param::Struct4`: test - --> $DIR/generics-default-stability.rs:91:29 + --> $DIR/generics-default-stability.rs:90:29 | LL | let _: Struct4 = Struct4 { field: 0 }; | ^^^^^^^ warning: use of deprecated struct `unstable_generic_param::Struct4`: test - --> $DIR/generics-default-stability.rs:91:12 + --> $DIR/generics-default-stability.rs:90:12 | LL | let _: Struct4 = Struct4 { field: 0 }; | ^^^^^^^^^^^^^^ warning: use of deprecated struct `unstable_generic_param::Struct5`: test - --> $DIR/generics-default-stability.rs:97:29 + --> $DIR/generics-default-stability.rs:96:29 | LL | let _: Struct5 = Struct5 { field: 1 }; | ^^^^^^^ warning: use of deprecated struct `unstable_generic_param::Struct5`: test - --> $DIR/generics-default-stability.rs:97:12 + --> $DIR/generics-default-stability.rs:96:12 | LL | let _: Struct5 = Struct5 { field: 1 }; | ^^^^^^^^^^^^^^ warning: use of deprecated struct `unstable_generic_param::Struct5`: test - --> $DIR/generics-default-stability.rs:102:12 + --> $DIR/generics-default-stability.rs:101:12 | LL | let _: Struct5 = STRUCT5; | ^^^^^^^ warning: use of deprecated struct `unstable_generic_param::Struct5`: test - --> $DIR/generics-default-stability.rs:103:12 + --> $DIR/generics-default-stability.rs:102:12 | LL | let _: Struct5 = STRUCT5; | ^^^^^^^^^^^^^^ warning: use of deprecated struct `unstable_generic_param::Struct5`: test - --> $DIR/generics-default-stability.rs:105:29 + --> $DIR/generics-default-stability.rs:104:29 | LL | let _: Struct5 = Struct5 { field: 0 }; | ^^^^^^^ warning: use of deprecated struct `unstable_generic_param::Struct5`: test - --> $DIR/generics-default-stability.rs:105:12 + --> $DIR/generics-default-stability.rs:104:12 | LL | let _: Struct5 = Struct5 { field: 0 }; | ^^^^^^^^^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test - --> $DIR/generics-default-stability.rs:160:28 + --> $DIR/generics-default-stability.rs:159:28 | LL | let _: Alias4 = Alias4::Some(1); | ^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test - --> $DIR/generics-default-stability.rs:160:12 + --> $DIR/generics-default-stability.rs:159:12 | LL | let _: Alias4 = Alias4::Some(1); | ^^^^^^^^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test - --> $DIR/generics-default-stability.rs:164:12 + --> $DIR/generics-default-stability.rs:163:12 | LL | let _: Alias4 = ALIAS4; | ^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test - --> $DIR/generics-default-stability.rs:165:12 + --> $DIR/generics-default-stability.rs:164:12 | LL | let _: Alias4 = ALIAS4; | ^^^^^^^^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test - --> $DIR/generics-default-stability.rs:166:28 + --> $DIR/generics-default-stability.rs:165:28 | LL | let _: Alias4 = Alias4::Some(0); | ^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test - --> $DIR/generics-default-stability.rs:166:12 + --> $DIR/generics-default-stability.rs:165:12 | LL | let _: Alias4 = Alias4::Some(0); | ^^^^^^^^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test - --> $DIR/generics-default-stability.rs:171:28 + --> $DIR/generics-default-stability.rs:170:28 | LL | let _: Alias5 = Alias5::Some(1); | ^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test - --> $DIR/generics-default-stability.rs:171:12 + --> $DIR/generics-default-stability.rs:170:12 | LL | let _: Alias5 = Alias5::Some(1); | ^^^^^^^^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test - --> $DIR/generics-default-stability.rs:175:12 + --> $DIR/generics-default-stability.rs:174:12 | LL | let _: Alias5 = ALIAS5; | ^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test - --> $DIR/generics-default-stability.rs:176:12 + --> $DIR/generics-default-stability.rs:175:12 | LL | let _: Alias5 = ALIAS5; | ^^^^^^^^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test - --> $DIR/generics-default-stability.rs:178:28 + --> $DIR/generics-default-stability.rs:177:28 | LL | let _: Alias5 = Alias5::Some(0); | ^^^^^^ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test - --> $DIR/generics-default-stability.rs:178:12 + --> $DIR/generics-default-stability.rs:177:12 | LL | let _: Alias5 = Alias5::Some(0); | ^^^^^^^^^^^^^ warning: use of deprecated variant `unstable_generic_param::Enum4::Some`: test - --> $DIR/generics-default-stability.rs:232:27 + --> $DIR/generics-default-stability.rs:231:27 | LL | let _: Enum4 = Enum4::Some(1); | ^^^^^^^^^^^ warning: use of deprecated enum `unstable_generic_param::Enum4`: test - --> $DIR/generics-default-stability.rs:232:12 + --> $DIR/generics-default-stability.rs:231:12 | LL | let _: Enum4 = Enum4::Some(1); | ^^^^^^^^^^^^ warning: use of deprecated enum `unstable_generic_param::Enum4`: test - --> $DIR/generics-default-stability.rs:236:12 + --> $DIR/generics-default-stability.rs:235:12 | LL | let _: Enum4 = ENUM4; | ^^^^^ warning: use of deprecated enum `unstable_generic_param::Enum4`: test - --> $DIR/generics-default-stability.rs:237:12 + --> $DIR/generics-default-stability.rs:236:12 | LL | let _: Enum4 = ENUM4; | ^^^^^^^^^^^^ warning: use of deprecated variant `unstable_generic_param::Enum4::Some`: test - --> $DIR/generics-default-stability.rs:238:27 + --> $DIR/generics-default-stability.rs:237:27 | LL | let _: Enum4 = Enum4::Some(0); | ^^^^^^^^^^^ warning: use of deprecated enum `unstable_generic_param::Enum4`: test - --> $DIR/generics-default-stability.rs:238:12 + --> $DIR/generics-default-stability.rs:237:12 | LL | let _: Enum4 = Enum4::Some(0); | ^^^^^^^^^^^^ warning: use of deprecated variant `unstable_generic_param::Enum5::Some`: test - --> $DIR/generics-default-stability.rs:243:27 + --> $DIR/generics-default-stability.rs:242:27 | LL | let _: Enum5 = Enum5::Some(1); | ^^^^^^^^^^^ warning: use of deprecated enum `unstable_generic_param::Enum5`: test - --> $DIR/generics-default-stability.rs:243:12 + --> $DIR/generics-default-stability.rs:242:12 | LL | let _: Enum5 = Enum5::Some(1); | ^^^^^^^^^^^^ warning: use of deprecated enum `unstable_generic_param::Enum5`: test - --> $DIR/generics-default-stability.rs:247:12 + --> $DIR/generics-default-stability.rs:246:12 | LL | let _: Enum5 = ENUM5; | ^^^^^ warning: use of deprecated enum `unstable_generic_param::Enum5`: test - --> $DIR/generics-default-stability.rs:248:12 + --> $DIR/generics-default-stability.rs:247:12 | LL | let _: Enum5 = ENUM5; | ^^^^^^^^^^^^ warning: use of deprecated variant `unstable_generic_param::Enum5::Some`: test - --> $DIR/generics-default-stability.rs:250:27 + --> $DIR/generics-default-stability.rs:249:27 | LL | let _: Enum5 = Enum5::Some(0); | ^^^^^^^^^^^ warning: use of deprecated enum `unstable_generic_param::Enum5`: test - --> $DIR/generics-default-stability.rs:250:12 + --> $DIR/generics-default-stability.rs:249:12 | LL | let _: Enum5 = Enum5::Some(0); | ^^^^^^^^^^^^ error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:36:20 + --> $DIR/generics-default-stability.rs:35:20 | LL | let _: Struct1 = Struct1 { field: 1 }; | ^^^^^ @@ -249,7 +249,7 @@ LL | let _: Struct1 = Struct1 { field: 1 }; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:40:20 + --> $DIR/generics-default-stability.rs:39:20 | LL | let _: Struct1 = STRUCT1; | ^^^^^ @@ -257,7 +257,7 @@ LL | let _: Struct1 = STRUCT1; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:41:20 + --> $DIR/generics-default-stability.rs:40:20 | LL | let _: Struct1 = Struct1 { field: 0 }; | ^^^^^ @@ -265,7 +265,7 @@ LL | let _: Struct1 = Struct1 { field: 0 }; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:70:27 + --> $DIR/generics-default-stability.rs:69:27 | LL | let _: Struct3 = STRUCT3; | ^^^^^ @@ -273,7 +273,7 @@ LL | let _: Struct3 = STRUCT3; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:72:27 + --> $DIR/generics-default-stability.rs:71:27 | LL | let _: Struct3 = Struct3 { field1: 0, field2: 0 }; | ^^^^^ @@ -281,7 +281,7 @@ LL | let _: Struct3 = Struct3 { field1: 0, field2: 0 }; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:73:27 + --> $DIR/generics-default-stability.rs:72:27 | LL | let _: Struct3 = Struct3 { field1: 0, field2: 0 }; | ^^^^^ @@ -289,7 +289,7 @@ LL | let _: Struct3 = Struct3 { field1: 0, field2: 0 }; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:97:20 + --> $DIR/generics-default-stability.rs:96:20 | LL | let _: Struct5 = Struct5 { field: 1 }; | ^^^^^ @@ -297,7 +297,7 @@ LL | let _: Struct5 = Struct5 { field: 1 }; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:103:20 + --> $DIR/generics-default-stability.rs:102:20 | LL | let _: Struct5 = STRUCT5; | ^^^^^ @@ -305,7 +305,7 @@ LL | let _: Struct5 = STRUCT5; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:105:20 + --> $DIR/generics-default-stability.rs:104:20 | LL | let _: Struct5 = Struct5 { field: 0 }; | ^^^^^ @@ -313,7 +313,7 @@ LL | let _: Struct5 = Struct5 { field: 0 }; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:113:19 + --> $DIR/generics-default-stability.rs:112:19 | LL | let _: Alias1 = Alias1::Some(1); | ^^^^^ @@ -321,7 +321,7 @@ LL | let _: Alias1 = Alias1::Some(1); = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:117:19 + --> $DIR/generics-default-stability.rs:116:19 | LL | let _: Alias1 = ALIAS1; | ^^^^^ @@ -329,7 +329,7 @@ LL | let _: Alias1 = ALIAS1; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:118:19 + --> $DIR/generics-default-stability.rs:117:19 | LL | let _: Alias1 = Alias1::Some(0); | ^^^^^ @@ -337,7 +337,7 @@ LL | let _: Alias1 = Alias1::Some(0); = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:146:26 + --> $DIR/generics-default-stability.rs:145:26 | LL | let _: Alias3 = ALIAS3; | ^^^^^ @@ -345,7 +345,7 @@ LL | let _: Alias3 = ALIAS3; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:148:26 + --> $DIR/generics-default-stability.rs:147:26 | LL | let _: Alias3 = Alias3::Ok(0); | ^^^^^ @@ -353,7 +353,7 @@ LL | let _: Alias3 = Alias3::Ok(0); = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:149:26 + --> $DIR/generics-default-stability.rs:148:26 | LL | let _: Alias3 = Alias3::Ok(0); | ^^^^^ @@ -361,7 +361,7 @@ LL | let _: Alias3 = Alias3::Ok(0); = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:171:19 + --> $DIR/generics-default-stability.rs:170:19 | LL | let _: Alias5 = Alias5::Some(1); | ^^^^^ @@ -369,7 +369,7 @@ LL | let _: Alias5 = Alias5::Some(1); = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:176:19 + --> $DIR/generics-default-stability.rs:175:19 | LL | let _: Alias5 = ALIAS5; | ^^^^^ @@ -377,7 +377,7 @@ LL | let _: Alias5 = ALIAS5; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:178:19 + --> $DIR/generics-default-stability.rs:177:19 | LL | let _: Alias5 = Alias5::Some(0); | ^^^^^ @@ -385,7 +385,7 @@ LL | let _: Alias5 = Alias5::Some(0); = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:185:18 + --> $DIR/generics-default-stability.rs:184:18 | LL | let _: Enum1 = Enum1::Some(1); | ^^^^^ @@ -393,7 +393,7 @@ LL | let _: Enum1 = Enum1::Some(1); = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:189:18 + --> $DIR/generics-default-stability.rs:188:18 | LL | let _: Enum1 = ENUM1; | ^^^^^ @@ -401,7 +401,7 @@ LL | let _: Enum1 = ENUM1; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:190:18 + --> $DIR/generics-default-stability.rs:189:18 | LL | let _: Enum1 = Enum1::Some(0); | ^^^^^ @@ -409,7 +409,7 @@ LL | let _: Enum1 = Enum1::Some(0); = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:218:25 + --> $DIR/generics-default-stability.rs:217:25 | LL | let _: Enum3 = ENUM3; | ^^^^^ @@ -417,7 +417,7 @@ LL | let _: Enum3 = ENUM3; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:220:25 + --> $DIR/generics-default-stability.rs:219:25 | LL | let _: Enum3 = Enum3::Ok(0); | ^^^^^ @@ -425,7 +425,7 @@ LL | let _: Enum3 = Enum3::Ok(0); = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:221:25 + --> $DIR/generics-default-stability.rs:220:25 | LL | let _: Enum3 = Enum3::Ok(0); | ^^^^^ @@ -433,7 +433,7 @@ LL | let _: Enum3 = Enum3::Ok(0); = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:243:18 + --> $DIR/generics-default-stability.rs:242:18 | LL | let _: Enum5 = Enum5::Some(1); | ^^^^^ @@ -441,7 +441,7 @@ LL | let _: Enum5 = Enum5::Some(1); = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:248:18 + --> $DIR/generics-default-stability.rs:247:18 | LL | let _: Enum5 = ENUM5; | ^^^^^ @@ -449,7 +449,7 @@ LL | let _: Enum5 = ENUM5; = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'unstable_default' - --> $DIR/generics-default-stability.rs:250:18 + --> $DIR/generics-default-stability.rs:249:18 | LL | let _: Enum5 = Enum5::Some(0); | ^^^^^ @@ -457,7 +457,7 @@ LL | let _: Enum5 = Enum5::Some(0); = help: add `#![feature(unstable_default)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'box_alloc_param' - --> $DIR/generics-default-stability.rs:257:24 + --> $DIR/generics-default-stability.rs:256:24 | LL | let _: Box1 = Box1::new(1); | ^^^^^^ @@ -465,25 +465,25 @@ LL | let _: Box1 = Box1::new(1); = help: add `#![feature(box_alloc_param)]` to the crate attributes to enable warning: use of deprecated field `unstable_generic_param::Struct4::field`: test - --> $DIR/generics-default-stability.rs:84:39 + --> $DIR/generics-default-stability.rs:83:39 | LL | let _: Struct4 = Struct4 { field: 1 }; | ^^^^^^^^ warning: use of deprecated field `unstable_generic_param::Struct4::field`: test - --> $DIR/generics-default-stability.rs:91:39 + --> $DIR/generics-default-stability.rs:90:39 | LL | let _: Struct4 = Struct4 { field: 0 }; | ^^^^^^^^ warning: use of deprecated field `unstable_generic_param::Struct5::field`: test - --> $DIR/generics-default-stability.rs:97:39 + --> $DIR/generics-default-stability.rs:96:39 | LL | let _: Struct5 = Struct5 { field: 1 }; | ^^^^^^^^ warning: use of deprecated field `unstable_generic_param::Struct5::field`: test - --> $DIR/generics-default-stability.rs:105:39 + --> $DIR/generics-default-stability.rs:104:39 | LL | let _: Struct5 = Struct5 { field: 0 }; | ^^^^^^^^ diff --git a/src/test/ui/structs/structure-constructor-type-mismatch.rs b/src/test/ui/structs/structure-constructor-type-mismatch.rs index 56c8ffb3e65..efc6304a6f7 100644 --- a/src/test/ui/structs/structure-constructor-type-mismatch.rs +++ b/src/test/ui/structs/structure-constructor-type-mismatch.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - struct Point { x: T, y: T, diff --git a/src/test/ui/structs/structure-constructor-type-mismatch.stderr b/src/test/ui/structs/structure-constructor-type-mismatch.stderr index 46114149672..64381278681 100644 --- a/src/test/ui/structs/structure-constructor-type-mismatch.stderr +++ b/src/test/ui/structs/structure-constructor-type-mismatch.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:19:12 + --> $DIR/structure-constructor-type-mismatch.rs:17:12 | LL | x: 1, | ^ @@ -8,7 +8,7 @@ LL | x: 1, | help: use a float literal: `1.0` error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:22:12 + --> $DIR/structure-constructor-type-mismatch.rs:20:12 | LL | y: 2, | ^ @@ -17,7 +17,7 @@ LL | y: 2, | help: use a float literal: `2.0` error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:28:12 + --> $DIR/structure-constructor-type-mismatch.rs:26:12 | LL | x: 3, | ^ @@ -26,7 +26,7 @@ LL | x: 3, | help: use a float literal: `3.0` error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:31:12 + --> $DIR/structure-constructor-type-mismatch.rs:29:12 | LL | y: 4, | ^ @@ -35,7 +35,7 @@ LL | y: 4, | help: use a float literal: `4.0` error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:37:12 + --> $DIR/structure-constructor-type-mismatch.rs:35:12 | LL | x: 5, | ^ @@ -44,7 +44,7 @@ LL | x: 5, | help: use a float literal: `5.0` error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:44:12 + --> $DIR/structure-constructor-type-mismatch.rs:42:12 | LL | x: 7, | ^ @@ -53,7 +53,7 @@ LL | x: 7, | help: use a float literal: `7.0` error[E0107]: this type alias takes 0 type arguments but 1 type argument was supplied - --> $DIR/structure-constructor-type-mismatch.rs:50:15 + --> $DIR/structure-constructor-type-mismatch.rs:48:15 | LL | let pt3 = PointF:: { | ^^^^^^------- help: remove these generics @@ -61,13 +61,13 @@ LL | let pt3 = PointF:: { | expected 0 type arguments | note: type alias defined here, with 0 type parameters - --> $DIR/structure-constructor-type-mismatch.rs:8:6 + --> $DIR/structure-constructor-type-mismatch.rs:6:6 | LL | type PointF = Point; | ^^^^^^ error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:51:12 + --> $DIR/structure-constructor-type-mismatch.rs:49:12 | LL | x: 9, | ^ @@ -76,7 +76,7 @@ LL | x: 9, | help: use a float literal: `9.0` error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:52:12 + --> $DIR/structure-constructor-type-mismatch.rs:50:12 | LL | y: 10, | ^^ @@ -85,7 +85,7 @@ LL | y: 10, | help: use a float literal: `10.0` error[E0107]: this type alias takes 0 type arguments but 1 type argument was supplied - --> $DIR/structure-constructor-type-mismatch.rs:56:9 + --> $DIR/structure-constructor-type-mismatch.rs:54:9 | LL | PointF:: { .. } => {} | ^^^^^^------- help: remove these generics @@ -93,13 +93,13 @@ LL | PointF:: { .. } => {} | expected 0 type arguments | note: type alias defined here, with 0 type parameters - --> $DIR/structure-constructor-type-mismatch.rs:8:6 + --> $DIR/structure-constructor-type-mismatch.rs:6:6 | LL | type PointF = Point; | ^^^^^^ error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:56:9 + --> $DIR/structure-constructor-type-mismatch.rs:54:9 | LL | match (Point { x: 1, y: 2 }) { | ---------------------- this expression has type `Point<{integer}>` @@ -110,7 +110,7 @@ LL | PointF:: { .. } => {} found struct `Point` error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:61:9 + --> $DIR/structure-constructor-type-mismatch.rs:59:9 | LL | match (Point { x: 1, y: 2 }) { | ---------------------- this expression has type `Point<{integer}>` @@ -121,7 +121,7 @@ LL | PointF { .. } => {} found struct `Point` error[E0308]: mismatched types - --> $DIR/structure-constructor-type-mismatch.rs:69:9 + --> $DIR/structure-constructor-type-mismatch.rs:67:9 | LL | match (Pair { x: 1, y: 2 }) { | --------------------- this expression has type `Pair<{integer}, {integer}>` diff --git a/src/test/ui/symbol-names/impl1.legacy.stderr b/src/test/ui/symbol-names/impl1.legacy.stderr index bd32a39a65c..b6012e41594 100644 --- a/src/test/ui/symbol-names/impl1.legacy.stderr +++ b/src/test/ui/symbol-names/impl1.legacy.stderr @@ -1,71 +1,71 @@ error: symbol-name(_ZN5impl13foo3Foo3bar17) - --> $DIR/impl1.rs:15:9 + --> $DIR/impl1.rs:14:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(impl1::foo::Foo::bar::) - --> $DIR/impl1.rs:15:9 + --> $DIR/impl1.rs:14:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(impl1::foo::Foo::bar) - --> $DIR/impl1.rs:15:9 + --> $DIR/impl1.rs:14:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(foo::Foo::bar) - --> $DIR/impl1.rs:22:9 + --> $DIR/impl1.rs:21:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17) - --> $DIR/impl1.rs:33:9 + --> $DIR/impl1.rs:32:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(impl1::bar::::baz::) - --> $DIR/impl1.rs:33:9 + --> $DIR/impl1.rs:32:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(impl1::bar::::baz) - --> $DIR/impl1.rs:33:9 + --> $DIR/impl1.rs:32:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(bar::::baz) - --> $DIR/impl1.rs:40:9 + --> $DIR/impl1.rs:39:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17) - --> $DIR/impl1.rs:63:13 + --> $DIR/impl1.rs:62:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method::) - --> $DIR/impl1.rs:63:13 + --> $DIR/impl1.rs:62:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method) - --> $DIR/impl1.rs:63:13 + --> $DIR/impl1.rs:62:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:70:13 + --> $DIR/impl1.rs:69:13 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index 771695330d8..b0b31a57d06 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -1,5 +1,4 @@ // build-fail -// ignore-tidy-linelength // revisions: legacy v0 //[legacy]compile-flags: -Z symbol-mangling-version=legacy //[v0]compile-flags: -Z symbol-mangling-version=v0 diff --git a/src/test/ui/symbol-names/impl1.stderr b/src/test/ui/symbol-names/impl1.stderr deleted file mode 100644 index 20e48782a3a..00000000000 --- a/src/test/ui/symbol-names/impl1.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: symbol-name(_ZN5impl13foo3Foo3bar17he53b9bee7600ed8dE) - --> $DIR/impl1.rs:8:9 - | -LL | #[rustc_symbol_name] - | ^^^^^^^^^^^^^^^^^^^^ - -error: def-path(foo::Foo::bar) - --> $DIR/impl1.rs:9:9 - | -LL | #[rustc_def_path] - | ^^^^^^^^^^^^^^^^^ - -error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h86c41f0462d901d4E) - --> $DIR/impl1.rs:18:9 - | -LL | #[rustc_symbol_name] - | ^^^^^^^^^^^^^^^^^^^^ - -error: def-path(bar::::baz) - --> $DIR/impl1.rs:19:9 - | -LL | #[rustc_def_path] - | ^^^^^^^^^^^^^^^^^ - -error: aborting due to 4 previous errors - diff --git a/src/test/ui/symbol-names/impl1.v0.stderr b/src/test/ui/symbol-names/impl1.v0.stderr index 3a6610935d6..e5b0deee36e 100644 --- a/src/test/ui/symbol-names/impl1.v0.stderr +++ b/src/test/ui/symbol-names/impl1.v0.stderr @@ -1,71 +1,71 @@ error: symbol-name(_RNvMNtCs21hi0yVfW1J_5impl13fooNtB2_3Foo3bar) - --> $DIR/impl1.rs:15:9 + --> $DIR/impl1.rs:14:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(::bar) - --> $DIR/impl1.rs:15:9 + --> $DIR/impl1.rs:14:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(::bar) - --> $DIR/impl1.rs:15:9 + --> $DIR/impl1.rs:14:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(foo::Foo::bar) - --> $DIR/impl1.rs:22:9 + --> $DIR/impl1.rs:21:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ error: symbol-name(_RNvMNtCs21hi0yVfW1J_5impl13barNtNtB4_3foo3Foo3baz) - --> $DIR/impl1.rs:33:9 + --> $DIR/impl1.rs:32:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(::baz) - --> $DIR/impl1.rs:33:9 + --> $DIR/impl1.rs:32:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(::baz) - --> $DIR/impl1.rs:33:9 + --> $DIR/impl1.rs:32:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(bar::::baz) - --> $DIR/impl1.rs:40:9 + --> $DIR/impl1.rs:39:9 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ error: symbol-name(_RNvXNCNvCs21hi0yVfW1J_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hvEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) - --> $DIR/impl1.rs:63:13 + --> $DIR/impl1.rs:62:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(<[&dyn impl1[17891616a171812d]::Foo extern "C" fn(&'a u8, ...)> + impl1[17891616a171812d]::AutoTrait; 3: usize] as impl1[17891616a171812d]::main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:63:13 + --> $DIR/impl1.rs:62:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8, ...)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:63:13 + --> $DIR/impl1.rs:62:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:70:13 + --> $DIR/impl1.rs:69:13 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/symbol-names/issue-60925.legacy.stderr b/src/test/ui/symbol-names/issue-60925.legacy.stderr index 65cc62b4d1d..83576783992 100644 --- a/src/test/ui/symbol-names/issue-60925.legacy.stderr +++ b/src/test/ui/symbol-names/issue-60925.legacy.stderr @@ -1,17 +1,17 @@ error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h6244e5288326926aE) - --> $DIR/issue-60925.rs:22:9 + --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(issue_60925::foo::Foo::foo::h6244e5288326926a) - --> $DIR/issue-60925.rs:22:9 + --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(issue_60925::foo::Foo::foo) - --> $DIR/issue-60925.rs:22:9 + --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/symbol-names/issue-60925.rs b/src/test/ui/symbol-names/issue-60925.rs index 47c9230c0ed..3238eb1e579 100644 --- a/src/test/ui/symbol-names/issue-60925.rs +++ b/src/test/ui/symbol-names/issue-60925.rs @@ -1,5 +1,4 @@ // build-fail -// ignore-tidy-linelength // revisions: legacy v0 //[legacy]compile-flags: -Z symbol-mangling-version=legacy //[v0]compile-flags: -Z symbol-mangling-version=v0 diff --git a/src/test/ui/symbol-names/issue-60925.stderr b/src/test/ui/symbol-names/issue-60925.stderr deleted file mode 100644 index ae753f0cebb..00000000000 --- a/src/test/ui/symbol-names/issue-60925.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: symbol-name(_ZN11issue_609253foo36Foo$LT$issue_60925..llv$6d$..Foo$GT$3foo17h059a991a004536adE) - --> $DIR/issue-60925.rs:16:9 - | -LL | #[rustc_symbol_name] - | ^^^^^^^^^^^^^^^^^^^^ - -error: demangling(issue_60925::foo::Foo $DIR/issue-60925.rs:16:9 - | -LL | #[rustc_symbol_name] - | ^^^^^^^^^^^^^^^^^^^^ - -error: demangling-alt(issue_60925::foo::Foo $DIR/issue-60925.rs:16:9 - | -LL | #[rustc_symbol_name] - | ^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors - diff --git a/src/test/ui/symbol-names/issue-60925.v0.stderr b/src/test/ui/symbol-names/issue-60925.v0.stderr index aed60a58af9..6a5885e1ea3 100644 --- a/src/test/ui/symbol-names/issue-60925.v0.stderr +++ b/src/test/ui/symbol-names/issue-60925.v0.stderr @@ -1,17 +1,17 @@ error: symbol-name(_RNvMNtCs21hi0yVfW1J_11issue_609253fooINtB2_3FooNtNtB4_4llvm3FooE3foo) - --> $DIR/issue-60925.rs:22:9 + --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(>::foo) - --> $DIR/issue-60925.rs:22:9 + --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(>::foo) - --> $DIR/issue-60925.rs:22:9 + --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/symbol-names/issue-75326.legacy.stderr b/src/test/ui/symbol-names/issue-75326.legacy.stderr index 2ad16bdb816..aadc0cf43a2 100644 --- a/src/test/ui/symbol-names/issue-75326.legacy.stderr +++ b/src/test/ui/symbol-names/issue-75326.legacy.stderr @@ -1,17 +1,17 @@ error: symbol-name(_ZN72_$LT$issue_75326..Foo$LT$I$C$E$GT$$u20$as$u20$issue_75326..Iterator2$GT$4next17SYMBOL_HASH) - --> $DIR/issue-75326.rs:42:5 + --> $DIR/issue-75326.rs:41:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling( as issue_75326::Iterator2>::next::SYMBOL_HASH) - --> $DIR/issue-75326.rs:42:5 + --> $DIR/issue-75326.rs:41:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt( as issue_75326::Iterator2>::next) - --> $DIR/issue-75326.rs:42:5 + --> $DIR/issue-75326.rs:41:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/symbol-names/issue-75326.rs b/src/test/ui/symbol-names/issue-75326.rs index faf36715b19..4d061cafef3 100644 --- a/src/test/ui/symbol-names/issue-75326.rs +++ b/src/test/ui/symbol-names/issue-75326.rs @@ -1,5 +1,4 @@ // build-fail -// ignore-tidy-linelength // revisions: legacy v0 //[legacy]compile-flags: -Z symbol-mangling-version=legacy //[v0]compile-flags: -Z symbol-mangling-version=v0 diff --git a/src/test/ui/symbol-names/issue-75326.v0.stderr b/src/test/ui/symbol-names/issue-75326.v0.stderr index 1f57952acd6..98844aafb65 100644 --- a/src/test/ui/symbol-names/issue-75326.v0.stderr +++ b/src/test/ui/symbol-names/issue-75326.v0.stderr @@ -1,17 +1,17 @@ error: symbol-name(_RNvXINICs21hi0yVfW1J_11issue_75326s_0pppEINtB5_3FooppENtB5_9Iterator24nextB5_) - --> $DIR/issue-75326.rs:42:5 + --> $DIR/issue-75326.rs:41:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling( as issue_75326[17891616a171812d]::Iterator2>::next) - --> $DIR/issue-75326.rs:42:5 + --> $DIR/issue-75326.rs:41:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt( as issue_75326::Iterator2>::next) - --> $DIR/issue-75326.rs:42:5 + --> $DIR/issue-75326.rs:41:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs index 5772450477c..e4abb96b4bf 100644 --- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // Check that creating/matching on an enum variant through an alias with // the wrong braced/unit form is caught as an error. diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr index b0de3ee42e3..f80abade0fd 100644 --- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr @@ -1,23 +1,23 @@ error[E0533]: expected unit struct, unit variant or constant, found struct variant `Alias::Braced` - --> $DIR/incorrect-variant-form-through-alias-caught.rs:10:5 + --> $DIR/incorrect-variant-form-through-alias-caught.rs:8:5 | LL | Alias::Braced; | ^^^^^^^^^^^^^ error[E0533]: expected unit struct, unit variant or constant, found struct variant `Alias::Braced` - --> $DIR/incorrect-variant-form-through-alias-caught.rs:12:9 + --> $DIR/incorrect-variant-form-through-alias-caught.rs:10:9 | LL | let Alias::Braced = panic!(); | ^^^^^^^^^^^^^ error[E0164]: expected tuple struct or tuple variant, found struct variant `Alias::Braced` - --> $DIR/incorrect-variant-form-through-alias-caught.rs:14:9 + --> $DIR/incorrect-variant-form-through-alias-caught.rs:12:9 | LL | let Alias::Braced(..) = panic!(); | ^^^^^^^^^^^^^^^^^ not a tuple variant or struct error[E0618]: expected function, found enum variant `Alias::Unit` - --> $DIR/incorrect-variant-form-through-alias-caught.rs:17:5 + --> $DIR/incorrect-variant-form-through-alias-caught.rs:15:5 | LL | enum Enum { Braced {}, Unit, Tuple() } | ---- `Alias::Unit` defined here @@ -33,7 +33,7 @@ LL | Alias::Unit; | ^^^^^^^^^^^ error[E0164]: expected tuple struct or tuple variant, found unit variant `Alias::Unit` - --> $DIR/incorrect-variant-form-through-alias-caught.rs:19:9 + --> $DIR/incorrect-variant-form-through-alias-caught.rs:17:9 | LL | let Alias::Unit() = panic!(); | ^^^^^^^^^^^^^ not a tuple variant or struct diff --git a/src/test/ui/type-alias-impl-trait/issue-53598.full_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-53598.full_tait.stderr index 8c2d713c160..ee4b7eef0bd 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53598.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-53598.full_tait.stderr @@ -1,5 +1,5 @@ warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-53598.rs:5:32 + --> $DIR/issue-53598.rs:4:32 | LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] | ^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: see issue #63063 for more information error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-53598.rs:24:42 + --> $DIR/issue-53598.rs:23:42 | LL | fn foo(_: T) -> Self::Item { | __________________________________________^ diff --git a/src/test/ui/type-alias-impl-trait/issue-53598.min_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-53598.min_tait.stderr index cb5d6ec8040..728721b6dbd 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53598.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-53598.min_tait.stderr @@ -1,5 +1,5 @@ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-53598.rs:24:42 + --> $DIR/issue-53598.rs:23:42 | LL | fn foo(_: T) -> Self::Item { | __________________________________________^ diff --git a/src/test/ui/type-alias-impl-trait/issue-53598.rs b/src/test/ui/type-alias-impl-trait/issue-53598.rs index 1388c587db9..38067a72223 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53598.rs +++ b/src/test/ui/type-alias-impl-trait/issue-53598.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // ignore-compare-mode-chalk // revisions: min_tait full_tait #![feature(min_type_alias_impl_trait)] diff --git a/src/test/ui/type-alias-impl-trait/issue-57700.full_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-57700.full_tait.stderr index f92a5997a9b..4336532cdbb 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57700.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57700.full_tait.stderr @@ -1,5 +1,5 @@ warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-57700.rs:6:32 + --> $DIR/issue-57700.rs:5:32 | LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] | ^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: see issue #63063 for more information error: type parameter `impl Deref` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-57700.rs:20:58 + --> $DIR/issue-57700.rs:19:58 | LL | fn foo(self: impl Deref) -> Self::Bar { | __________________________________________________________^ diff --git a/src/test/ui/type-alias-impl-trait/issue-57700.min_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-57700.min_tait.stderr index 1aaa42b99ac..47ab31cd797 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57700.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57700.min_tait.stderr @@ -1,5 +1,5 @@ error: type parameter `impl Deref` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-57700.rs:20:58 + --> $DIR/issue-57700.rs:19:58 | LL | fn foo(self: impl Deref) -> Self::Bar { | __________________________________________________________^ diff --git a/src/test/ui/type-alias-impl-trait/issue-57700.rs b/src/test/ui/type-alias-impl-trait/issue-57700.rs index c7a123ad240..476a188cde6 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57700.rs +++ b/src/test/ui/type-alias-impl-trait/issue-57700.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // ignore-compare-mode-chalk #![feature(arbitrary_self_types)] // revisions: min_tait full_tait diff --git a/src/test/ui/union/union-deref.rs b/src/test/ui/union/union-deref.rs index df598eea9ef..48f5b36bd17 100644 --- a/src/test/ui/union/union-deref.rs +++ b/src/test/ui/union/union-deref.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength //! Test the part of RFC 2514 that is about not applying `DerefMut` coercions //! of union fields. #![feature(untagged_unions)] diff --git a/src/test/ui/union/union-deref.stderr b/src/test/ui/union/union-deref.stderr index f7722764cd3..6af050bc4b7 100644 --- a/src/test/ui/union/union-deref.stderr +++ b/src/test/ui/union/union-deref.stderr @@ -1,5 +1,5 @@ error: not automatically applying `DerefMut` on `ManuallyDrop` union field - --> $DIR/union-deref.rs:15:14 + --> $DIR/union-deref.rs:14:14 | LL | unsafe { u.f.0 = Vec::new() }; | ^^^ @@ -8,7 +8,7 @@ LL | unsafe { u.f.0 = Vec::new() }; = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor error: not automatically applying `DerefMut` on `ManuallyDrop` union field - --> $DIR/union-deref.rs:17:19 + --> $DIR/union-deref.rs:16:19 | LL | unsafe { &mut u.f.0 }; | ^^^ @@ -17,7 +17,7 @@ LL | unsafe { &mut u.f.0 }; = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor error: not automatically applying `DerefMut` on `ManuallyDrop` union field - --> $DIR/union-deref.rs:19:14 + --> $DIR/union-deref.rs:18:14 | LL | unsafe { u.f.0.push(0) }; | ^^^ @@ -26,7 +26,7 @@ LL | unsafe { u.f.0.push(0) }; = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor error: not automatically applying `DerefMut` on `ManuallyDrop` union field - --> $DIR/union-deref.rs:23:14 + --> $DIR/union-deref.rs:22:14 | LL | unsafe { u.f.0.0 = Vec::new() }; | ^^^^^ @@ -35,7 +35,7 @@ LL | unsafe { u.f.0.0 = Vec::new() }; = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor error: not automatically applying `DerefMut` on `ManuallyDrop` union field - --> $DIR/union-deref.rs:25:19 + --> $DIR/union-deref.rs:24:19 | LL | unsafe { &mut u.f.0.0 }; | ^^^^^ @@ -44,7 +44,7 @@ LL | unsafe { &mut u.f.0.0 }; = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor error: not automatically applying `DerefMut` on `ManuallyDrop` union field - --> $DIR/union-deref.rs:27:14 + --> $DIR/union-deref.rs:26:14 | LL | unsafe { u.f.0.0.push(0) }; | ^^^^^ diff --git a/src/test/ui/unsized/return-unsized-from-trait-method.rs b/src/test/ui/unsized/return-unsized-from-trait-method.rs index 2d265d5db5c..ebe6edd1010 100644 --- a/src/test/ui/unsized/return-unsized-from-trait-method.rs +++ b/src/test/ui/unsized/return-unsized-from-trait-method.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - // regression test for #26376 trait Foo { diff --git a/src/test/ui/unsized/return-unsized-from-trait-method.stderr b/src/test/ui/unsized/return-unsized-from-trait-method.stderr index 7ecdd286166..4dd7cf5e02f 100644 --- a/src/test/ui/unsized/return-unsized-from-trait-method.stderr +++ b/src/test/ui/unsized/return-unsized-from-trait-method.stderr @@ -1,5 +1,5 @@ error[E0161]: cannot move a value of type [u8]: the size of [u8] cannot be statically determined - --> $DIR/return-unsized-from-trait-method.rs:11:17 + --> $DIR/return-unsized-from-trait-method.rs:9:17 | LL | let _ = f.foo(); | ^^^^^^^ From 8a058926ecd6d0988714f8f7a5a31293c533f8c6 Mon Sep 17 00:00:00 2001 From: SlightlyOutOfPhase Date: Sat, 3 Apr 2021 16:32:59 -0400 Subject: [PATCH 326/370] List trait impls before methods from deref in the sidebar of Rustdoc's output --- src/librustdoc/html/render/mod.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 07bd26a4c5e..2bc90e0a3c9 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1931,13 +1931,6 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) { } if v.iter().any(|i| i.inner_impl().trait_.is_some()) { - if let Some(impl_) = v - .iter() - .filter(|i| i.inner_impl().trait_.is_some()) - .find(|i| i.inner_impl().trait_.def_id_full(cache) == cx.cache.deref_trait_did) - { - sidebar_deref_methods(cx, out, impl_, v); - } let format_impls = |impls: Vec<&Impl>| { let mut links = FxHashSet::default(); @@ -2005,6 +1998,14 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) { ); write_sidebar_links(out, blanket_format); } + + if let Some(impl_) = v + .iter() + .filter(|i| i.inner_impl().trait_.is_some()) + .find(|i| i.inner_impl().trait_.def_id_full(cache) == cx.cache.deref_trait_did) + { + sidebar_deref_methods(cx, out, impl_, v); + } } } } From 72502e889c1b30aa95d76be22bfdb359efd9ba74 Mon Sep 17 00:00:00 2001 From: SlightlyOutOfPhase Date: Sat, 3 Apr 2021 17:00:07 -0400 Subject: [PATCH 327/370] Remove trailing whitespace --- src/librustdoc/html/render/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 2bc90e0a3c9..f6b676228f9 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1998,7 +1998,7 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) { ); write_sidebar_links(out, blanket_format); } - + if let Some(impl_) = v .iter() .filter(|i| i.inner_impl().trait_.is_some()) From 13e482bf8384062eb0360603a895ffdbfe2cc95a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 3 Apr 2021 15:14:23 +0200 Subject: [PATCH 328/370] Remove unneeded INITIAL_IDS const --- src/librustdoc/config.rs | 1 - src/librustdoc/html/markdown.rs | 15 +++++++++------ src/librustdoc/html/render/context.rs | 7 ++----- src/librustdoc/html/render/mod.rs | 18 ------------------ 4 files changed, 11 insertions(+), 30 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 246e0ebbb2b..5df52e498b5 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -507,7 +507,6 @@ impl Options { let edition = config::parse_crate_edition(&matches); let mut id_map = html::markdown::IdMap::new(); - id_map.populate(&html::render::INITIAL_IDS); let external_html = match ExternalHtml::load( &matches.opt_strs("html-in-header"), &matches.opt_strs("html-before-content"), diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index cdccb1c8581..509f1730557 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1356,6 +1356,9 @@ fn init_id_map() -> FxHashMap { map.insert("rustdoc-vars".to_owned(), 1); map.insert("sidebar-vars".to_owned(), 1); map.insert("copy-path".to_owned(), 1); + map.insert("help".to_owned(), 1); + map.insert("TOC".to_owned(), 1); + map.insert("render-detail".to_owned(), 1); // This is the list of IDs used by rustdoc sections. map.insert("fields".to_owned(), 1); map.insert("variants".to_owned(), 1); @@ -1365,6 +1368,12 @@ fn init_id_map() -> FxHashMap { map.insert("trait-implementations".to_owned(), 1); map.insert("synthetic-implementations".to_owned(), 1); map.insert("blanket-implementations".to_owned(), 1); + map.insert("associated-types".to_owned(), 1); + map.insert("associated-const".to_owned(), 1); + map.insert("required-methods".to_owned(), 1); + map.insert("provided-methods".to_owned(), 1); + map.insert("implementors".to_owned(), 1); + map.insert("synthetic-implementors".to_owned(), 1); map } @@ -1373,12 +1382,6 @@ impl IdMap { IdMap { map: init_id_map() } } - crate fn populate, S: AsRef + ToString>(&mut self, ids: I) { - for id in ids { - let _ = self.derive(id); - } - } - crate fn derive + ToString>(&mut self, candidate: S) -> String { let id = match self.map.get_mut(candidate.as_ref()) { None => candidate.to_string(), diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 07c850a20a9..1a993f360a1 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -18,7 +18,7 @@ use super::print_item::{full_path, item_path, print_item}; use super::write_shared::write_shared; use super::{ print_sidebar, settings, AllTypes, NameDoc, SharedContext, StylePath, BASIC_KEYWORDS, - CURRENT_DEPTH, INITIAL_IDS, + CURRENT_DEPTH, }; use crate::clean::{self, AttributesExt}; @@ -423,14 +423,11 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { } fn make_child_renderer(&self) -> Self { - let mut id_map = IdMap::new(); - id_map.populate(&INITIAL_IDS); - Self { current: self.current.clone(), dst: self.dst.clone(), render_redirect_pages: self.render_redirect_pages, - id_map: RefCell::new(id_map), + id_map: RefCell::new(IdMap::new()), deref_id_map: RefCell::new(FxHashMap::default()), shared: Rc::clone(&self.shared), cache: Rc::clone(&self.cache), diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 07bd26a4c5e..3a557a3f719 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -283,24 +283,6 @@ crate struct StylePath { thread_local!(crate static CURRENT_DEPTH: Cell = Cell::new(0)); -crate const INITIAL_IDS: [&'static str; 15] = [ - "main", - "search", - "help", - "TOC", - "render-detail", - "associated-types", - "associated-const", - "required-methods", - "provided-methods", - "implementors", - "synthetic-implementors", - "implementors-list", - "synthetic-implementors-list", - "methods", - "implementations", -]; - fn write_srclink(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) { if let Some(l) = cx.src_href(item) { write!(buf, "[src]", l) From 3bd241f95b6992d73f159c00551069e2c3424747 Mon Sep 17 00:00:00 2001 From: The8472 Date: Fri, 2 Apr 2021 23:06:05 +0200 Subject: [PATCH 329/370] cleanup leak after test to make miri happy --- library/alloc/tests/vec.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index b926c697d58..026d3f63bb7 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1078,12 +1078,21 @@ fn test_from_iter_specialization_panic_during_drop_leaks() { } } + let mut to_free: *mut Droppable = core::ptr::null_mut(); + let mut cap = 0; + let _ = std::panic::catch_unwind(AssertUnwindSafe(|| { - let v = vec![Droppable::DroppedTwice(Box::new(123)), Droppable::PanicOnDrop]; + let mut v = vec![Droppable::DroppedTwice(Box::new(123)), Droppable::PanicOnDrop]; + to_free = v.as_mut_ptr(); + cap = v.capacity(); let _ = v.into_iter().take(0).collect::>(); })); assert_eq!(unsafe { DROP_COUNTER }, 1); + // clean up the leak to keep miri happy + unsafe { + Vec::from_raw_parts(to_free, 0, cap); + } } #[test] From 572873fce0365cbba75557458ee5d7cb744bac12 Mon Sep 17 00:00:00 2001 From: the8472 Date: Sun, 4 Apr 2021 01:38:58 +0200 Subject: [PATCH 330/370] suggestion from review Co-authored-by: Ralf Jung --- library/alloc/tests/vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 026d3f63bb7..cdd18520c59 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1091,7 +1091,7 @@ fn test_from_iter_specialization_panic_during_drop_leaks() { assert_eq!(unsafe { DROP_COUNTER }, 1); // clean up the leak to keep miri happy unsafe { - Vec::from_raw_parts(to_free, 0, cap); + drop(Vec::from_raw_parts(to_free, 0, cap)); } } From a3d0fa8008c75c543c37d6f5af6414ae83874974 Mon Sep 17 00:00:00 2001 From: AngelicosPhosphoros Date: Sun, 4 Apr 2021 02:42:56 +0300 Subject: [PATCH 331/370] Add `#[inline]` to IpAddr methods Add some inlines to trivial methods of IpAddr Closes https://github.com/rust-lang/rust/issues/77583 --- library/std/src/net/ip.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index 7f8c33dac56..da2415e3610 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -993,6 +993,7 @@ impl Ord for Ipv4Addr { } impl IntoInner for Ipv4Addr { + #[inline] fn into_inner(self) -> c::in_addr { self.inner } @@ -1800,11 +1801,13 @@ impl Ord for Ipv6Addr { } impl AsInner for Ipv6Addr { + #[inline] fn as_inner(&self) -> &c::in6_addr { &self.inner } } impl FromInner for Ipv6Addr { + #[inline] fn from_inner(addr: c::in6_addr) -> Ipv6Addr { Ipv6Addr { inner: addr } } From ed89e6b831424ea68060c4f8b1145637d6ee15a5 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Sat, 3 Apr 2021 17:47:32 -0700 Subject: [PATCH 332/370] Address review comments and Windows failure, and make cleaner --- src/bootstrap/dist.rs | 52 ++++++------ src/bootstrap/install.rs | 20 ++--- src/bootstrap/tarball.rs | 2 +- src/bootstrap/test.rs | 3 + src/tools/rust-demangler/README.md | 27 +++--- src/tools/rust-demangler/tests/lib.rs | 113 ++++++++++++-------------- 6 files changed, 108 insertions(+), 109 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 34243b79717..38ebe0e5208 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1253,7 +1253,7 @@ pub struct RustDemangler { } impl Step for RustDemangler { - type Output = GeneratedTarball; + type Output = Option; const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -1271,11 +1271,17 @@ impl Step for RustDemangler { }); } - fn run(self, builder: &Builder<'_>) -> GeneratedTarball { + fn run(self, builder: &Builder<'_>) -> Option { let compiler = self.compiler; let target = self.target; assert!(builder.config.extended); + // Only build this extended tool if explicitly included in `tools`, or if `profiler = true` + let profiler = builder.config.profiler_enabled(target); + if !builder.config.tools.as_ref().map_or(profiler, |t| t.contains("rust-demangler")) { + return None; + } + let rust_demangler = builder .ensure(tool::RustDemangler { compiler, target, extra_features: Vec::new() }) .expect("rust-demangler expected to build - in-tree tool"); @@ -1286,7 +1292,7 @@ impl Step for RustDemangler { tarball.is_preview(true); tarball.add_file(&rust_demangler, "bin", 0o755); tarball.add_legal_and_readme_to("share/doc/rust-demangler"); - tarball.generate() + Some(tarball.generate()) } } @@ -1326,14 +1332,7 @@ impl Step for Extended { let rustc_installer = builder.ensure(Rustc { compiler: builder.compiler(stage, target) }); let cargo_installer = builder.ensure(Cargo { compiler, target }); let rustfmt_installer = builder.ensure(Rustfmt { compiler, target }); - let profiler = builder.config.profiler_enabled(target); - let install_rust_demangler = - builder.config.tools.as_ref().map_or(profiler, |t| t.contains("rust-demangler")); - let rust_demangler_installer = if install_rust_demangler { - Some(builder.ensure(RustDemangler { compiler, target })) - } else { - None - }; + let rust_demangler_installer = builder.ensure(RustDemangler { compiler, target }); let rls_installer = builder.ensure(Rls { compiler, target }); let rust_analyzer_installer = builder.ensure(RustAnalyzer { compiler, target }); let llvm_tools_installer = builder.ensure(LlvmTools { target }); @@ -1359,14 +1358,12 @@ impl Step for Extended { let mut tarballs = Vec::new(); tarballs.push(rustc_installer); tarballs.push(cargo_installer); + tarballs.push(clippy_installer); + tarballs.extend(rust_demangler_installer.clone()); tarballs.extend(rls_installer.clone()); tarballs.extend(rust_analyzer_installer.clone()); - tarballs.push(clippy_installer); tarballs.extend(miri_installer.clone()); tarballs.extend(rustfmt_installer.clone()); - if let Some(rust_demangler_installer) = rust_demangler_installer { - tarballs.push(rust_demangler_installer); - } tarballs.extend(llvm_tools_installer); if let Some(analysis_installer) = analysis_installer { tarballs.push(analysis_installer); @@ -1421,6 +1418,9 @@ impl Step for Extended { let xform = |p: &Path| { let mut contents = t!(fs::read_to_string(p)); + if rust_demangler_installer.is_none() { + contents = filter(&contents, "rust-demangler"); + } if rls_installer.is_none() { contents = filter(&contents, "rls"); } @@ -1468,11 +1468,10 @@ impl Step for Extended { prepare("rust-docs"); prepare("rust-std"); prepare("rust-analysis"); - if install_rust_demangler { + prepare("clippy"); + if rust_demangler_installer.is_some() { prepare("rust-demangler"); } - prepare("clippy"); - if rls_installer.is_some() { prepare("rls"); } @@ -1520,6 +1519,8 @@ impl Step for Extended { "rust-analyzer-preview".to_string() } else if name == "clippy" { "clippy-preview".to_string() + } else if name == "rust-demangler" { + "rust-demangler-preview".to_string() } else if name == "miri" { "miri-preview".to_string() } else { @@ -1534,12 +1535,12 @@ impl Step for Extended { prepare("rustc"); prepare("cargo"); prepare("rust-analysis"); - if install_rust_demangler { - prepare("rust-demangler"); - } prepare("rust-docs"); prepare("rust-std"); prepare("clippy"); + if rust_demangler_installer.is_some() { + prepare("rust-demangler"); + } if rls_installer.is_some() { prepare("rls"); } @@ -1681,7 +1682,7 @@ impl Step for Extended { .arg("-t") .arg(etc.join("msi/remove-duplicates.xsl")), ); - if install_rust_demangler { + if rust_demangler_installer.is_some() { builder.run( Command::new(&heat) .current_dir(&exe) @@ -1773,6 +1774,9 @@ impl Step for Extended { .arg(&input); add_env(builder, &mut cmd, target); + if rust_demangler_installer.is_some() { + cmd.arg("-dRustDemanglerDir=rust-demangler"); + } if rls_installer.is_some() { cmd.arg("-dRlsDir=rls"); } @@ -1795,7 +1799,7 @@ impl Step for Extended { candle("CargoGroup.wxs".as_ref()); candle("StdGroup.wxs".as_ref()); candle("ClippyGroup.wxs".as_ref()); - if install_rust_demangler { + if rust_demangler_installer.is_some() { candle("RustDemanglerGroup.wxs".as_ref()); } if rls_installer.is_some() { @@ -1844,7 +1848,7 @@ impl Step for Extended { if rust_analyzer_installer.is_some() { cmd.arg("RustAnalyzerGroup.wixobj"); } - if install_rust_demangler { + if rust_demangler_installer.is_some() { cmd.arg("RustDemanglerGroup.wixobj"); } if miri_installer.is_some() { diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index e034e2a2f90..68e7dc80067 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -190,18 +190,14 @@ install!((self, builder, _config), ); } }; - RustDemangler, - "rust-demangler", - Self::should_build(_config), - only_hosts: true, - { - let profiler = builder.config.profiler_enabled(self.target); - let install_rust_demangler = - builder.config.tools.as_ref().map_or(profiler, |t| t.contains("rust-demangler")); - if install_rust_demangler { - let tarball = builder.ensure( - dist::RustDemangler { compiler: self.compiler, target: self.target } - ); + RustDemangler, "rust-demangler", Self::should_build(_config), only_hosts: true, { + // Note: Even though `should_build` may return true for `extended` default tools, + // dist::RustDemangler may still return None, unless the target-dependent `profiler` config + // is also true, or the `tools` array explicitly includes "rust-demangler". + if let Some(tarball) = builder.ensure(dist::RustDemangler { + compiler: self.compiler, + target: self.target + }) { install_sh(builder, "rust-demangler", self.compiler.stage, Some(self.target), &tarball); } else { builder.info( diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 4a5d5fbf04f..b02d7e062a5 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -68,7 +68,7 @@ impl OverlayKind { match self { OverlayKind::Rust => builder.rust_version(), OverlayKind::LLVM => builder.rust_version(), - OverlayKind::RustDemangler => builder.rust_version(), + OverlayKind::RustDemangler => builder.release_num("rust-demangler"), OverlayKind::Cargo => { builder.cargo_info.version(builder, &builder.release_num("cargo")) } diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 7425dcb52c0..69d39f5e544 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -393,6 +393,9 @@ impl Step for RustDemangler { t!(fs::create_dir_all(&dir)); cargo.env("RUST_DEMANGLER_DRIVER_PATH", rust_demangler); + + cargo.arg("--").args(builder.config.cmd.test_args()); + cargo.add_rustc_lib_path(builder, compiler); builder.run(&mut cargo.into()); diff --git a/src/tools/rust-demangler/README.md b/src/tools/rust-demangler/README.md index a45f5c45732..4e8a689a13a 100644 --- a/src/tools/rust-demangler/README.md +++ b/src/tools/rust-demangler/README.md @@ -1,18 +1,15 @@ # rust-demangler -Demangles rustc mangled names. +_Demangles rustc mangled names._ -This tool uses the [rustc-demangle](https://crates.io/crates/rustc-demangle) -crate to convert an input buffer of newline-separated mangled names into their -demangled translations. +`rust-demangler` supports the requirements of the [`llvm-cov show -Xdemangler` +option](https://llvm.org/docs/CommandGuide/llvm-cov.html#cmdoption-llvm-cov-show-xdemangler), +to perform Rust-specific symbol demangling: -This tool takes a list of mangled names (one per line) on standard input, and -prints a corresponding list of demangled names. The tool is designed to support -programs that can leverage a third-party demangler, such as `llvm-cov`, via the -`-Xdemangler=` option. +> _The demangler is expected to read a newline-separated list of symbols from +> stdin and write a newline-separated list of the same length to stdout._ -To use `rust-demangler` with `llvm-cov` for example, add the `-Xdemangler=...` -option: +To use `rust-demangler` with `llvm-cov` for example: ```shell $ TARGET="${PWD}/build/x86_64-unknown-linux-gnu" @@ -21,6 +18,16 @@ $ "${TARGET}"/llvm/bin/llvm-cov show \ --instr-profile=main.profdata ./main --show-line-counts-or-regions ``` +`rust-demangler` is a Rust "extended tool", used in Rust compiler tests, and +optionally included in Rust distributions that enable coverage profiling. Symbol +demangling is implemented using the +[rustc-demangle](https://crates.io/crates/rustc-demangle) crate. + +_(Note, for Rust developers, the third-party tool +[`rustfilt`](https://crates.io/crates/rustfilt) also supports `llvm-cov` symbol +demangling. `rustfilt` is a more generalized tool that searches any body of +text, using pattern matching, to find and demangle Rust symbols.)_ + ## License Rust-demangler is distributed under the terms of both the MIT license and the diff --git a/src/tools/rust-demangler/tests/lib.rs b/src/tools/rust-demangler/tests/lib.rs index 09752fd7212..5a67b423225 100644 --- a/src/tools/rust-demangler/tests/lib.rs +++ b/src/tools/rust-demangler/tests/lib.rs @@ -22,74 +22,63 @@ _RNvC9backtrace3foo.llvm.A5310EB9 _RNvNtNtNtNtCs92dm3009vxr_4rand4rngs7adapter9reseeding4fork23FORK_HANDLER_REGISTERED.0.0 "; +const DEMANGLED_OUTPUT: &str = r" +123foo[0]::bar +utf8_idents[317d481089b8c8fe]::საჭმელად_გემრიელი_სადილი +cc[4d6468d6c9fd4bb3]::spawn::{closure#0}::{closure#0} + as core[846817f741e54dfd]::iter::iterator::Iterator>::rposition::::{closure#0} +alloc[f15a878b47eb696b]::alloc::box_free::> +INtC8arrayvec8ArrayVechKj7b_E +> +> +> +> +> +> +> +> +>::foo::FOO +foo[0] +foo[0] +backtrace[0]::foo +rand[693ea8e72247470f]::rngs::adapter::reseeding::fork::FORK_HANDLER_REGISTERED.0.0 +"; + +const DEMANGLED_OUTPUT_NO_CRATE_DISAMBIGUATORS: &str = r" +123foo[0]::bar +utf8_idents::საჭმელად_გემრიელი_სადილი +cc::spawn::{closure#0}::{closure#0} + as core::iter::iterator::Iterator>::rposition::::{closure#0} +alloc::alloc::box_free::> +INtC8arrayvec8ArrayVechKj7b_E +> +> +> +> +> +> +> +> +>::foo::FOO +foo[0] +foo[0] +backtrace[0]::foo +rand::rngs::adapter::reseeding::fork::FORK_HANDLER_REGISTERED.0.0 +"; + #[test] fn test_demangle_lines() { let demangled_lines = demangle_lines(MANGLED_INPUT.lines(), None); - let mut iter = demangled_lines.iter(); - assert_eq!("", iter.next().unwrap()); - assert_eq!("123foo[0]::bar", iter.next().unwrap()); - assert_eq!("utf8_idents[317d481089b8c8fe]::საჭმელად_გემრიელი_სადილი", iter.next().unwrap()); - assert_eq!("cc[4d6468d6c9fd4bb3]::spawn::{closure#0}::{closure#0}", iter.next().unwrap()); - assert_eq!( - " as core[846817f741e54dfd]::iter::iterator::Iterator>::rposition::::{closure#0}", - iter.next().unwrap() - ); - assert_eq!( - "alloc[f15a878b47eb696b]::alloc::box_free::>", - iter.next().unwrap() - ); - assert_eq!("INtC8arrayvec8ArrayVechKj7b_E", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">::foo::FOO", iter.next().unwrap()); - assert_eq!("foo[0]", iter.next().unwrap()); - assert_eq!("foo[0]", iter.next().unwrap()); - assert_eq!("backtrace[0]::foo", iter.next().unwrap()); - assert_eq!( - "rand[693ea8e72247470f]::rngs::adapter::reseeding::fork::FORK_HANDLER_REGISTERED.0.0", - iter.next().unwrap() - ); - assert!(iter.next().is_none()); + for (expected, actual) in DEMANGLED_OUTPUT.lines().zip(demangled_lines) { + assert_eq!(expected, actual); + } } #[test] fn test_demangle_lines_no_crate_disambiguators() { let demangled_lines = demangle_lines(MANGLED_INPUT.lines(), Some(create_disambiguator_re())); - let mut iter = demangled_lines.iter(); - assert_eq!("", iter.next().unwrap()); - assert_eq!("123foo[0]::bar", iter.next().unwrap()); - assert_eq!("utf8_idents::საჭმელად_გემრიელი_სადილი", iter.next().unwrap()); - assert_eq!("cc::spawn::{closure#0}::{closure#0}", iter.next().unwrap()); - assert_eq!( - " as core::iter::iterator::Iterator>::rposition::::{closure#0}", - iter.next().unwrap() - ); - assert_eq!( - "alloc::alloc::box_free::>", - iter.next().unwrap() - ); - assert_eq!("INtC8arrayvec8ArrayVechKj7b_E", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">", iter.next().unwrap()); - assert_eq!(">::foo::FOO", iter.next().unwrap()); - assert_eq!("foo[0]", iter.next().unwrap()); - assert_eq!("foo[0]", iter.next().unwrap()); - assert_eq!("backtrace[0]::foo", iter.next().unwrap()); - assert_eq!( - "rand::rngs::adapter::reseeding::fork::FORK_HANDLER_REGISTERED.0.0", - iter.next().unwrap() - ); - assert!(iter.next().is_none()); + for (expected, actual) in DEMANGLED_OUTPUT_NO_CRATE_DISAMBIGUATORS.lines().zip(demangled_lines) + { + assert_eq!(expected, actual); + } } From 0513ba4d65b953ab637fbafd979a9bd002b93e5c Mon Sep 17 00:00:00 2001 From: The8472 Date: Sun, 21 Feb 2021 12:08:04 +0100 Subject: [PATCH 333/370] perform filesystem probe once before running bins checks concurrently this avoids concurrent write attempts to the output directory --- src/tools/tidy/src/bins.rs | 176 ++++++++++++++++++++++--------------- src/tools/tidy/src/lib.rs | 7 -- src/tools/tidy/src/main.rs | 11 ++- 3 files changed, 112 insertions(+), 82 deletions(-) diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs index f4e203cac40..1d5ec5c31c6 100644 --- a/src/tools/tidy/src/bins.rs +++ b/src/tools/tidy/src/bins.rs @@ -5,94 +5,126 @@ //! huge amount of bloat to the Git history, so it's good to just ensure we //! don't do that again. -use std::path::Path; +pub use os_impl::*; // All files are executable on Windows, so just check on Unix. #[cfg(windows)] -pub fn check(_path: &Path, _output: &Path, _bad: &mut bool) {} +mod os_impl { + use std::path::Path; + + pub fn check_filesystem_support(_sources: &[&Path], _output: &Path) -> bool { + return false; + } + + pub fn check(_path: &Path, _bad: &mut bool) {} +} #[cfg(unix)] -pub fn check(path: &Path, output: &Path, bad: &mut bool) { +mod os_impl { use std::fs; use std::os::unix::prelude::*; + use std::path::Path; use std::process::{Command, Stdio}; + enum FilesystemSupport { + Supported, + Unsupported, + ReadOnlyFs, + } + + use FilesystemSupport::*; + fn is_executable(path: &Path) -> std::io::Result { Ok(path.metadata()?.mode() & 0o111 != 0) } - // We want to avoid false positives on filesystems that do not support the - // executable bit. This occurs on some versions of Window's linux subsystem, - // for example. - // - // We try to create the temporary file first in the src directory, which is - // the preferred location as it's most likely to be on the same filesystem, - // and then in the output (`build`) directory if that fails. Sometimes we - // see the source directory mounted as read-only which means we can't - // readily create a file there to test. - // - // See #36706 and #74753 for context. - // - // We also add the thread ID to avoid threads trampling on each others files. - let file_name = format!("t{}.tidy-test-file", std::thread::current().id().as_u64()); - let mut temp_path = path.join(&file_name); - match fs::File::create(&temp_path).or_else(|_| { - temp_path = output.join(&file_name); - fs::File::create(&temp_path) - }) { - Ok(file) => { - let exec = is_executable(&temp_path).unwrap_or(false); - std::mem::drop(file); - std::fs::remove_file(&temp_path).expect("Deleted temp file"); - if exec { - // If the file is executable, then we assume that this - // filesystem does not track executability, so skip this check. - return; - } - } - Err(e) => { - // If the directory is read-only or we otherwise don't have rights, - // just don't run this check. - // - // 30 is the "Read-only filesystem" code at least in one CI - // environment. - if e.raw_os_error() == Some(30) { - eprintln!("tidy: Skipping binary file check, read-only filesystem"); - return; - } + pub fn check_filesystem_support(sources: &[&Path], output: &Path) -> bool { + // We want to avoid false positives on filesystems that do not support the + // executable bit. This occurs on some versions of Window's linux subsystem, + // for example. + // + // We try to create the temporary file first in the src directory, which is + // the preferred location as it's most likely to be on the same filesystem, + // and then in the output (`build`) directory if that fails. Sometimes we + // see the source directory mounted as read-only which means we can't + // readily create a file there to test. + // + // See #36706 and #74753 for context. - panic!("unable to create temporary file `{:?}`: {:?}", temp_path, e); + fn check_dir(dir: &Path) -> FilesystemSupport { + let path = dir.join("tidy-test-file"); + match fs::File::create(&path) { + Ok(file) => { + let exec = is_executable(&path).unwrap_or(false); + std::mem::drop(file); + std::fs::remove_file(&path).expect("Deleted temp file"); + // If the file is executable, then we assume that this + // filesystem does not track executability, so skip this check. + return if exec { Unsupported } else { Supported }; + } + Err(e) => { + // If the directory is read-only or we otherwise don't have rights, + // just don't run this check. + // + // 30 is the "Read-only filesystem" code at least in one CI + // environment. + if e.raw_os_error() == Some(30) { + eprintln!("tidy: Skipping binary file check, read-only filesystem"); + return ReadOnlyFs; + } + + panic!("unable to create temporary file `{:?}`: {:?}", path, e); + } + }; } + + for &source_dir in sources { + match check_dir(source_dir) { + Unsupported => return false, + ReadOnlyFs => { + return match check_dir(output) { + Supported => true, + _ => false, + }; + } + _ => {} + } + } + + return true; } - super::walk_no_read( - path, - &mut |path| super::filter_dirs(path) || path.ends_with("src/etc"), - &mut |entry| { - let file = entry.path(); - let filename = file.file_name().unwrap().to_string_lossy(); - let extensions = [".py", ".sh"]; - if extensions.iter().any(|e| filename.ends_with(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("\\", "/"); - 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()); + #[cfg(unix)] + pub fn check(path: &Path, bad: &mut bool) { + crate::walk_no_read( + path, + &mut |path| crate::filter_dirs(path) || path.ends_with("src/etc"), + &mut |entry| { + let file = entry.path(); + let filename = file.file_name().unwrap().to_string_lossy(); + let extensions = [".py", ".sh"]; + if extensions.iter().any(|e| filename.ends_with(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("\\", "/"); + 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/lib.rs b/src/tools/tidy/src/lib.rs index 45cc169470b..11d36751f67 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -4,7 +4,6 @@ //! to be used by tools. #![cfg_attr(bootstrap, feature(str_split_once))] -#![feature(thread_id_value)] use std::fs::File; use std::io::Read; @@ -55,12 +54,6 @@ pub mod unit_tests; pub mod unstable_book; fn filter_dirs(path: &Path) -> bool { - // Filter out temporary files used by the bins module to probe the filesystem - match path.extension() { - Some(ext) if ext == "tidy-test-file" => return true, - _ => {} - } - let skip = [ "compiler/rustc_codegen_cranelift", "src/llvm-project", diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 2d19db38799..f190a9e57ce 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -75,9 +75,14 @@ fn main() { check!(unit_tests, &compiler_path); check!(unit_tests, &library_path); - check!(bins, &src_path, &output_directory); - check!(bins, &compiler_path, &output_directory); - check!(bins, &library_path, &output_directory); + if bins::check_filesystem_support( + &[&src_path, &compiler_path, &library_path], + &output_directory, + ) { + check!(bins, &src_path); + check!(bins, &compiler_path); + check!(bins, &library_path); + } check!(style, &src_path); check!(style, &compiler_path); From 5f92951d4ff91085ae7af62b2abf43fffde8b35d Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 3 Apr 2021 19:08:14 -0700 Subject: [PATCH 334/370] rustdoc: sort search index items for compression This should not affect the appearance of the docs pages themselves. This makes the pre-compressed search index smaller, thanks to the empty-string path duplication format, and also the gzipped version, by giving the algorithm more structure to work with. rust$ wc -c search-index-old.js search-index-new.js 2628334 search-index-old.js 2586181 search-index-new.js 5214515 total rust$ gzip search-index-* rust$ wc -c search-index-old.js.gz search-index-new.js.gz 239486 search-index-old.js.gz 237386 search-index-new.js.gz 476872 total --- src/librustdoc/clean/types.rs | 4 ++-- src/librustdoc/formats/cache.rs | 9 +-------- src/librustdoc/html/render/cache.rs | 23 ++++++++++++++++------- src/librustdoc/html/render/mod.rs | 1 + 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 4132e187c72..49a91240b6a 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -914,7 +914,7 @@ impl Attributes { .collect() } - crate fn get_doc_aliases(&self) -> FxHashSet { + crate fn get_doc_aliases(&self) -> Box<[String]> { let mut aliases = FxHashSet::default(); for attr in self.other_attrs.lists(sym::doc).filter(|a| a.has_name(sym::alias)) { @@ -931,7 +931,7 @@ impl Attributes { aliases.insert(attr.value_str().map(|s| s.to_string()).unwrap()); } } - aliases + aliases.into_iter().collect::>().into() } } diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 01bceb1d910..7100cc87b0c 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -309,15 +309,8 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { parent, parent_idx: None, search_type: get_index_search_type(&item, &self.empty_cache, self.tcx), + aliases: item.attrs.get_doc_aliases(), }); - - for alias in item.attrs.get_doc_aliases() { - self.cache - .aliases - .entry(alias.to_lowercase()) - .or_insert(Vec::new()) - .push(self.cache.search_index.len() - 1); - } } } (Some(parent), None) if is_inherent_impl_item => { diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 5d49a494727..022afee3105 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -82,19 +82,28 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< parent: Some(did), parent_idx: None, search_type: get_index_search_type(&item, cache, tcx), + aliases: item.attrs.get_doc_aliases(), }); - for alias in item.attrs.get_doc_aliases() { - cache - .aliases - .entry(alias.to_lowercase()) - .or_insert(Vec::new()) - .push(cache.search_index.len() - 1); - } } } let Cache { ref mut search_index, ref paths, ref mut aliases, .. } = *cache; + // Sort search index items. This improves the compressibility of the search index. + search_index.sort_unstable_by(|k1, k2| { + // `sort_unstable_by_key` produces lifetime errors + let k1 = (&k1.path, &k1.name, &k1.ty, &k1.parent); + let k2 = (&k2.path, &k2.name, &k2.ty, &k2.parent); + std::cmp::Ord::cmp(&k1, &k2) + }); + + // Set up alias indexes. + for (i, item) in search_index.iter().enumerate() { + for alias in &item.aliases[..] { + aliases.entry(alias.to_lowercase()).or_insert(Vec::new()).push(i); + } + } + // Reduce `DefId` in paths into smaller sequential numbers, // and prune the paths that do not appear in the index. let mut lastpath = String::new(); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 07bd26a4c5e..cb5ca5b5e64 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -164,6 +164,7 @@ crate struct IndexItem { crate parent: Option, crate parent_idx: Option, crate search_type: Option, + crate aliases: Box<[String]>, } /// A type used for the search index. From 5d1747bf07311f893829728c0e26e088794651e1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 4 Apr 2021 11:24:25 +0200 Subject: [PATCH 335/370] rely on intra-doc links Co-authored-by: Yuki Okushi --- library/core/src/ptr/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index ba14b1abdb2..bed5e0b8998 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1548,8 +1548,6 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L } /// See [`addr_of_mut`] for how to create a pointer to ininitialized data. /// Doing that with `addr_of` would not make much sense since one could only /// read the data, and that would be Undefined Behavior. -/// -/// [`addr_of_mut`]: macro.addr_of_mut.html #[stable(feature = "raw_ref_macros", since = "1.51.0")] #[rustc_macro_transparency = "semitransparent"] #[allow_internal_unstable(raw_ref_op)] From ddc53f809b89001c08296b5b49fe1fcad1e566d5 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sun, 4 Apr 2021 08:09:56 +0100 Subject: [PATCH 336/370] Allow clobbering unsupported registers in asm! Previously registers could only be marked as clobbered if the target feature for that register was enabled. This restriction is now removed. --- compiler/rustc_ast_lowering/src/expr.rs | 82 +++++++++++++++---------- compiler/rustc_codegen_llvm/src/asm.rs | 27 +++++++- src/test/codegen/asm-target-clobbers.rs | 21 +++++++ 3 files changed, 97 insertions(+), 33 deletions(-) create mode 100644 src/test/codegen/asm-target-clobbers.rs diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 32fb8d1c8f4..d5a9d7ee6e3 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1499,46 +1499,64 @@ impl<'hir> LoweringContext<'_, 'hir> { // previous iteration. required_features.clear(); - // Validate register classes against currently enabled target - // features. We check that at least one type is available for - // the current target. let reg_class = reg.reg_class(); if reg_class == asm::InlineAsmRegClass::Err { continue; } - for &(_, feature) in reg_class.supported_types(asm_arch.unwrap()) { - if let Some(feature) = feature { - if self.sess.target_features.contains(&Symbol::intern(feature)) { + + // We ignore target feature requirements for clobbers: if the + // feature is disabled then the compiler doesn't care what we + // do with the registers. + // + // Note that this is only possible for explicit register + // operands, which cannot be used in the asm string. + let is_clobber = matches!( + op, + hir::InlineAsmOperand::Out { + reg: asm::InlineAsmRegOrRegClass::Reg(_), + late: _, + expr: None + } + ); + + if !is_clobber { + // Validate register classes against currently enabled target + // features. We check that at least one type is available for + // the current target. + for &(_, feature) in reg_class.supported_types(asm_arch.unwrap()) { + if let Some(feature) = feature { + if self.sess.target_features.contains(&Symbol::intern(feature)) { + required_features.clear(); + break; + } else { + required_features.push(feature); + } + } else { required_features.clear(); break; - } else { - required_features.push(feature); } - } else { - required_features.clear(); - break; } - } - // We are sorting primitive strs here and can use unstable sort here - required_features.sort_unstable(); - required_features.dedup(); - match &required_features[..] { - [] => {} - [feature] => { - let msg = format!( - "register class `{}` requires the `{}` target feature", - reg_class.name(), - feature - ); - sess.struct_span_err(op_sp, &msg).emit(); - } - features => { - let msg = format!( - "register class `{}` requires at least one target feature: {}", - reg_class.name(), - features.join(", ") - ); - sess.struct_span_err(op_sp, &msg).emit(); + // We are sorting primitive strs here and can use unstable sort here + required_features.sort_unstable(); + required_features.dedup(); + match &required_features[..] { + [] => {} + [feature] => { + let msg = format!( + "register class `{}` requires the `{}` target feature", + reg_class.name(), + feature + ); + sess.struct_span_err(op_sp, &msg).emit(); + } + features => { + let msg = format!( + "register class `{}` requires at least one target feature: {}", + reg_class.name(), + features.join(", ") + ); + sess.struct_span_err(op_sp, &msg).emit(); + } } } diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index e7d359c4f14..84b091d8d4d 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -14,7 +14,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::{bug, span_bug}; -use rustc_span::{Pos, Span}; +use rustc_span::{Pos, Span, Symbol}; use rustc_target::abi::*; use rustc_target::asm::*; @@ -125,15 +125,39 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { // Collect the types of output operands let mut constraints = vec![]; + let mut clobbers = vec![]; let mut output_types = vec![]; let mut op_idx = FxHashMap::default(); for (idx, op) in operands.iter().enumerate() { match *op { InlineAsmOperandRef::Out { reg, late, place } => { + let is_target_supported = |reg_class: InlineAsmRegClass| { + for &(_, feature) in reg_class.supported_types(asm_arch) { + if let Some(feature) = feature { + if self.tcx.sess.target_features.contains(&Symbol::intern(feature)) + { + return true; + } + } else { + // Register class is unconditionally supported + return true; + } + } + false + }; + let mut layout = None; let ty = if let Some(ref place) = place { layout = Some(&place.layout); llvm_fixup_output_type(self.cx, reg.reg_class(), &place.layout) + } else if !is_target_supported(reg.reg_class()) { + // We turn discarded outputs into clobber constraints + // if the target feature needed by the register class is + // disabled. This is necessary otherwise LLVM will try + // to actually allocate a register for the dummy output. + assert!(matches!(reg, InlineAsmRegOrRegClass::Reg(_))); + clobbers.push(format!("~{}", reg_to_llvm(reg, None))); + continue; } else { // If the output is discarded, we don't really care what // type is used. We're just using this to tell LLVM to @@ -244,6 +268,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { } } + constraints.append(&mut clobbers); if !options.contains(InlineAsmOptions::PRESERVES_FLAGS) { match asm_arch { InlineAsmArch::AArch64 | InlineAsmArch::Arm => { diff --git a/src/test/codegen/asm-target-clobbers.rs b/src/test/codegen/asm-target-clobbers.rs new file mode 100644 index 00000000000..f637cdcd234 --- /dev/null +++ b/src/test/codegen/asm-target-clobbers.rs @@ -0,0 +1,21 @@ +// only-x86_64 +// revisions: base avx512 +// [avx512]compile-flags: -C target-feature=+avx512f + +#![crate_type = "rlib"] +#![feature(asm)] + +// CHECK-LABEL: @avx512_clobber +// base: call void asm sideeffect inteldialect "", "~{xmm31}"() +// avx512: call float asm sideeffect inteldialect "", "=&{xmm31}"() +#[no_mangle] +pub unsafe fn avx512_clobber() { + asm!("", out("zmm31") _, options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @eax_clobber +// CHECK: call i32 asm sideeffect inteldialect "", "=&{ax}"() +#[no_mangle] +pub unsafe fn eax_clobber() { + asm!("", out("eax") _, options(nostack, nomem, preserves_flags)); +} From 31d0459207d3623cabf931ed6b272b45592c2a7e Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sun, 4 Apr 2021 10:49:44 +0100 Subject: [PATCH 337/370] Update clobber example in the asm documentation --- src/doc/unstable-book/src/library-features/asm.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index c0e23b834d1..25d8629a38f 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -306,13 +306,19 @@ fn call_foo(arg: i32) { sym foo, // 1st argument in rdi, which is caller-saved inout("rdi") arg => _, - // All caller-saved registers must be marked as clobberred + // All caller-saved registers must be marked as clobbered out("rax") _, out("rcx") _, out("rdx") _, out("rsi") _, out("r8") _, out("r9") _, out("r10") _, out("r11") _, out("xmm0") _, out("xmm1") _, out("xmm2") _, out("xmm3") _, out("xmm4") _, out("xmm5") _, out("xmm6") _, out("xmm7") _, out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _, out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _, + // Also mark AVX-512 registers as clobbered. This is accepted by the + // compiler even if AVX-512 is not enabled on the current target. + out("xmm16") _, out("xmm17") _, out("xmm18") _, out("xmm19") _, + out("xmm20") _, out("xmm21") _, out("xmm22") _, out("xmm13") _, + out("xmm24") _, out("xmm25") _, out("xmm26") _, out("xmm27") _, + out("xmm28") _, out("xmm29") _, out("xmm30") _, out("xmm31") _, ) } } From a41d41cbc66b81111704a8787bf408b78de7730d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 24 Mar 2021 21:42:04 +0100 Subject: [PATCH 338/370] Fix error codes check run and ensure it will not go unnoticed again --- src/tools/tidy/src/error_codes_check.rs | 40 +++++++++++++++++-------- src/tools/tidy/src/main.rs | 2 +- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs index a7199fdfce6..55f824b63f2 100644 --- a/src/tools/tidy/src/error_codes_check.rs +++ b/src/tools/tidy/src/error_codes_check.rs @@ -48,6 +48,8 @@ fn check_error_code_explanation( } fn check_if_error_code_is_test_in_explanation(f: &str, err_code: &str) -> bool { + let mut ignore_found = false; + for line in f.lines() { let s = line.trim(); if s.starts_with("#### Note: this error code is no longer emitted by the compiler") { @@ -56,13 +58,13 @@ fn check_if_error_code_is_test_in_explanation(f: &str, err_code: &str) -> bool { if s.starts_with("```") { if s.contains("compile_fail") && s.contains(err_code) { return true; - } else if s.contains('(') { + } else if s.contains("ignore") { // It's very likely that we can't actually make it fail compilation... - return true; + ignore_found = true; } } } - false + ignore_found } macro_rules! some_or_continue { @@ -164,18 +166,32 @@ fn extract_error_codes_from_tests(f: &str, error_codes: &mut HashMap = HashMap::new(); - super::walk(path, &mut |path| super::filter_dirs(path), &mut |entry, contents| { - let file_name = entry.file_name(); - if file_name == "error_codes.rs" { - extract_error_codes(contents, &mut error_codes, entry.path(), &mut errors); - } else if entry.path().extension() == Some(OsStr::new("stderr")) { - extract_error_codes_from_tests(contents, &mut error_codes); - } - }); + for path in paths { + super::walk(path, &mut |path| super::filter_dirs(path), &mut |entry, contents| { + let file_name = entry.file_name(); + if file_name == "error_codes.rs" { + extract_error_codes(contents, &mut error_codes, entry.path(), &mut errors); + found_explanations += 1; + } else if entry.path().extension() == Some(OsStr::new("stderr")) { + extract_error_codes_from_tests(contents, &mut error_codes); + found_tests += 1; + } + }); + } + if found_explanations == 0 { + eprintln!("No error code explanation was tested!"); + *bad = true; + } + if found_tests == 0 { + eprintln!("No error code was found in compilation errors!"); + *bad = true; + } if errors.is_empty() { println!("Found {} error codes", error_codes.len()); diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index f190a9e57ce..10356a2fdc5 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -65,7 +65,7 @@ fn main() { // Checks that only make sense for the compiler. check!(errors, &compiler_path); - check!(error_codes_check, &src_path); + check!(error_codes_check, &[&src_path, &compiler_path]); // Checks that only make sense for the std libs. check!(pal, &library_path); From fbf1bec48228a5c6c16073319cd4c9a54ec28c9f Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 8 Mar 2021 15:05:03 +0300 Subject: [PATCH 339/370] resolve/expand: Cache intermediate results of `#[derive]` expansion --- compiler/rustc_builtin_macros/src/derive.rs | 57 ++++++++------ compiler/rustc_expand/src/base.rs | 9 +-- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 15 +++- compiler/rustc_resolve/src/macros.rs | 87 ++++++++++++--------- 5 files changed, 97 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index 0da2c1c1021..1bb050a40ce 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -1,6 +1,6 @@ use crate::cfg_eval::cfg_eval; -use rustc_ast::{self as ast, token, ItemKind, MetaItemKind, NestedMetaItem, StmtKind}; +use rustc_ast::{self as ast, attr, token, ItemKind, MetaItemKind, NestedMetaItem, StmtKind}; use rustc_errors::{struct_span_err, Applicability}; use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier}; use rustc_feature::AttributeTemplate; @@ -26,32 +26,39 @@ impl MultiItemModifier for Expander { return ExpandResult::Ready(vec![item]); } - let template = - AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() }; - let attr = ecx.attribute(meta_item.clone()); - validate_attr::check_builtin_attribute(&sess.parse_sess, &attr, sym::derive, template); + let result = + ecx.resolver.resolve_derives(ecx.current_expansion.id, ecx.force_mode, &|| { + let template = + AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() }; + let attr = attr::mk_attr_outer(meta_item.clone()); + validate_attr::check_builtin_attribute( + &sess.parse_sess, + &attr, + sym::derive, + template, + ); - let derives: Vec<_> = attr - .meta_item_list() - .unwrap_or_default() - .into_iter() - .filter_map(|nested_meta| match nested_meta { - NestedMetaItem::MetaItem(meta) => Some(meta), - NestedMetaItem::Literal(lit) => { - // Reject `#[derive("Debug")]`. - report_unexpected_literal(sess, &lit); - None - } - }) - .map(|meta| { - // Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the paths. - report_path_args(sess, &meta); - meta.path - }) - .collect(); + attr.meta_item_list() + .unwrap_or_default() + .into_iter() + .filter_map(|nested_meta| match nested_meta { + NestedMetaItem::MetaItem(meta) => Some(meta), + NestedMetaItem::Literal(lit) => { + // Reject `#[derive("Debug")]`. + report_unexpected_literal(sess, &lit); + None + } + }) + .map(|meta| { + // Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the paths. + report_path_args(sess, &meta); + meta.path + }) + .map(|path| (path, None)) + .collect() + }); - // FIXME: Try to cache intermediate results to avoid collecting same paths multiple times. - match ecx.resolver.resolve_derives(ecx.current_expansion.id, derives, ecx.force_mode) { + match result { Ok(()) => ExpandResult::Ready(cfg_eval(ecx, item)), Err(Indeterminate) => ExpandResult::Retry(item), } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 594b9a82ad0..a2035ee3c6e 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -868,6 +868,8 @@ impl SyntaxExtension { /// Error type that denotes indeterminacy. pub struct Indeterminate; +pub type DeriveResolutions = Vec<(ast::Path, Option>)>; + pub trait ResolverExpand { fn next_node_id(&mut self) -> NodeId; @@ -904,15 +906,12 @@ pub trait ResolverExpand { fn resolve_derives( &mut self, expn_id: ExpnId, - derives: Vec, force: bool, + derive_paths: &dyn Fn() -> DeriveResolutions, ) -> Result<(), Indeterminate>; /// Take resolutions for paths inside the `#[derive(...)]` attribute with the given `ExpnId` /// back from resolver. - fn take_derive_resolutions( - &mut self, - expn_id: ExpnId, - ) -> Option, ast::Path)>>; + fn take_derive_resolutions(&mut self, expn_id: ExpnId) -> Option; /// Path resolution logic for `#[cfg_accessible(path)]`. fn cfg_accessible(&mut self, expn_id: ExpnId, path: &ast::Path) -> Result; } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 470788a972a..53e2b4e6acc 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -515,7 +515,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { invocations.reserve(derives.len()); derives .into_iter() - .map(|(_exts, path)| { + .map(|(path, _exts)| { // FIXME: Consider using the derive resolutions (`_exts`) // instead of enqueuing the derives to be resolved again later. let expn_id = ExpnId::fresh(None); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index fe5078f26bd..9488ce14a54 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -37,7 +37,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::ptr_key::PtrKey; use rustc_data_structures::sync::Lrc; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; -use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; +use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind}; use rustc_hir::def::Namespace::*; use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX}; @@ -851,6 +851,12 @@ enum BuiltinMacroState { AlreadySeen(Span), } +struct DeriveData { + resolutions: DeriveResolutions, + helper_attrs: Vec, + has_derive_copy: bool, +} + /// The main resolver class. /// /// This is the visitor that walks the whole crate. @@ -973,8 +979,9 @@ pub struct Resolver<'a> { output_macro_rules_scopes: FxHashMap>, /// Helper attributes that are in scope for the given expansion. helper_attrs: FxHashMap>, - /// Resolutions for paths inside the `#[derive(...)]` attribute with the given `ExpnId`. - derive_resolutions: FxHashMap, ast::Path)>>, + /// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute + /// with the given `ExpnId`. + derive_data: FxHashMap, /// Avoid duplicated errors for "name already defined". name_already_seen: FxHashMap, @@ -1310,7 +1317,7 @@ impl<'a> Resolver<'a> { invocation_parent_scopes: Default::default(), output_macro_rules_scopes: Default::default(), helper_attrs: Default::default(), - derive_resolutions: Default::default(), + derive_data: Default::default(), local_macro_def_scopes: FxHashMap::default(), name_already_seen: FxHashMap::default(), potentially_unused_imports: Vec::new(), diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index d238f65c941..567a99e4abf 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -4,7 +4,7 @@ use crate::imports::ImportResolver; use crate::Namespace::*; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BuiltinMacroState, Determinacy}; -use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak}; +use crate::{CrateLint, DeriveData, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak}; use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding}; use rustc_ast::{self as ast, Inline, ItemKind, ModKind, NodeId}; use rustc_ast_lowering::ResolverAstLowering; @@ -14,8 +14,8 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::ptr_key::PtrKey; use rustc_data_structures::sync::Lrc; use rustc_errors::struct_span_err; -use rustc_expand::base::Annotatable; -use rustc_expand::base::{Indeterminate, ResolverExpand, SyntaxExtension, SyntaxExtensionKind}; +use rustc_expand::base::{Annotatable, DeriveResolutions, Indeterminate, ResolverExpand}; +use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::compile_declarative_macro; use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion}; use rustc_feature::is_builtin_attr_name; @@ -359,8 +359,8 @@ impl<'a> ResolverExpand for Resolver<'a> { fn resolve_derives( &mut self, expn_id: ExpnId, - derives: Vec, force: bool, + derive_paths: &dyn Fn() -> DeriveResolutions, ) -> Result<(), Indeterminate> { // Block expansion of the container until we resolve all derives in it. // This is required for two reasons: @@ -368,49 +368,60 @@ impl<'a> ResolverExpand for Resolver<'a> { // is applied, so they have to be produced by the container's expansion rather // than by individual derives. // - Derives in the container need to know whether one of them is a built-in `Copy`. - // FIXME: Try to cache intermediate results to avoid resolving same derives multiple times. + // Temporarily take the data to avoid borrow checker conflicts. + let mut derive_data = mem::take(&mut self.derive_data); + let entry = derive_data.entry(expn_id).or_insert_with(|| DeriveData { + resolutions: derive_paths(), + helper_attrs: Vec::new(), + has_derive_copy: false, + }); let parent_scope = self.invocation_parent_scopes[&expn_id]; - let mut exts = Vec::new(); - let mut helper_attrs = Vec::new(); - let mut has_derive_copy = false; - for path in derives { - exts.push(( - match self.resolve_macro_path( - &path, - Some(MacroKind::Derive), - &parent_scope, - true, - force, - ) { - Ok((Some(ext), _)) => { - let span = - path.segments.last().unwrap().ident.span.normalize_to_macros_2_0(); - helper_attrs - .extend(ext.helper_attrs.iter().map(|name| Ident::new(*name, span))); - has_derive_copy |= ext.builtin_name == Some(sym::Copy); - ext - } - Ok(_) | Err(Determinacy::Determined) => self.dummy_ext(MacroKind::Derive), - Err(Determinacy::Undetermined) => return Err(Indeterminate), - }, - path, - )) + for (path, opt_ext) in &mut entry.resolutions { + if opt_ext.is_none() { + *opt_ext = Some( + match self.resolve_macro_path( + &path, + Some(MacroKind::Derive), + &parent_scope, + true, + force, + ) { + Ok((Some(ext), _)) => { + if !ext.helper_attrs.is_empty() { + let last_seg = path.segments.last().unwrap(); + let span = last_seg.ident.span.normalize_to_macros_2_0(); + entry.helper_attrs.extend( + ext.helper_attrs.iter().map(|name| Ident::new(*name, span)), + ); + } + entry.has_derive_copy |= ext.builtin_name == Some(sym::Copy); + ext + } + Ok(_) | Err(Determinacy::Determined) => self.dummy_ext(MacroKind::Derive), + Err(Determinacy::Undetermined) => { + assert!(self.derive_data.is_empty()); + self.derive_data = derive_data; + return Err(Indeterminate); + } + }, + ); + } } - self.derive_resolutions.insert(expn_id, exts); - self.helper_attrs.insert(expn_id, helper_attrs); + // If we get to here, then `derive_data` for the given `expn_id` will only be accessed by + // `take_derive_resolutions` later, so we can steal `helper_attrs` instead of cloning them. + self.helper_attrs.insert(expn_id, mem::take(&mut entry.helper_attrs)); // Mark this derive as having `Copy` either if it has `Copy` itself or if its parent derive // has `Copy`, to support cases like `#[derive(Clone, Copy)] #[derive(Debug)]`. - if has_derive_copy || self.has_derive_copy(parent_scope.expansion) { + if entry.has_derive_copy || self.has_derive_copy(parent_scope.expansion) { self.containers_deriving_copy.insert(expn_id); } + assert!(self.derive_data.is_empty()); + self.derive_data = derive_data; Ok(()) } - fn take_derive_resolutions( - &mut self, - expn_id: ExpnId, - ) -> Option, ast::Path)>> { - self.derive_resolutions.remove(&expn_id) + fn take_derive_resolutions(&mut self, expn_id: ExpnId) -> Option { + self.derive_data.remove(&expn_id).map(|data| data.resolutions) } // The function that implements the resolution logic of `#[cfg_accessible(path)]`. From b96584485a43c561d90eb262651ecb87d1d98d2a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 4 Apr 2021 17:51:31 +0300 Subject: [PATCH 340/370] resolve: Stable order for derive helper attributes --- compiler/rustc_resolve/src/lib.rs | 2 +- compiler/rustc_resolve/src/macros.rs | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 9488ce14a54..d474e990211 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -853,7 +853,7 @@ enum BuiltinMacroState { struct DeriveData { resolutions: DeriveResolutions, - helper_attrs: Vec, + helper_attrs: Vec<(usize, Ident)>, has_derive_copy: bool, } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 567a99e4abf..10e27f33c29 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -376,7 +376,7 @@ impl<'a> ResolverExpand for Resolver<'a> { has_derive_copy: false, }); let parent_scope = self.invocation_parent_scopes[&expn_id]; - for (path, opt_ext) in &mut entry.resolutions { + for (i, (path, opt_ext)) in entry.resolutions.iter_mut().enumerate() { if opt_ext.is_none() { *opt_ext = Some( match self.resolve_macro_path( @@ -391,7 +391,9 @@ impl<'a> ResolverExpand for Resolver<'a> { let last_seg = path.segments.last().unwrap(); let span = last_seg.ident.span.normalize_to_macros_2_0(); entry.helper_attrs.extend( - ext.helper_attrs.iter().map(|name| Ident::new(*name, span)), + ext.helper_attrs + .iter() + .map(|name| (i, Ident::new(*name, span))), ); } entry.has_derive_copy |= ext.builtin_name == Some(sym::Copy); @@ -407,9 +409,10 @@ impl<'a> ResolverExpand for Resolver<'a> { ); } } - // If we get to here, then `derive_data` for the given `expn_id` will only be accessed by - // `take_derive_resolutions` later, so we can steal `helper_attrs` instead of cloning them. - self.helper_attrs.insert(expn_id, mem::take(&mut entry.helper_attrs)); + // Sort helpers in a stable way independent from the derive resolution order. + entry.helper_attrs.sort_by_key(|(i, _)| *i); + self.helper_attrs + .insert(expn_id, entry.helper_attrs.iter().map(|(_, ident)| *ident).collect()); // Mark this derive as having `Copy` either if it has `Copy` itself or if its parent derive // has `Copy`, to support cases like `#[derive(Clone, Copy)] #[derive(Debug)]`. if entry.has_derive_copy || self.has_derive_copy(parent_scope.expansion) { From da66a31572e0f49981d6b958ecdd95397ecf2d3f Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Wed, 30 Dec 2020 12:52:21 -0600 Subject: [PATCH 341/370] wasm64 --- compiler/rustc_codegen_llvm/src/attributes.rs | 2 +- compiler/rustc_codegen_llvm/src/back/write.rs | 5 +- .../src/debuginfo/metadata.rs | 4 +- compiler/rustc_codegen_ssa/src/back/linker.rs | 2 +- .../rustc_codegen_ssa/src/target_features.rs | 2 +- compiler/rustc_session/src/config.rs | 3 + compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_symbol_mangling/src/lib.rs | 2 +- compiler/rustc_target/src/abi/call/mod.rs | 2 + compiler/rustc_target/src/abi/call/wasm64.rs | 58 +++++++++++++++++++ compiler/rustc_target/src/spec/mod.rs | 8 ++- .../rustc_target/src/spec/tests/tests_impl.rs | 1 + .../src/spec/wasm32_unknown_emscripten.rs | 4 +- .../src/spec/wasm32_unknown_unknown.rs | 4 +- compiler/rustc_target/src/spec/wasm32_wasi.rs | 4 +- .../src/spec/wasm64_unknown_unknown.rs | 39 +++++++++++++ .../src/spec/{wasm32_base.rs => wasm_base.rs} | 2 + src/doc/rustc/src/platform-support.md | 1 + src/librustdoc/clean/cfg.rs | 3 +- 19 files changed, 129 insertions(+), 18 deletions(-) create mode 100644 compiler/rustc_target/src/abi/call/wasm64.rs create mode 100644 compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs rename compiler/rustc_target/src/spec/{wasm32_base.rs => wasm_base.rs} (99%) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 64ebe585dd8..531847c7a0e 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -317,7 +317,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: // Note that currently the `wasm-import-module` doesn't do anything, but // eventually LLVM 7 should read this and ferry the appropriate import // module to the output file. - if cx.tcx.sess.target.arch == "wasm32" { + if cx.tcx.sess.target.is_like_wasm { if let Some(module) = wasm_import_module(cx.tcx, instance.def_id()) { llvm::AddFunctionAttrStringValue( llfn, diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 388dd7ce81b..b354b97b2d5 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -170,10 +170,7 @@ pub fn target_machine_factory( // On the wasm target once the `atomics` feature is enabled that means that // we're no longer single-threaded, or otherwise we don't want LLVM to // lower atomic operations to single-threaded operations. - if singlethread - && sess.target.llvm_target.contains("wasm32") - && sess.target_features.contains(&sym::atomics) - { + if singlethread && sess.target.is_like_wasm && sess.target_features.contains(&sym::atomics) { singlethread = false; } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index d5b32e58cc3..a6a7f6e0f5b 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1083,9 +1083,9 @@ pub fn compile_unit_metadata( ); } - // Insert `llvm.ident` metadata on the wasm32 targets since that will + // Insert `llvm.ident` metadata on the wasm targets since that will // get hooked up to the "producer" sections `processed-by` information. - if tcx.sess.opts.target_triple.triple().starts_with("wasm32") { + if tcx.sess.target.is_like_wasm { let name_metadata = llvm::LLVMMDStringInContext( debug_context.llcontext, rustc_producer.as_ptr().cast(), diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index bb35e7ec894..911bdad314d 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -184,7 +184,7 @@ impl<'a> GccLinker<'a> { // * On OSX they have their own linker, not binutils' // * For WebAssembly the only functional linker is LLD, which doesn't // support hint flags - !self.sess.target.is_like_osx && self.sess.target.arch != "wasm32" + !self.sess.target.is_like_osx && !self.sess.target.is_like_wasm } // Some platforms take hints about whether a library is static or dynamic. diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index fd18f42f2dd..3254b555ada 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -160,7 +160,7 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt "mips" | "mips64" => MIPS_ALLOWED_FEATURES, "powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES, "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES, - "wasm32" => WASM_ALLOWED_FEATURES, + "wasm32" | "wasm64" => WASM_ALLOWED_FEATURES, _ => &[], } } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 75078a12311..724e32bc495 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -859,6 +859,9 @@ pub fn default_configuration(sess: &Session) -> CrateConfig { } } ret.insert((sym::target_arch, Some(Symbol::intern(arch)))); + if sess.target.is_like_wasm { + ret.insert((sym::wasm, None)); + } ret.insert((sym::target_endian, Some(Symbol::intern(end.as_str())))); ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz)))); ret.insert((sym::target_env, Some(Symbol::intern(env)))); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index cd3dabb6795..47b5e90cf9a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1291,6 +1291,7 @@ symbols! { vreg, vreg_low16, warn, + wasm, wasm_import_module, wasm_target_feature, while_let, diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 3dd7ce93deb..c050bbc9b9d 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -198,7 +198,7 @@ fn compute_symbol_name( // // [1]: https://bugs.llvm.org/show_bug.cgi?id=44316 if is_foreign - && (tcx.sess.target.arch != "wasm32" + && (!tcx.sess.target.is_like_wasm || !tcx.wasm_import_module_map(def_id.krate).contains_key(&def_id)) { if let Some(name) = attrs.link_name { diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 2c3f7762759..395235399ea 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -20,6 +20,7 @@ mod sparc; mod sparc64; mod wasm32; mod wasm32_bindgen_compat; +mod wasm64; mod x86; mod x86_64; mod x86_win64; @@ -652,6 +653,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { _ => wasm32_bindgen_compat::compute_abi_info(self), }, "asmjs" => wasm32::compute_abi_info(cx, self), + "wasm64" => wasm64::compute_abi_info(cx, self), a => return Err(format!("unrecognized arch \"{}\" in target specification", a)), } diff --git a/compiler/rustc_target/src/abi/call/wasm64.rs b/compiler/rustc_target/src/abi/call/wasm64.rs new file mode 100644 index 00000000000..46d670d1689 --- /dev/null +++ b/compiler/rustc_target/src/abi/call/wasm64.rs @@ -0,0 +1,58 @@ +use crate::abi::call::{ArgAbi, FnAbi, Uniform}; +use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; + +fn unwrap_trivial_aggregate<'a, Ty, C>(cx: &C, val: &mut ArgAbi<'a, Ty>) -> bool +where + Ty: TyAndLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout, +{ + if val.layout.is_aggregate() { + if let Some(unit) = val.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) { + let size = val.layout.size; + if unit.size == size { + val.cast_to(Uniform { unit, total: size }); + return true; + } + } + } + false +} + +fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>) +where + Ty: TyAndLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout, +{ + ret.extend_integer_width_to(64); + if ret.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, ret) { + ret.make_indirect(); + } +} + +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +where + Ty: TyAndLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout, +{ + arg.extend_integer_width_to(64); + if arg.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, arg) { + arg.make_indirect_byval(); + } +} + +pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyAndLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout, +{ + if !fn_abi.ret.is_ignore() { + classify_ret(cx, &mut fn_abi.ret); + } + + for arg in &mut fn_abi.args { + if arg.is_ignore() { + continue; + } + classify_arg(cx, arg); + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index c9fffd213d7..23d86d6874f 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -78,7 +78,7 @@ mod solaris_base; mod thumb_base; mod uefi_msvc_base; mod vxworks_base; -mod wasm32_base; +mod wasm_base; mod windows_gnu_base; mod windows_msvc_base; mod windows_uwp_gnu_base; @@ -762,6 +762,7 @@ supported_targets! { ("wasm32-unknown-emscripten", wasm32_unknown_emscripten), ("wasm32-unknown-unknown", wasm32_unknown_unknown), ("wasm32-wasi", wasm32_wasi), + ("wasm64-unknown-unknown", wasm64_unknown_unknown), ("thumbv6m-none-eabi", thumbv6m_none_eabi), ("thumbv7m-none-eabi", thumbv7m_none_eabi), @@ -996,6 +997,8 @@ pub struct TargetOptions { pub is_like_emscripten: bool, /// Whether the target toolchain is like Fuchsia's. pub is_like_fuchsia: bool, + /// Whether a target toolchain is like WASM. + pub is_like_wasm: bool, /// Version of DWARF to use if not using the default. /// Useful because some platforms (osx, bsd) only want up to DWARF2. pub dwarf_version: Option, @@ -1204,6 +1207,7 @@ impl Default for TargetOptions { is_like_emscripten: false, is_like_msvc: false, is_like_fuchsia: false, + is_like_wasm: false, dwarf_version: None, linker_is_gnu: false, allows_weak_linkage: true, @@ -1678,6 +1682,7 @@ impl Target { key!(is_like_msvc, bool); key!(is_like_emscripten, bool); key!(is_like_fuchsia, bool); + key!(is_like_wasm, bool); key!(dwarf_version, Option); key!(linker_is_gnu, bool); key!(allows_weak_linkage, bool); @@ -1914,6 +1919,7 @@ impl ToJson for Target { target_option_val!(is_like_msvc); target_option_val!(is_like_emscripten); target_option_val!(is_like_fuchsia); + target_option_val!(is_like_wasm); target_option_val!(dwarf_version); target_option_val!(linker_is_gnu); target_option_val!(allows_weak_linkage); diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs index 9ec8467e0ac..f4de8bc0a58 100644 --- a/compiler/rustc_target/src/spec/tests/tests_impl.rs +++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs @@ -50,6 +50,7 @@ impl Target { // and you certainly want "unknown" for the OS name. fn can_use_os_unknown(&self) -> bool { self.llvm_target == "wasm32-unknown-unknown" + || self.llvm_target == "wasm64-unknown-unknown" || (self.env == "sgx" && self.vendor == "fortanix") } } diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs index 9f69ce16c21..dee06753f97 100644 --- a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs @@ -1,8 +1,8 @@ -use super::wasm32_base; +use super::wasm_base; use super::{LinkArgs, LinkerFlavor, PanicStrategy, Target, TargetOptions}; pub fn target() -> Target { - let mut options = wasm32_base::options(); + let mut options = wasm_base::options(); let clang_args = options.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs index 5e89ba2520b..597146275a8 100644 --- a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs @@ -10,11 +10,11 @@ //! This target is more or less managed by the Rust and WebAssembly Working //! Group nowadays at . -use super::wasm32_base; +use super::wasm_base; use super::{LinkerFlavor, LldFlavor, Target}; pub fn target() -> Target { - let mut options = wasm32_base::options(); + let mut options = wasm_base::options(); options.os = "unknown".to_string(); options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); let clang_args = options.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs index 3f44acdc36b..a6b12d2ee8f 100644 --- a/compiler/rustc_target/src/spec/wasm32_wasi.rs +++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs @@ -72,11 +72,11 @@ //! best we can with this target. Don't start relying on too much here unless //! you know what you're getting in to! -use super::wasm32_base; +use super::wasm_base; use super::{crt_objects, LinkerFlavor, LldFlavor, Target}; pub fn target() -> Target { - let mut options = wasm32_base::options(); + let mut options = wasm_base::options(); options.os = "wasi".to_string(); options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); diff --git a/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs new file mode 100644 index 00000000000..8bfb229d77f --- /dev/null +++ b/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs @@ -0,0 +1,39 @@ +//! A "bare wasm" target representing a WebAssembly output that makes zero +//! assumptions about its environment. +//! +//! The `wasm64-unknown-unknown` target is intended to encapsulate use cases +//! that do not rely on any imported functionality. The binaries generated are +//! entirely self-contained by default when using the standard library. Although +//! the standard library is available, most of it returns an error immediately +//! (e.g. trying to create a TCP stream or something like that). + +use super::wasm_base; +use super::{LinkerFlavor, LldFlavor, Target}; + +pub fn target() -> Target { + let mut options = wasm_base::options(); + options.os = "unknown".to_string(); + options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); + let clang_args = options.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); + + // Make sure clang uses LLD as its linker and is configured appropriately + // otherwise + clang_args.push("--target=wasm64-unknown-unknown".to_string()); + + // For now this target just never has an entry symbol no matter the output + // type, so unconditionally pass this. + clang_args.push("-Wl,--no-entry".to_string()); + options + .pre_link_args + .get_mut(&LinkerFlavor::Lld(LldFlavor::Wasm)) + .unwrap() + .push("--no-entry".to_string()); + + Target { + llvm_target: "wasm64-unknown-unknown".to_string(), + pointer_width: 64, + data_layout: "e-m:e-p:64:64-i64:64-n32:64-S128".to_string(), + arch: "wasm64".to_string(), + options, + } +} diff --git a/compiler/rustc_target/src/spec/wasm32_base.rs b/compiler/rustc_target/src/spec/wasm_base.rs similarity index 99% rename from compiler/rustc_target/src/spec/wasm32_base.rs rename to compiler/rustc_target/src/spec/wasm_base.rs index bfef3d37228..c93ad24225a 100644 --- a/compiler/rustc_target/src/spec/wasm32_base.rs +++ b/compiler/rustc_target/src/spec/wasm_base.rs @@ -60,6 +60,8 @@ pub fn options() -> TargetOptions { pre_link_args.insert(LinkerFlavor::Gcc, clang_args); TargetOptions { + is_like_wasm: true, + // we allow dynamic linking, but only cdylibs. Basically we allow a // final library artifact that exports some symbols (a wasm module) but // we don't allow intermediate `dylib` crate types diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index ee17fcac45c..f352746d3fb 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -216,6 +216,7 @@ target | std | host | notes `thumbv7a-uwp-windows-msvc` | ✓ | | `thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode ARMv7a Linux with NEON, MUSL `thumbv4t-none-eabi` | * | | ARMv4T T32 +`wasm64-unknown-unknown` | * | | WebAssembly `x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst on x86_64 `x86_64-apple-tvos` | * | | x86 64-bit tvOS `x86_64-unknown-none-linuxkernel` | * | | Linux kernel modules diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 02adccef594..e93803e2761 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -487,6 +487,7 @@ impl<'a> fmt::Display for Display<'a> { "windows" => "Windows", _ => "", }, + (sym::wasm, None) => "WebAssembly", (sym::target_arch, Some(arch)) => match &*arch.as_str() { "aarch64" => "AArch64", "arm" => "ARM", @@ -498,7 +499,7 @@ impl<'a> fmt::Display for Display<'a> { "powerpc64" => "PowerPC-64", "s390x" => "s390x", "sparc64" => "SPARC64", - "wasm32" => "WebAssembly", + "wasm32" | "wasm64" => "WebAssembly", "x86" => "x86", "x86_64" => "x86-64", _ => "", From a76de0d0a74ed6212475404bf9c6ce19ac337a6a Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Fri, 26 Mar 2021 11:25:48 -0400 Subject: [PATCH 342/370] Bump bootstrap compiler --- src/stage0.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stage0.txt b/src/stage0.txt index 4a53d1a60d1..d86f550db90 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,14 +12,14 @@ # stable release's version number. `date` is the date where the release we're # bootstrapping off was released. -date: 2021-02-14 +date: 2021-03-26 rustc: beta # We use a nightly rustfmt to format the source because it solves some # bootstrapping issues with use of new syntax in this repo. If you're looking at # the beta/stable branch, this key should be omitted, as we don't want to depend # on rustfmt from nightly there. -rustfmt: nightly-2021-01-28 +rustfmt: nightly-2021-03-25 # When making a stable release the process currently looks like: # From b577d7ef259c159c8d74333c79a0540b954ba726 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 4 Apr 2021 19:32:54 +0200 Subject: [PATCH 343/370] fix typo Co-authored-by: kennytm --- library/core/src/ptr/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index bed5e0b8998..12fd4a36bd0 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1545,7 +1545,7 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L } /// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2); /// ``` /// -/// See [`addr_of_mut`] for how to create a pointer to ininitialized data. +/// See [`addr_of_mut`] for how to create a pointer to unininitialized data. /// Doing that with `addr_of` would not make much sense since one could only /// read the data, and that would be Undefined Behavior. #[stable(feature = "raw_ref_macros", since = "1.51.0")] From ed0d8fa3e8c061fdd22fb95f6cfadbada864118d Mon Sep 17 00:00:00 2001 From: AngelicosPhosphoros Date: Sat, 3 Apr 2021 20:58:15 +0300 Subject: [PATCH 344/370] Optimize PartialOrd le Closes https://github.com/rust-lang/rust/issues/73338 This change stops default implementation of `le()` method from generating jumps. --- library/core/src/cmp.rs | 3 +- src/test/codegen/issue-73338-effecient-cmp.rs | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/test/codegen/issue-73338-effecient-cmp.rs diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 5bab1fb93db..adb033e6bdf 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -981,7 +981,8 @@ pub trait PartialOrd: PartialEq { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn le(&self, other: &Rhs) -> bool { - matches!(self.partial_cmp(other), Some(Less | Equal)) + // Pattern `Some(Less | Eq)` optimizes worse than negating `None | Some(Greater)`. + !matches!(self.partial_cmp(other), None | Some(Greater)) } /// This method tests greater than (for `self` and `other`) and is used by the `>` operator. diff --git a/src/test/codegen/issue-73338-effecient-cmp.rs b/src/test/codegen/issue-73338-effecient-cmp.rs new file mode 100644 index 00000000000..85c2bbfd040 --- /dev/null +++ b/src/test/codegen/issue-73338-effecient-cmp.rs @@ -0,0 +1,39 @@ +// This test checks that comparison operation +// generated by #[derive(PartialOrd)] +// doesn't contain jumps for C enums + +// compile-flags: -Copt-level=3 + +#![crate_type="lib"] + +#[repr(u32)] +#[derive(Copy, Clone, Eq, PartialEq, PartialOrd)] +pub enum Foo { + Zero, + One, + Two, +} + +#[no_mangle] +pub fn compare_less(a: Foo, b: Foo)->bool{ + // CHECK-NOT: br {{.*}} + a < b +} + +#[no_mangle] +pub fn compare_le(a: Foo, b: Foo)->bool{ + // CHECK-NOT: br {{.*}} + a <= b +} + +#[no_mangle] +pub fn compare_ge(a: Foo, b: Foo)->bool{ + // CHECK-NOT: br {{.*}} + a >= b +} + +#[no_mangle] +pub fn compare_greater(a: Foo, b: Foo)->bool{ + // CHECK-NOT: br {{.*}} + a > b +} From 37498a19dedb4105f8800a7cc2473803fd4bbccf Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 4 Apr 2021 11:55:13 -0700 Subject: [PATCH 345/370] Use `#[inline(always)]` on trivial UnsafeCell methods UnsafeCell is the standard building block for shared mutable data structures. UnsafeCell should add zero overhead compared to using raw pointers directly. Some reports suggest that debug builds, or even builds at opt-level 1, may not always be inlining its methods. Mark the methods as `#[inline(always)]`, since once inlined the methods should result in no actual code other than field accesses. --- library/core/src/cell.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 9a2908c275d..4820588df25 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1815,7 +1815,7 @@ impl UnsafeCell { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_unsafe_cell_new", since = "1.32.0")] - #[inline] + #[inline(always)] pub const fn new(value: T) -> UnsafeCell { UnsafeCell { value } } @@ -1831,7 +1831,7 @@ impl UnsafeCell { /// /// let five = uc.into_inner(); /// ``` - #[inline] + #[inline(always)] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] pub const fn into_inner(self) -> T { @@ -1856,7 +1856,7 @@ impl UnsafeCell { /// /// let five = uc.get(); /// ``` - #[inline] + #[inline(always)] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_unsafecell_get", since = "1.32.0")] pub const fn get(&self) -> *mut T { @@ -1881,7 +1881,7 @@ impl UnsafeCell { /// /// assert_eq!(*c.get_mut(), 6); /// ``` - #[inline] + #[inline(always)] #[stable(feature = "unsafe_cell_get_mut", since = "1.50.0")] pub fn get_mut(&mut self) -> &mut T { &mut self.value @@ -1914,7 +1914,7 @@ impl UnsafeCell { /// /// assert_eq!(uc.into_inner(), 5); /// ``` - #[inline] + #[inline(always)] #[unstable(feature = "unsafe_cell_raw_get", issue = "66358")] pub const fn raw_get(this: *const Self) -> *mut T { // We can just cast the pointer from `UnsafeCell` to `T` because of From b3a4f91b8d16f65e3220f14fc7867fed0cc7d1e7 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Fri, 26 Mar 2021 16:10:21 -0400 Subject: [PATCH 346/370] Bump cfgs --- compiler/rustc_error_codes/src/lib.rs | 3 +- library/alloc/src/lib.rs | 4 +-- library/core/src/hash/mod.rs | 52 ++++----------------------- library/core/src/lib.rs | 6 ++-- library/core/src/macros/mod.rs | 2 -- library/core/src/ops/deref.rs | 2 +- library/core/src/prelude/v1.rs | 2 -- library/core/src/ptr/const_ptr.rs | 8 ----- library/core/src/ptr/mod.rs | 45 ----------------------- library/core/src/ptr/mut_ptr.rs | 8 ----- library/core/src/ptr/non_null.rs | 2 -- library/core/src/slice/mod.rs | 26 +++++--------- library/core/tests/lib.rs | 5 ++- library/core/tests/ptr.rs | 7 ---- library/std/src/lib.rs | 3 +- library/std/src/prelude/v1.rs | 2 -- src/bootstrap/builder.rs | 14 ++------ src/tools/linkchecker/main.rs | 2 -- src/tools/tidy/src/lib.rs | 2 -- 19 files changed, 24 insertions(+), 171 deletions(-) diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index 14ddb3e2079..f2432f61653 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -1,5 +1,4 @@ -#![cfg_attr(bootstrap, deny(invalid_codeblock_attributes))] -#![cfg_attr(not(bootstrap), deny(rustdoc::invalid_codeblock_attributes))] +#![deny(rustdoc::invalid_codeblock_attributes)] //! This library is used to gather all error codes into one place, //! the goal being to make their maintenance easier. diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index fb243100990..14cb1d3b405 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -133,7 +133,6 @@ #![feature(trusted_len)] #![feature(unboxed_closures)] #![feature(unicode_internals)] -#![cfg_attr(bootstrap, feature(unsafe_block_in_unsafe_fn))] #![feature(unsize)] #![feature(unsized_fn_params)] #![feature(allocator_internals)] @@ -142,8 +141,7 @@ #![feature(alloc_layout_extra)] #![feature(trusted_random_access)] #![feature(try_trait)] -#![cfg_attr(bootstrap, feature(type_alias_impl_trait))] -#![cfg_attr(not(bootstrap), feature(min_type_alias_impl_trait))] +#![feature(min_type_alias_impl_trait)] #![feature(associated_type_bounds)] #![feature(slice_group_by)] #![feature(decl_macro)] diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index 7bfa58d34ed..0c3303cc210 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -691,29 +691,9 @@ mod impls { impl Hash for *const T { #[inline] fn hash(&self, state: &mut H) { - #[cfg(not(bootstrap))] - { - let (address, metadata) = self.to_raw_parts(); - state.write_usize(address as usize); - metadata.hash(state); - } - #[cfg(bootstrap)] - { - if mem::size_of::() == mem::size_of::() { - // Thin pointer - state.write_usize(*self as *const () as usize); - } else { - // Fat pointer - // SAFETY: we are accessing the memory occupied by `self` - // which is guaranteed to be valid. - // This assumes a fat pointer can be represented by a `(usize, usize)`, - // which is safe to do in `std` because it is shipped and kept in sync - // with the implementation of fat pointers in `rustc`. - let (a, b) = unsafe { *(self as *const Self as *const (usize, usize)) }; - state.write_usize(a); - state.write_usize(b); - } - } + let (address, metadata) = self.to_raw_parts(); + state.write_usize(address as usize); + metadata.hash(state); } } @@ -721,29 +701,9 @@ mod impls { impl Hash for *mut T { #[inline] fn hash(&self, state: &mut H) { - #[cfg(not(bootstrap))] - { - let (address, metadata) = self.to_raw_parts(); - state.write_usize(address as usize); - metadata.hash(state); - } - #[cfg(bootstrap)] - { - if mem::size_of::() == mem::size_of::() { - // Thin pointer - state.write_usize(*self as *const () as usize); - } else { - // Fat pointer - // SAFETY: we are accessing the memory occupied by `self` - // which is guaranteed to be valid. - // This assumes a fat pointer can be represented by a `(usize, usize)`, - // which is safe to do in `std` because it is shipped and kept in sync - // with the implementation of fat pointers in `rustc`. - let (a, b) = unsafe { *(self as *const Self as *const (usize, usize)) }; - state.write_usize(a); - state.write_usize(b); - } - } + let (address, metadata) = self.to_raw_parts(); + state.write_usize(address as usize); + metadata.hash(state); } } } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 158b1e152ad..013e98a8660 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -129,7 +129,7 @@ #![feature(auto_traits)] #![cfg_attr(bootstrap, feature(or_patterns))] #![feature(prelude_import)] -#![cfg_attr(not(bootstrap), feature(ptr_metadata))] +#![feature(ptr_metadata)] #![feature(repr_simd, platform_intrinsics)] #![feature(rustc_attrs)] #![feature(simd_ffi)] @@ -167,7 +167,6 @@ #![feature(slice_ptr_get)] #![feature(no_niche)] // rust-lang/rust#68303 #![feature(int_error_matching)] -#![cfg_attr(bootstrap, feature(unsafe_block_in_unsafe_fn))] #![deny(unsafe_op_in_unsafe_fn)] #[prelude_import] @@ -299,8 +298,7 @@ pub mod primitive; unused_imports, unsafe_op_in_unsafe_fn )] -#[cfg_attr(bootstrap, allow(non_autolinks))] -#[cfg_attr(not(bootstrap), allow(rustdoc::non_autolinks))] +#[allow(rustdoc::non_autolinks)] // FIXME: This annotation should be moved into rust-lang/stdarch after clashing_extern_declarations is // merged. It currently cannot because bootstrap fails as the lint hasn't been defined yet. #[allow(clashing_extern_declarations)] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 99894b5605e..5d9b0f80d3a 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1391,7 +1391,6 @@ pub(crate) mod builtin { } /// Attribute macro used to apply derive macros. - #[cfg(not(bootstrap))] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_builtin_macro] pub macro derive($item:item) { @@ -1453,7 +1452,6 @@ pub(crate) mod builtin { } /// Expands all `#[cfg]` and `#[cfg_attr]` attributes in the code fragment it's applied to. - #[cfg(not(bootstrap))] #[unstable( feature = "cfg_eval", issue = "82679", diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index 10e3ce67448..dcf3ce070ec 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -65,7 +65,7 @@ pub trait Deref { /// The resulting type after dereferencing. #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "deref_target"] - #[cfg_attr(not(bootstrap), lang = "deref_target")] + #[lang = "deref_target"] type Target: ?Sized; /// Dereferences the value. diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index 7d33ca8bb69..c89fe57cb05 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -67,7 +67,6 @@ pub use crate::macros::builtin::{ bench, global_allocator, test, test_case, RustcDecodable, RustcEncodable, }; -#[cfg(not(bootstrap))] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[doc(no_inline)] pub use crate::macros::builtin::derive; @@ -80,7 +79,6 @@ pub use crate::macros::builtin::derive; #[doc(no_inline)] pub use crate::macros::builtin::cfg_accessible; -#[cfg(not(bootstrap))] #[unstable( feature = "cfg_eval", issue = "82679", diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 25b8f435acc..f18387d020d 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -51,7 +51,6 @@ impl *const T { /// Decompose a (possibly wide) pointer into is address and metadata components. /// /// The pointer can be later reconstructed with [`from_raw_parts`]. - #[cfg(not(bootstrap))] #[unstable(feature = "ptr_metadata", issue = "81513")] #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")] #[inline] @@ -915,13 +914,6 @@ impl *const [T] { #[unstable(feature = "slice_ptr_len", issue = "71146")] #[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")] pub const fn len(self) -> usize { - #[cfg(bootstrap)] - { - // SAFETY: this is safe because `*const [T]` and `FatPtr` have the same layout. - // Only `std` can make this guarantee. - unsafe { Repr { rust: self }.raw }.len - } - #[cfg(not(bootstrap))] metadata(self) } diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 6412bd41a8c..52660116026 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -90,11 +90,8 @@ pub use crate::intrinsics::copy; #[doc(inline)] pub use crate::intrinsics::write_bytes; -#[cfg(not(bootstrap))] mod metadata; -#[cfg(not(bootstrap))] pub(crate) use metadata::PtrRepr; -#[cfg(not(bootstrap))] #[unstable(feature = "ptr_metadata", issue = "81513")] pub use metadata::{from_raw_parts, from_raw_parts_mut, metadata, DynMetadata, Pointee, Thin}; @@ -236,33 +233,6 @@ pub const fn null_mut() -> *mut T { 0 as *mut T } -#[cfg(bootstrap)] -#[repr(C)] -pub(crate) union Repr { - pub(crate) rust: *const [T], - rust_mut: *mut [T], - pub(crate) raw: FatPtr, -} - -#[cfg(bootstrap)] -#[repr(C)] -pub(crate) struct FatPtr { - data: *const T, - pub(crate) len: usize, -} - -#[cfg(bootstrap)] -// Manual impl needed to avoid `T: Clone` bound. -impl Clone for FatPtr { - fn clone(&self) -> Self { - *self - } -} - -#[cfg(bootstrap)] -// Manual impl needed to avoid `T: Copy` bound. -impl Copy for FatPtr {} - /// Forms a raw slice from a pointer and a length. /// /// The `len` argument is the number of **elements**, not the number of bytes. @@ -287,14 +257,6 @@ impl Copy for FatPtr {} #[stable(feature = "slice_from_raw_parts", since = "1.42.0")] #[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] pub const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { - #[cfg(bootstrap)] - { - // SAFETY: Accessing the value from the `Repr` union is safe since *const [T] - // and FatPtr have the same memory layouts. Only std can make this - // guarantee. - unsafe { Repr { raw: FatPtr { data, len } }.rust } - } - #[cfg(not(bootstrap))] from_raw_parts(data.cast(), len) } @@ -327,13 +289,6 @@ pub const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { #[stable(feature = "slice_from_raw_parts", since = "1.42.0")] #[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] pub const fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { - #[cfg(bootstrap)] - { - // SAFETY: Accessing the value from the `Repr` union is safe since *mut [T] - // and FatPtr have the same memory layouts - unsafe { Repr { raw: FatPtr { data, len } }.rust_mut } - } - #[cfg(not(bootstrap))] from_raw_parts_mut(data.cast(), len) } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 732e1273b4b..3c6f1978283 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -50,7 +50,6 @@ impl *mut T { /// Decompose a (possibly wide) pointer into is address and metadata components. /// /// The pointer can be later reconstructed with [`from_raw_parts_mut`]. - #[cfg(not(bootstrap))] #[unstable(feature = "ptr_metadata", issue = "81513")] #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")] #[inline] @@ -1175,13 +1174,6 @@ impl *mut [T] { #[unstable(feature = "slice_ptr_len", issue = "71146")] #[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")] pub const fn len(self) -> usize { - #[cfg(bootstrap)] - { - // SAFETY: this is safe because `*const [T]` and `FatPtr` have the same layout. - // Only `std` can make this guarantee. - unsafe { Repr { rust_mut: self }.raw }.len - } - #[cfg(not(bootstrap))] metadata(self) } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 83b88ffd916..e525f616043 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -181,7 +181,6 @@ impl NonNull { /// See the documentation of [`std::ptr::from_raw_parts`] for more details. /// /// [`std::ptr::from_raw_parts`]: crate::ptr::from_raw_parts - #[cfg(not(bootstrap))] #[unstable(feature = "ptr_metadata", issue = "81513")] #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")] #[inline] @@ -198,7 +197,6 @@ impl NonNull { /// Decompose a (possibly wide) pointer into is address and metadata components. /// /// The pointer can be later reconstructed with [`NonNull::from_raw_parts`]. - #[cfg(not(bootstrap))] #[unstable(feature = "ptr_metadata", issue = "81513")] #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")] #[inline] diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index e4b1bffcfe0..ec28cdd1ba0 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -102,23 +102,14 @@ impl [T] { // SAFETY: const sound because we transmute out the length field as a usize (which it must be) #[rustc_allow_const_fn_unstable(const_fn_union)] pub const fn len(&self) -> usize { - #[cfg(bootstrap)] - { - // SAFETY: this is safe because `&[T]` and `FatPtr` have the same layout. - // Only `std` can make this guarantee. - unsafe { crate::ptr::Repr { rust: self }.raw.len } - } - #[cfg(not(bootstrap))] - { - // FIXME: Replace with `crate::ptr::metadata(self)` when that is const-stable. - // As of this writing this causes a "Const-stable functions can only call other - // const-stable functions" error. + // FIXME: Replace with `crate::ptr::metadata(self)` when that is const-stable. + // As of this writing this causes a "Const-stable functions can only call other + // const-stable functions" error. - // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T - // and PtrComponents have the same memory layouts. Only std can make this - // guarantee. - unsafe { crate::ptr::PtrRepr { const_ptr: self }.components.metadata } - } + // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T + // and PtrComponents have the same memory layouts. Only std can make this + // guarantee. + unsafe { crate::ptr::PtrRepr { const_ptr: self }.components.metadata } } /// Returns `true` if the slice has a length of 0. @@ -2265,8 +2256,7 @@ impl [T] { // in crate `alloc`, and as such doesn't exists yet when building `core`. // links to downstream crate: #74481. Since primitives are only documented in // libstd (#73423), this never leads to broken links in practice. - #[cfg_attr(not(bootstrap), allow(rustdoc::broken_intra_doc_links))] - #[cfg_attr(bootstrap, allow(broken_intra_doc_links))] + #[allow(rustdoc::broken_intra_doc_links)] #[stable(feature = "slice_binary_search_by_key", since = "1.10.0")] #[inline] pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 997e618cc51..1d885eb1092 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -68,7 +68,7 @@ #![feature(option_result_unwrap_unchecked)] #![feature(result_into_ok_or_err)] #![feature(peekable_peek_mut)] -#![cfg_attr(not(bootstrap), feature(ptr_metadata))] +#![feature(ptr_metadata)] #![feature(once_cell)] #![feature(unsized_tuple_coercion)] #![feature(nonzero_leading_trailing_zeros)] @@ -76,8 +76,7 @@ #![feature(integer_atomics)] #![feature(slice_group_by)] #![feature(trusted_random_access)] -#![cfg_attr(bootstrap, feature(unsafe_block_in_unsafe_fn))] -#![cfg_attr(not(bootstrap), feature(unsize))] +#![feature(unsize)] #![deny(unsafe_op_in_unsafe_fn)] extern crate test; diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs index 224a58e3ccd..11af8090c3a 100644 --- a/library/core/tests/ptr.rs +++ b/library/core/tests/ptr.rs @@ -1,8 +1,6 @@ use core::cell::RefCell; -#[cfg(not(bootstrap))] use core::ptr; use core::ptr::*; -#[cfg(not(bootstrap))] use std::fmt::{Debug, Display}; #[test] @@ -419,7 +417,6 @@ fn offset_from() { } #[test] -#[cfg(not(bootstrap))] fn ptr_metadata() { struct Unit; struct Pair(A, B); @@ -478,7 +475,6 @@ fn ptr_metadata() { } #[test] -#[cfg(not(bootstrap))] fn ptr_metadata_bounds() { fn metadata_eq_method_address() -> usize { // The `Metadata` associated type has an `Ord` bound, so this is valid: @@ -510,7 +506,6 @@ fn ptr_metadata_bounds() { } #[test] -#[cfg(not(bootstrap))] fn dyn_metadata() { #[derive(Debug)] #[repr(align(32))] @@ -530,7 +525,6 @@ fn dyn_metadata() { } #[test] -#[cfg(not(bootstrap))] fn from_raw_parts() { let mut value = 5_u32; let address = &mut value as *mut _ as *mut (); @@ -557,7 +551,6 @@ fn from_raw_parts() { } #[test] -#[cfg(not(bootstrap))] fn thin_box() { let foo = ThinBox::::new(4); assert_eq!(foo.to_string(), "4"); diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 6ab68100b1d..c983022746c 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -234,7 +234,7 @@ #![feature(box_syntax)] #![feature(c_variadic)] #![feature(cfg_accessible)] -#![cfg_attr(not(bootstrap), feature(cfg_eval))] +#![feature(cfg_eval)] #![feature(cfg_target_has_atomic)] #![feature(cfg_target_thread_local)] #![feature(char_error_internals)] @@ -331,7 +331,6 @@ #![feature(try_blocks)] #![feature(try_reserve)] #![feature(unboxed_closures)] -#![cfg_attr(bootstrap, feature(unsafe_block_in_unsafe_fn))] #![feature(unsafe_cell_raw_get)] #![feature(unwind_attributes)] #![feature(vec_into_raw_parts)] diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index c5b871edbf2..4a3c3ba1635 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -54,7 +54,6 @@ pub use core::prelude::v1::{ bench, global_allocator, test, test_case, RustcDecodable, RustcEncodable, }; -#[cfg(not(bootstrap))] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[doc(hidden)] pub use core::prelude::v1::derive; @@ -67,7 +66,6 @@ pub use core::prelude::v1::derive; #[doc(hidden)] pub use core::prelude::v1::cfg_accessible; -#[cfg(not(bootstrap))] #[unstable( feature = "cfg_eval", issue = "82679", diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 86f59495504..38901a35296 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -741,12 +741,7 @@ impl<'a> Builder<'a> { .env("RUSTDOC_REAL", self.rustdoc(compiler)) .env("RUSTC_BOOTSTRAP", "1"); - // cfg(bootstrap), can be removed on the next beta bump - if compiler.stage == 0 { - cmd.arg("-Winvalid_codeblock_attributes"); - } else { - cmd.arg("-Wrustdoc::invalid_codeblock_attributes"); - } + cmd.arg("-Wrustdoc::invalid_codeblock_attributes"); if self.config.deny_warnings { cmd.arg("-Dwarnings"); @@ -1303,12 +1298,7 @@ impl<'a> Builder<'a> { // fixed via better support from Cargo. cargo.env("RUSTC_LINT_FLAGS", lint_flags.join(" ")); - // cfg(bootstrap), can be removed on the next beta bump - if compiler.stage == 0 { - rustdocflags.arg("-Winvalid_codeblock_attributes"); - } else { - rustdocflags.arg("-Wrustdoc::invalid_codeblock_attributes"); - } + rustdocflags.arg("-Wrustdoc::invalid_codeblock_attributes"); } if mode == Mode::Rustc { diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index f6875e0036f..c677d04917e 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -14,8 +14,6 @@ //! A few exceptions are allowed as there's known bugs in rustdoc, but this //! should catch the majority of "broken link" cases. -#![cfg_attr(bootstrap, feature(str_split_once))] - use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; use std::env; diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 11d36751f67..cbcc01dc39a 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -3,8 +3,6 @@ //! This library contains the tidy lints and exposes it //! to be used by tools. -#![cfg_attr(bootstrap, feature(str_split_once))] - use std::fs::File; use std::io::Read; use walkdir::{DirEntry, WalkDir}; From f06efd2a24761b3f2b73d9888a8f945de5ec26e4 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 4 Apr 2021 14:51:22 -0400 Subject: [PATCH 347/370] Workaround increased cache clearing in Cargo 1.52 Cargo adds rust-lang/cargo#8640 which means that cargo will try to purge the doc directory caches for us. In theory this may mean that we can jettison the clear_if_dirty for rustdoc versioning entirely, but for now just workaround the effects of this change in a less principled but more local way. --- src/bootstrap/doc.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 1168d54b55e..fc79fc10fb4 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -461,7 +461,16 @@ impl Step for Std { // create correct links between crates because rustdoc depends on the // existence of the output directories to know if it should be a local // or remote link. - let krates = ["core", "alloc", "std", "proc_macro", "test"]; + // + // There's also a mild hack here where we build the first crate in this + // list, core, twice. This is currently necessary to make sure that + // cargo's cached rustc/rustdoc versions are up to date which means + // cargo won't delete the out_dir we create for the stampfile. + // Essentially any crate could go into the first slot here as it's + // output directory will be deleted by us (as cargo will purge the stamp + // file during the first slot's run), and core is relatively fast to + // build so works OK to fill this 'dummy' slot. + let krates = ["core", "core", "alloc", "std", "proc_macro", "test"]; for krate in &krates { run_cargo_rustdoc_for(krate); } From 3c3d3ddde967f66938966d6d557a3a4fe4d267ff Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 11 Mar 2021 14:39:37 +0200 Subject: [PATCH 348/370] core: rearrange `ptr::swap_nonoverlapping_one`'s cases (no functional changes). --- library/core/src/ptr/mod.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 6412bd41a8c..15aa4769697 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -473,19 +473,21 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { #[inline] #[rustc_const_unstable(feature = "const_swap", issue = "83163")] pub(crate) const unsafe fn swap_nonoverlapping_one(x: *mut T, y: *mut T) { - // For types smaller than the block optimization below, - // just swap directly to avoid pessimizing codegen. - if mem::size_of::() < 32 { - // SAFETY: the caller must guarantee that `x` and `y` are valid - // for writes, properly aligned, and non-overlapping. - unsafe { - let z = read(x); - copy_nonoverlapping(y, x, 1); - write(y, z); - } - } else { + // Only apply the block optimization in `swap_nonoverlapping_bytes` for types + // at least as large as the block size, to avoid pessimizing codegen. + if mem::size_of::() >= 32 { // SAFETY: the caller must uphold the safety contract for `swap_nonoverlapping`. unsafe { swap_nonoverlapping(x, y, 1) }; + return; + } + + // Direct swapping, for the cases not going through the block optimization. + // SAFETY: the caller must guarantee that `x` and `y` are valid + // for writes, properly aligned, and non-overlapping. + unsafe { + let z = read(x); + copy_nonoverlapping(y, x, 1); + write(y, z); } } From bc6af97ed0088304a2430b74b47c182c65ce0b9f Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 11 Mar 2021 16:33:34 +0200 Subject: [PATCH 349/370] core: disable `ptr::swap_nonoverlapping_one`'s block optimization on SPIR-V. --- library/core/src/ptr/mod.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 15aa4769697..f673a6fd178 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -473,12 +473,23 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { #[inline] #[rustc_const_unstable(feature = "const_swap", issue = "83163")] pub(crate) const unsafe fn swap_nonoverlapping_one(x: *mut T, y: *mut T) { - // Only apply the block optimization in `swap_nonoverlapping_bytes` for types - // at least as large as the block size, to avoid pessimizing codegen. - if mem::size_of::() >= 32 { - // SAFETY: the caller must uphold the safety contract for `swap_nonoverlapping`. - unsafe { swap_nonoverlapping(x, y, 1) }; - return; + // NOTE(eddyb) SPIR-V's Logical addressing model doesn't allow for arbitrary + // reinterpretation of values as (chunkable) byte arrays, and the loop in the + // block optimization in `swap_nonoverlapping_bytes` is hard to rewrite back + // into the (unoptimized) direct swapping implementation, so we disable it. + // FIXME(eddyb) the block optimization also prevents MIR optimizations from + // understanding `mem::replace`, `Option::take`, etc. - a better overall + // solution might be to make `swap_nonoverlapping` into an intrinsic, which + // a backend can choose to implement using the block optimization, or not. + #[cfg(not(target_arch = "spirv"))] + { + // Only apply the block optimization in `swap_nonoverlapping_bytes` for types + // at least as large as the block size, to avoid pessimizing codegen. + if mem::size_of::() >= 32 { + // SAFETY: the caller must uphold the safety contract for `swap_nonoverlapping`. + unsafe { swap_nonoverlapping(x, y, 1) }; + return; + } } // Direct swapping, for the cases not going through the block optimization. From 14406df189150a1a79298dd82007c6fd6186fafc Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 10 Feb 2021 00:33:17 -0500 Subject: [PATCH 350/370] Use the beta compiler for building bootstrap tools when `download-rustc` is set ## Motivation This avoids having to rebuild bootstrap and tidy each time you rebase over master. In particular, it makes rebasing and running `x.py fmt` on each commit in a branch significantly faster. It also avoids having to rebuild bootstrap after setting `download-rustc = true`. ## Implementation Instead of extracting the CI artifacts directly to `stage0/`, extract them to `ci-rustc/` instead. Continue to copy them to the proper sysroots as necessary for all stages except stage 0. This also requires `bootstrap.py` to download both stage0 and CI artifacts and distinguish between the two when checking stamp files. Note that since tools have to be built by the same compiler that built `rustc-dev` and the standard library, the downloaded artifacts can't be reused when building with the beta compiler. To make sure this is still a good user experience, warn when building with the beta compiler, and default to building with stage 2. --- src/bootstrap/bootstrap.py | 149 ++++++++++++++++++++----------------- src/bootstrap/compile.rs | 15 ++-- src/bootstrap/config.rs | 98 +++++++++++++----------- src/bootstrap/tool.rs | 13 ++++ 4 files changed, 158 insertions(+), 117 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 3e7d1d54f12..1f57d85866f 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -383,7 +383,7 @@ class RustBuild(object): self.nix_deps_dir = None self.rustc_commit = None - def download_stage0(self): + def download_toolchain(self, stage0=True, rustc_channel=None): """Fetch the build system for Rust, written in Rust This method will build a cache directory, then it will fetch the @@ -393,43 +393,47 @@ class RustBuild(object): Each downloaded tarball is extracted, after that, the script will move all the content to the right place. """ - rustc_channel = self.rustc_channel + if rustc_channel is None: + rustc_channel = self.rustc_channel rustfmt_channel = self.rustfmt_channel + bin_root = self.bin_root(stage0) - if self.rustc().startswith(self.bin_root()) and \ - (not os.path.exists(self.rustc()) or - self.program_out_of_date(self.rustc_stamp(), self.date + str(self.rustc_commit))): - if os.path.exists(self.bin_root()): - shutil.rmtree(self.bin_root()) - download_rustc = self.rustc_commit is not None + key = self.date + if not stage0: + key += str(self.rustc_commit) + if self.rustc(stage0).startswith(bin_root) and \ + (not os.path.exists(self.rustc(stage0)) or + self.program_out_of_date(self.rustc_stamp(stage0), key)): + if os.path.exists(bin_root): + shutil.rmtree(bin_root) tarball_suffix = '.tar.xz' if support_xz() else '.tar.gz' filename = "rust-std-{}-{}{}".format( rustc_channel, self.build, tarball_suffix) pattern = "rust-std-{}".format(self.build) - self._download_component_helper(filename, pattern, tarball_suffix, download_rustc) + self._download_component_helper(filename, pattern, tarball_suffix, stage0) filename = "rustc-{}-{}{}".format(rustc_channel, self.build, tarball_suffix) - self._download_component_helper(filename, "rustc", tarball_suffix, download_rustc) + self._download_component_helper(filename, "rustc", tarball_suffix, stage0) filename = "cargo-{}-{}{}".format(rustc_channel, self.build, tarball_suffix) self._download_component_helper(filename, "cargo", tarball_suffix) - if self.rustc_commit is not None: + if not stage0: filename = "rustc-dev-{}-{}{}".format(rustc_channel, self.build, tarball_suffix) self._download_component_helper( - filename, "rustc-dev", tarball_suffix, download_rustc + filename, "rustc-dev", tarball_suffix, stage0 ) - self.fix_bin_or_dylib("{}/bin/rustc".format(self.bin_root())) - self.fix_bin_or_dylib("{}/bin/rustdoc".format(self.bin_root())) - self.fix_bin_or_dylib("{}/bin/cargo".format(self.bin_root())) - lib_dir = "{}/lib".format(self.bin_root()) + self.fix_bin_or_dylib("{}/bin/rustc".format(bin_root)) + self.fix_bin_or_dylib("{}/bin/rustdoc".format(bin_root)) + self.fix_bin_or_dylib("{}/bin/cargo".format(bin_root)) + lib_dir = "{}/lib".format(bin_root) for lib in os.listdir(lib_dir): if lib.endswith(".so"): self.fix_bin_or_dylib(os.path.join(lib_dir, lib), rpath_libz=True) - with output(self.rustc_stamp()) as rust_stamp: - rust_stamp.write(self.date + str(self.rustc_commit)) + with output(self.rustc_stamp(stage0)) as rust_stamp: + rust_stamp.write(key) - if self.rustfmt() and self.rustfmt().startswith(self.bin_root()) and ( + if self.rustfmt() and self.rustfmt().startswith(bin_root) and ( not os.path.exists(self.rustfmt()) or self.program_out_of_date(self.rustfmt_stamp(), self.rustfmt_channel) ): @@ -440,12 +444,13 @@ class RustBuild(object): self._download_component_helper( filename, "rustfmt-preview", tarball_suffix, key=date ) - self.fix_bin_or_dylib("{}/bin/rustfmt".format(self.bin_root())) - self.fix_bin_or_dylib("{}/bin/cargo-fmt".format(self.bin_root())) + self.fix_bin_or_dylib("{}/bin/rustfmt".format(bin_root)) + self.fix_bin_or_dylib("{}/bin/cargo-fmt".format(bin_root)) with output(self.rustfmt_stamp()) as rustfmt_stamp: rustfmt_stamp.write(self.rustfmt_channel) - if self.downloading_llvm(): + # Avoid downloading LLVM twice (once for stage0 and once for the master rustc) + if self.downloading_llvm() and stage0: # We want the most recent LLVM submodule update to avoid downloading # LLVM more often than necessary. # @@ -496,27 +501,26 @@ class RustBuild(object): or (opt == "if-available" and self.build in supported_platforms) def _download_component_helper( - self, filename, pattern, tarball_suffix, download_rustc=False, key=None + self, filename, pattern, tarball_suffix, stage0=True, key=None ): if key is None: - if download_rustc: - key = self.rustc_commit - else: + if stage0: key = self.date + else: + key = self.rustc_commit cache_dst = os.path.join(self.build_dir, "cache") rustc_cache = os.path.join(cache_dst, key) if not os.path.exists(rustc_cache): os.makedirs(rustc_cache) - if download_rustc: - url = "https://ci-artifacts.rust-lang.org/rustc-builds/{}".format(self.rustc_commit) - else: + if stage0: url = "{}/dist/{}".format(self._download_url, key) + else: + url = "https://ci-artifacts.rust-lang.org/rustc-builds/{}".format(self.rustc_commit) tarball = os.path.join(rustc_cache, filename) if not os.path.exists(tarball): - do_verify = not download_rustc - get("{}/{}".format(url, filename), tarball, verbose=self.verbose, do_verify=do_verify) - unpack(tarball, tarball_suffix, self.bin_root(), match=pattern, verbose=self.verbose) + get("{}/{}".format(url, filename), tarball, verbose=self.verbose, do_verify=stage0) + unpack(tarball, tarball_suffix, self.bin_root(stage0), match=pattern, verbose=self.verbose) def _download_ci_llvm(self, llvm_sha, llvm_assertions): cache_prefix = "llvm-{}-{}".format(llvm_sha, llvm_assertions) @@ -574,10 +578,10 @@ class RustBuild(object): nix_os_msg = "info: you seem to be running NixOS. Attempting to patch" print(nix_os_msg, fname) - # Only build `stage0/.nix-deps` once. + # Only build `.nix-deps` once. nix_deps_dir = self.nix_deps_dir if not nix_deps_dir: - nix_deps_dir = "{}/.nix-deps".format(self.bin_root()) + nix_deps_dir = ".nix-deps" if not os.path.exists(nix_deps_dir): os.makedirs(nix_deps_dir) @@ -635,8 +639,8 @@ class RustBuild(object): print("warning: failed to call patchelf:", reason) return - # Return the stage1 compiler to download, if any. - def maybe_download_rustc(self): + # If `download-rustc` is set, download the most recent commit with CI artifacts + def maybe_download_ci_toolchain(self): # If `download-rustc` is not set, default to rebuilding. if self.get_toml("download-rustc", section="rust") != "true": return None @@ -656,17 +660,23 @@ class RustBuild(object): if status != 0: print("warning: `download-rustc` is enabled, but there are changes to compiler/") - return commit + if self.verbose: + print("using downloaded stage1 artifacts from CI (commit {})".format(commit)) + self.rustc_commit = commit + # FIXME: support downloading artifacts from the beta channel + self.download_toolchain(False, "nightly") - def rustc_stamp(self): - """Return the path for .rustc-stamp + def rustc_stamp(self, stage0): + """Return the path for .rustc-stamp at the given stage >>> rb = RustBuild() >>> rb.build_dir = "build" - >>> rb.rustc_stamp() == os.path.join("build", "stage0", ".rustc-stamp") + >>> rb.rustc_stamp(True) == os.path.join("build", "stage0", ".rustc-stamp") + True + >>> rb.rustc_stamp(False) == os.path.join("build", "ci-rustc", ".rustc-stamp") True """ - return os.path.join(self.bin_root(), '.rustc-stamp') + return os.path.join(self.bin_root(stage0), '.rustc-stamp') def rustfmt_stamp(self): """Return the path for .rustfmt-stamp @@ -676,7 +686,7 @@ class RustBuild(object): >>> rb.rustfmt_stamp() == os.path.join("build", "stage0", ".rustfmt-stamp") True """ - return os.path.join(self.bin_root(), '.rustfmt-stamp') + return os.path.join(self.bin_root(True), '.rustfmt-stamp') def llvm_stamp(self): """Return the path for .rustfmt-stamp @@ -696,21 +706,27 @@ class RustBuild(object): with open(stamp_path, 'r') as stamp: return key != stamp.read() - def bin_root(self): - """Return the binary root directory + def bin_root(self, stage0): + """Return the binary root directory for the given stage >>> rb = RustBuild() >>> rb.build_dir = "build" - >>> rb.bin_root() == os.path.join("build", "stage0") + >>> rb.bin_root(True) == os.path.join("build", "stage0") + True + >>> rb.bin_root(False) == os.path.join("build", "ci-rustc") True When the 'build' property is given should be a nested directory: >>> rb.build = "devel" - >>> rb.bin_root() == os.path.join("build", "devel", "stage0") + >>> rb.bin_root(True) == os.path.join("build", "devel", "stage0") True """ - return os.path.join(self.build_dir, self.build, "stage0") + if stage0: + subdir = "stage0" + else: + subdir = "ci-rustc" + return os.path.join(self.build_dir, self.build, subdir) def llvm_root(self): """Return the CI LLVM root directory @@ -773,9 +789,9 @@ class RustBuild(object): """Return config path for cargo""" return self.program_config('cargo') - def rustc(self): + def rustc(self, stage0): """Return config path for rustc""" - return self.program_config('rustc') + return self.program_config('rustc', stage0) def rustfmt(self): """Return config path for rustfmt""" @@ -783,23 +799,27 @@ class RustBuild(object): return None return self.program_config('rustfmt') - def program_config(self, program): - """Return config path for the given program + def program_config(self, program, stage0=True): + """Return config path for the given program at the given stage >>> rb = RustBuild() >>> rb.config_toml = 'rustc = "rustc"\\n' >>> rb.program_config('rustc') 'rustc' >>> rb.config_toml = '' - >>> cargo_path = rb.program_config('cargo') - >>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(), + >>> cargo_path = rb.program_config('cargo', True) + >>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(True), + ... "bin", "cargo") + True + >>> cargo_path = rb.program_config('cargo', False) + >>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(False), ... "bin", "cargo") True """ config = self.get_toml(program) if config: return os.path.expanduser(config) - return os.path.join(self.bin_root(), "bin", "{}{}".format( + return os.path.join(self.bin_root(stage0), "bin", "{}{}".format( program, self.exe_suffix())) @staticmethod @@ -854,14 +874,14 @@ class RustBuild(object): if "CARGO_BUILD_TARGET" in env: del env["CARGO_BUILD_TARGET"] env["CARGO_TARGET_DIR"] = build_dir - env["RUSTC"] = self.rustc() - env["LD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \ + env["RUSTC"] = self.rustc(True) + env["LD_LIBRARY_PATH"] = os.path.join(self.bin_root(True), "lib") + \ (os.pathsep + env["LD_LIBRARY_PATH"]) \ if "LD_LIBRARY_PATH" in env else "" - env["DYLD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \ + env["DYLD_LIBRARY_PATH"] = os.path.join(self.bin_root(True), "lib") + \ (os.pathsep + env["DYLD_LIBRARY_PATH"]) \ if "DYLD_LIBRARY_PATH" in env else "" - env["LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \ + env["LIBRARY_PATH"] = os.path.join(self.bin_root(True), "lib") + \ (os.pathsep + env["LIBRARY_PATH"]) \ if "LIBRARY_PATH" in env else "" # preserve existing RUSTFLAGS @@ -884,7 +904,7 @@ class RustBuild(object): if self.get_toml("deny-warnings", "rust") != "false": env["RUSTFLAGS"] += " -Dwarnings" - env["PATH"] = os.path.join(self.bin_root(), "bin") + \ + env["PATH"] = os.path.join(self.bin_root(True), "bin") + \ os.pathsep + env["PATH"] if not os.path.isfile(self.cargo()): raise Exception("no cargo executable found at `{}`".format( @@ -1135,14 +1155,9 @@ def bootstrap(help_triggered): build.update_submodules() # Fetch/build the bootstrap - build.rustc_commit = build.maybe_download_rustc() - if build.rustc_commit is not None: - if build.verbose: - commit = build.rustc_commit - print("using downloaded stage1 artifacts from CI (commit {})".format(commit)) - # FIXME: support downloading artifacts from the beta channel - build.rustc_channel = "nightly" - build.download_stage0() + build.download_toolchain() + # Download the master compiler if `download-rustc` is set + build.maybe_download_ci_toolchain() sys.stdout.flush() build.ensure_vendored() build.build_bootstrap() diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 9398f211721..8244c7710ab 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -65,7 +65,9 @@ impl Step for Std { // These artifacts were already copied (in `impl Step for Sysroot`). // Don't recompile them. - if builder.config.download_rustc { + // NOTE: the ABI of the beta compiler is different from the ABI of the downloaded compiler, + // so its artifacts can't be reused. + if builder.config.download_rustc && compiler.stage != 0 { return; } @@ -513,7 +515,9 @@ impl Step for Rustc { let compiler = self.compiler; let target = self.target; - if builder.config.download_rustc { + // NOTE: the ABI of the beta compiler is different from the ABI of the downloaded compiler, + // so its artifacts can't be reused. + if builder.config.download_rustc && compiler.stage != 0 { // Copy the existing artifacts instead of rebuilding them. // NOTE: this path is only taken for tools linking to rustc-dev. builder.ensure(Sysroot { compiler }); @@ -934,14 +938,15 @@ impl Step for Sysroot { t!(fs::create_dir_all(&sysroot)); // If we're downloading a compiler from CI, we can use the same compiler for all stages other than 0. - if builder.config.download_rustc { + if builder.config.download_rustc && compiler.stage != 0 { assert_eq!( builder.config.build, compiler.host, "Cross-compiling is not yet supported with `download-rustc`", ); // Copy the compiler into the correct sysroot. - let stage0_dir = builder.config.out.join(&*builder.config.build.triple).join("stage0"); - builder.cp_r(&stage0_dir, &sysroot); + let ci_rustc_dir = + builder.config.out.join(&*builder.config.build.triple).join("ci-rustc"); + builder.cp_r(&ci_rustc_dir, &sysroot); return INTERNER.intern_path(sysroot); } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index b9b090bb2d2..471f671fd27 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -687,51 +687,6 @@ impl Config { set(&mut config.print_step_timings, build.print_step_timings); set(&mut config.print_step_rusage, build.print_step_rusage); - // See https://github.com/rust-lang/compiler-team/issues/326 - config.stage = match config.cmd { - Subcommand::Check { .. } => flags.stage.or(build.check_stage).unwrap_or(0), - Subcommand::Doc { .. } => flags.stage.or(build.doc_stage).unwrap_or(0), - Subcommand::Build { .. } => flags.stage.or(build.build_stage).unwrap_or(1), - Subcommand::Test { .. } => flags.stage.or(build.test_stage).unwrap_or(1), - Subcommand::Bench { .. } => flags.stage.or(build.bench_stage).unwrap_or(2), - Subcommand::Dist { .. } => flags.stage.or(build.dist_stage).unwrap_or(2), - Subcommand::Install { .. } => flags.stage.or(build.install_stage).unwrap_or(2), - // These are all bootstrap tools, which don't depend on the compiler. - // The stage we pass shouldn't matter, but use 0 just in case. - Subcommand::Clean { .. } - | Subcommand::Clippy { .. } - | Subcommand::Fix { .. } - | Subcommand::Run { .. } - | Subcommand::Setup { .. } - | Subcommand::Format { .. } => flags.stage.unwrap_or(0), - }; - - // CI should always run stage 2 builds, unless it specifically states otherwise - #[cfg(not(test))] - if flags.stage.is_none() && crate::CiEnv::current() != crate::CiEnv::None { - match config.cmd { - Subcommand::Test { .. } - | Subcommand::Doc { .. } - | Subcommand::Build { .. } - | Subcommand::Bench { .. } - | Subcommand::Dist { .. } - | Subcommand::Install { .. } => { - assert_eq!( - config.stage, 2, - "x.py should be run with `--stage 2` on CI, but was run with `--stage {}`", - config.stage, - ); - } - Subcommand::Clean { .. } - | Subcommand::Check { .. } - | Subcommand::Clippy { .. } - | Subcommand::Fix { .. } - | Subcommand::Run { .. } - | Subcommand::Setup { .. } - | Subcommand::Format { .. } => {} - } - } - config.verbose = cmp::max(config.verbose, flags.verbose); if let Some(install) = toml.install { @@ -1005,6 +960,59 @@ impl Config { let default = config.channel == "dev"; config.ignore_git = ignore_git.unwrap_or(default); + let download_rustc = config.download_rustc; + // See https://github.com/rust-lang/compiler-team/issues/326 + config.stage = match config.cmd { + Subcommand::Check { .. } => flags.stage.or(build.check_stage).unwrap_or(0), + // `download-rustc` only has a speed-up for stage2 builds. Default to stage2 unless explicitly overridden. + Subcommand::Doc { .. } => { + flags.stage.or(build.doc_stage).unwrap_or(if download_rustc { 2 } else { 0 }) + } + Subcommand::Build { .. } => { + flags.stage.or(build.build_stage).unwrap_or(if download_rustc { 2 } else { 1 }) + } + Subcommand::Test { .. } => { + flags.stage.or(build.test_stage).unwrap_or(if download_rustc { 2 } else { 1 }) + } + Subcommand::Bench { .. } => flags.stage.or(build.bench_stage).unwrap_or(2), + Subcommand::Dist { .. } => flags.stage.or(build.dist_stage).unwrap_or(2), + Subcommand::Install { .. } => flags.stage.or(build.install_stage).unwrap_or(2), + // These are all bootstrap tools, which don't depend on the compiler. + // The stage we pass shouldn't matter, but use 0 just in case. + Subcommand::Clean { .. } + | Subcommand::Clippy { .. } + | Subcommand::Fix { .. } + | Subcommand::Run { .. } + | Subcommand::Setup { .. } + | Subcommand::Format { .. } => flags.stage.unwrap_or(0), + }; + + // CI should always run stage 2 builds, unless it specifically states otherwise + #[cfg(not(test))] + if flags.stage.is_none() && crate::CiEnv::current() != crate::CiEnv::None { + match config.cmd { + Subcommand::Test { .. } + | Subcommand::Doc { .. } + | Subcommand::Build { .. } + | Subcommand::Bench { .. } + | Subcommand::Dist { .. } + | Subcommand::Install { .. } => { + assert_eq!( + config.stage, 2, + "x.py should be run with `--stage 2` on CI, but was run with `--stage {}`", + config.stage, + ); + } + Subcommand::Clean { .. } + | Subcommand::Check { .. } + | Subcommand::Clippy { .. } + | Subcommand::Fix { .. } + | Subcommand::Run { .. } + | Subcommand::Setup { .. } + | Subcommand::Format { .. } => {} + } + } + config } diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 3fc3b68fd86..30bd9c1b4a1 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -514,6 +514,19 @@ impl Step for Rustdoc { // rustc compiler it's paired with, so it must be built with the previous stage compiler. let build_compiler = builder.compiler(target_compiler.stage - 1, builder.config.build); + // When using `download-rustc` and a stage0 build_compiler, copying rustc doesn't actually + // build stage0 libstd (because the libstd in sysroot has the wrong ABI). Explicitly build + // it. + builder.ensure(compile::Std { compiler: build_compiler, target: target_compiler.host }); + builder.ensure(compile::Rustc { compiler: build_compiler, target: target_compiler.host }); + // NOTE: this implies that `download-rustc` is pretty useless when compiling with the stage0 + // compiler, since you do just as much work. + if !builder.config.dry_run && builder.config.download_rustc && build_compiler.stage == 0 { + println!( + "warning: `download-rustc` does nothing when building stage1 tools; consider using `--stage 2` instead" + ); + } + // The presence of `target_compiler` ensures that the necessary libraries (codegen backends, // compiler libraries, ...) are built. Rustdoc does not require the presence of any // libraries within sysroot_libdir (i.e., rustlib), though doctests may want it (since From 2370e3b439aa01982c33bbfe9823337a6231207f Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 4 Apr 2021 13:08:17 -0700 Subject: [PATCH 351/370] Get rid of unneeded `aliases` field --- src/librustdoc/formats/cache.rs | 4 ---- src/librustdoc/html/render/cache.rs | 8 ++++++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 7100cc87b0c..3e17db7fa7f 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -120,10 +120,6 @@ crate struct Cache { // when gathering trait documentation on a type, hold impls here while // folding and add them to the cache later on if we find the trait. orphan_trait_impls: Vec<(DefId, FxHashSet, Impl)>, - - /// Aliases added through `#[doc(alias = "...")]`. Since a few items can have the same alias, - /// we need the alias element to have an array of items. - crate aliases: BTreeMap>, } /// This struct is used to wrap the `cache` and `tcx` in order to run `DocFolder`. diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 022afee3105..2265905dcba 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -87,7 +87,11 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< } } - let Cache { ref mut search_index, ref paths, ref mut aliases, .. } = *cache; + let Cache { ref mut search_index, ref paths, .. } = *cache; + + // Aliases added through `#[doc(alias = "...")]`. Since a few items can have the same alias, + // we need the alias element to have an array of items. + let mut aliases: BTreeMap> = BTreeMap::new(); // Sort search index items. This improves the compressibility of the search index. search_index.sort_unstable_by(|k1, k2| { @@ -210,7 +214,7 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< doc: crate_doc, items: crate_items, paths: crate_paths, - aliases, + aliases: &aliases, }) .expect("failed serde conversion") // All these `replace` calls are because we have to go through JS string for JSON content. From 3965773ae7743e051070b4eed3c6e02e9df3b25c Mon Sep 17 00:00:00 2001 From: Gus Wynn Date: Sun, 4 Apr 2021 14:07:56 -0700 Subject: [PATCH 352/370] use jemallocator in rustc/rustdoc --- Cargo.lock | 35 ++++++++++++++++--------- compiler/rustc/Cargo.toml | 10 ++++--- compiler/rustc/src/main.rs | 15 ++++++++++- src/bootstrap/tool.rs | 7 ++++- src/librustdoc/Cargo.toml | 3 +++ src/librustdoc/lib.rs | 51 ++++++++++++++++++++++++++++++++++++ src/tools/rustdoc/Cargo.toml | 3 +++ 7 files changed, 107 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d00f31e315..4bb32f842c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1732,17 +1732,6 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" -[[package]] -name = "jemalloc-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45" -dependencies = [ - "cc", - "fs_extra", - "libc", -] - [[package]] name = "jobserver" version = "0.1.21" @@ -3586,9 +3575,10 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" name = "rustc-main" version = "0.0.0" dependencies = [ - "jemalloc-sys", "rustc_codegen_ssa", "rustc_driver", + "tikv-jemalloc-sys", + "tikv-jemallocator", ] [[package]] @@ -5318,6 +5308,27 @@ dependencies = [ name = "tier-check" version = "0.1.0" +[[package]] +name = "tikv-jemalloc-sys" +version = "0.4.1+5.2.1-patched" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a26331b05179d4cb505c8d6814a7e18d298972f0a551b0e3cefccff927f86d3" +dependencies = [ + "cc", + "fs_extra", + "libc", +] + +[[package]] +name = "tikv-jemallocator" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c14a5a604eb8715bc5785018a37d00739b180bcf609916ddf4393d33d49ccdf" +dependencies = [ + "libc", + "tikv-jemalloc-sys", +] + [[package]] name = "time" version = "0.1.43" diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index 6e6c0c71a1f..ca6055c46a6 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -11,12 +11,16 @@ rustc_driver = { path = "../rustc_driver" } # crate is intended to be used by codegen backends, which may not be in-tree. rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } -[dependencies.jemalloc-sys] -version = '0.3.0' +[dependencies.tikv-jemalloc-sys] +version = '0.4.0' optional = true features = ['unprefixed_malloc_on_supported_platforms'] +[dependencies.tikv-jemallocator] +version = '0.4.0' +optional = true + [features] -jemalloc = ['jemalloc-sys'] +jemalloc = ['tikv-jemalloc-sys', 'tikv-jemallocator'] llvm = ['rustc_driver/llvm'] max_level_info = ['rustc_driver/max_level_info'] diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index 859028957db..c80fab99496 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -1,3 +1,16 @@ +// Configure jemalloc as the `global_allocator` when configured. This is +// so that we use the sized deallocation apis jemalloc provides +// (namely `sdallocx`). +// +// The symbol overrides documented below are also performed so that we can +// ensure that we use a consistent allocator across the rustc <-> llvm boundary +#[cfg(feature = "jemalloc")] +#[global_allocator] +static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; + +#[cfg(feature = "tikv-jemalloc-sys")] +use tikv_jemalloc_sys as jemalloc_sys; + fn main() { // Pull in jemalloc when enabled. // @@ -7,7 +20,7 @@ fn main() { // dynamic libraries. That means to pull in jemalloc we actually need to // reference allocation symbols one way or another (as this file is the only // object code in the rustc executable). - #[cfg(feature = "jemalloc-sys")] + #[cfg(feature = "tikv-jemalloc-sys")] { use std::os::raw::{c_int, c_void}; diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index bfb846f3b56..c2b8bd71e00 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -519,6 +519,11 @@ impl Step for Rustdoc { // they'll be linked to those libraries). As such, don't explicitly `ensure` any additional // libraries here. The intuition here is that If we've built a compiler, we should be able // to build rustdoc. + // + let mut features = Vec::new(); + if builder.config.jemalloc { + features.push("jemalloc".to_string()); + } let cargo = prepare_tool_cargo( builder, @@ -528,7 +533,7 @@ impl Step for Rustdoc { "build", "src/tools/rustdoc", SourceType::InTree, - &[], + features.as_slice(), ); builder.info(&format!( diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index eb38adb0b73..d778a507425 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -30,5 +30,8 @@ features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] [dev-dependencies] expect-test = "1.0" +[features] +jemalloc = [] + [package.metadata.rust-analyzer] rustc_private = true diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index c6262f5873e..fc5b7a4f4f3 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -30,6 +30,7 @@ extern crate tracing; // So if `rustc` was specified in Cargo.toml, this would spuriously rebuild crates. // // Dependencies listed in Cargo.toml do not need `extern crate`. + extern crate rustc_ast; extern crate rustc_ast_lowering; extern crate rustc_ast_pretty; @@ -60,6 +61,15 @@ extern crate rustc_trait_selection; extern crate rustc_typeck; extern crate test as testing; +#[cfg(feature = "jemalloc")] +extern crate tikv_jemalloc_sys; +#[cfg(feature = "jemalloc")] +use tikv_jemalloc_sys as jemalloc_sys; +#[cfg(feature = "jemalloc")] +extern crate tikv_jemallocator; +#[cfg(feature = "jemalloc")] +use tikv_jemallocator as jemallocator; + use std::default::Default; use std::env; use std::process; @@ -113,7 +123,48 @@ mod theme; mod visit_ast; mod visit_lib; +// See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs +// about jemallocator +#[cfg(feature = "jemalloc")] +#[global_allocator] +static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; + pub fn main() { + // See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs + // about jemalloc-sys + #[cfg(feature = "jemalloc")] + { + use std::os::raw::{c_int, c_void}; + + #[used] + static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; + #[used] + static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = + jemalloc_sys::posix_memalign; + #[used] + static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; + #[used] + static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; + #[used] + static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; + #[used] + static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; + + // On OSX, jemalloc doesn't directly override malloc/free, but instead + // registers itself with the allocator's zone APIs in a ctor. However, + // the linker doesn't seem to consider ctors as "used" when statically + // linking, so we need to explicitly depend on the function. + #[cfg(target_os = "macos")] + { + extern "C" { + fn _rjem_je_zone_register(); + } + + #[used] + static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; + } + } + rustc_driver::set_sigpipe_handler(); rustc_driver::install_ice_hook(); diff --git a/src/tools/rustdoc/Cargo.toml b/src/tools/rustdoc/Cargo.toml index 36aa5916da7..d0c047ad6df 100644 --- a/src/tools/rustdoc/Cargo.toml +++ b/src/tools/rustdoc/Cargo.toml @@ -13,3 +13,6 @@ path = "main.rs" [dependencies] rustdoc = { path = "../../librustdoc" } + +[features] +jemalloc = ['rustdoc/jemalloc'] From 82b2863a204e727a37a2d23efd738387d2fbab70 Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Sun, 4 Apr 2021 22:42:19 +0100 Subject: [PATCH 353/370] Render destructured struct function param names as underscore. Fixes #83852 r? `@GuillaumeGomez` --- src/librustdoc/clean/utils.rs | 12 +----------- src/test/rustdoc/issue-83852.rs | 10 ++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) create mode 100644 src/test/rustdoc/issue-83852.rs diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 60cbe9f376f..9c0ed1480fe 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -251,19 +251,9 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { debug!("trying to get a name from pattern: {:?}", p); Symbol::intern(&match p.kind { - PatKind::Wild => return kw::Underscore, + PatKind::Wild | PatKind::Struct(..) => return kw::Underscore, PatKind::Binding(_, _, ident, _) => return ident.name, PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p), - PatKind::Struct(ref name, ref fields, etc) => format!( - "{} {{ {}{} }}", - qpath_to_string(name), - fields - .iter() - .map(|fp| format!("{}: {}", fp.ident, name_from_pat(&fp.pat))) - .collect::>() - .join(", "), - if etc { ", .." } else { "" } - ), PatKind::Or(ref pats) => pats .iter() .map(|p| name_from_pat(&**p).to_string()) diff --git a/src/test/rustdoc/issue-83852.rs b/src/test/rustdoc/issue-83852.rs new file mode 100644 index 00000000000..3c0369e3d34 --- /dev/null +++ b/src/test/rustdoc/issue-83852.rs @@ -0,0 +1,10 @@ +#![crate_name = "foo"] + +struct BodyId { + hir_id: usize, +} + +// @has 'foo/fn.body_owner.html' '//*[@class="rust fn"]' 'pub fn body_owner(_: BodyId)' +pub fn body_owner(BodyId { hir_id }: BodyId) { + // ... +} From 45ccd50d0e52e006fdd81f854b4cd711ac439e85 Mon Sep 17 00:00:00 2001 From: Camelid Date: Sun, 4 Apr 2021 15:31:43 -0700 Subject: [PATCH 354/370] Don't report disambiguator error if link would have been ignored This prevents us from warning on links such as ``. Note that we still warn on links such as `` because they have no dots in them. However, the links will still work, even though a warning is reported. --- .../passes/collect_intra_doc_links.rs | 28 ++++++++++++++++--- .../intra-doc/email-address-localhost.rs | 6 ++++ .../intra-doc/email-address-localhost.stderr | 15 ++++++++++ src/test/rustdoc/intra-doc/email-address.rs | 6 ++++ 4 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 src/test/rustdoc-ui/intra-doc/email-address-localhost.rs create mode 100644 src/test/rustdoc-ui/intra-doc/email-address-localhost.stderr create mode 100644 src/test/rustdoc/intra-doc/email-address.rs diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 437f42b26dd..545fbf26181 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -978,14 +978,18 @@ impl LinkCollector<'_, '_> { Ok(Some((d, path))) => (path.trim(), Some(d)), Ok(None) => (link.trim(), None), Err((err_msg, relative_range)) => { - let disambiguator_range = (no_backticks_range.start + relative_range.start) - ..(no_backticks_range.start + relative_range.end); - disambiguator_error(self.cx, &item, dox, disambiguator_range, &err_msg); + if !should_ignore_link_with_disambiguators(link) { + // Only report error if we would not have ignored this link. + // See issue #83859. + let disambiguator_range = (no_backticks_range.start + relative_range.start) + ..(no_backticks_range.start + relative_range.end); + disambiguator_error(self.cx, &item, dox, disambiguator_range, &err_msg); + } return None; } }; - if path_str.contains(|ch: char| !(ch.is_alphanumeric() || ":_<>, !*&;".contains(ch))) { + if should_ignore_link(path_str) { return None; } @@ -1515,6 +1519,22 @@ fn range_between_backticks(ori_link: &MarkdownLink) -> Range { ..(ori_link.range.start + before_second_backtick_group) } +/// Returns true if we should ignore `link` due to it being unlikely +/// that it is an intra-doc link. `link` should still have disambiguators +/// if there were any. +/// +/// The difference between this and [`should_ignore_link()`] is that this +/// check should only be used on links that still have disambiguators. +fn should_ignore_link_with_disambiguators(link: &str) -> bool { + link.contains(|ch: char| !(ch.is_alphanumeric() || ":_<>, !*&;@()".contains(ch))) +} + +/// Returns true if we should ignore `path_str` due to it being unlikely +/// that it is an intra-doc link. +fn should_ignore_link(path_str: &str) -> bool { + path_str.contains(|ch: char| !(ch.is_alphanumeric() || ":_<>, !*&;".contains(ch))) +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] /// Disambiguators for a link. crate enum Disambiguator { diff --git a/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs b/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs new file mode 100644 index 00000000000..417618c7458 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs @@ -0,0 +1,6 @@ +#![deny(warnings)] + +//! Email me at . +//~^ ERROR unknown disambiguator `hello` + +//! This should *not* warn: . diff --git a/src/test/rustdoc-ui/intra-doc/email-address-localhost.stderr b/src/test/rustdoc-ui/intra-doc/email-address-localhost.stderr new file mode 100644 index 00000000000..de215b2163b --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/email-address-localhost.stderr @@ -0,0 +1,15 @@ +error: unknown disambiguator `hello` + --> $DIR/email-address-localhost.rs:3:18 + | +LL | //! Email me at . + | ^^^^^ + | +note: the lint level is defined here + --> $DIR/email-address-localhost.rs:1:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]` + +error: aborting due to previous error + diff --git a/src/test/rustdoc/intra-doc/email-address.rs b/src/test/rustdoc/intra-doc/email-address.rs new file mode 100644 index 00000000000..c407eb80da2 --- /dev/null +++ b/src/test/rustdoc/intra-doc/email-address.rs @@ -0,0 +1,6 @@ +//! Email me at . +//! Email me at . +//! Email me at (this warns but will still become a link). +// @has email_address/index.html '//a[@href="mailto:hello@example.com"]' 'hello@example.com' +// @has email_address/index.html '//a[@href="mailto:hello-world@example.com"]' 'hello-world@example.com' +// @has email_address/index.html '//a[@href="mailto:hello@localhost"]' 'hello@localhost' From 14fac683289dcd53625544edd3372e5fc737c7ed Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Mon, 5 Apr 2021 00:29:43 +0100 Subject: [PATCH 355/370] Renamed test --- src/test/rustdoc/{issue-83852.rs => struct-arg-pattern.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/test/rustdoc/{issue-83852.rs => struct-arg-pattern.rs} (100%) diff --git a/src/test/rustdoc/issue-83852.rs b/src/test/rustdoc/struct-arg-pattern.rs similarity index 100% rename from src/test/rustdoc/issue-83852.rs rename to src/test/rustdoc/struct-arg-pattern.rs From 29fed9aa4e8e3124bde9debcd139431594a7b26c Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Mon, 29 Mar 2021 18:33:22 +0200 Subject: [PATCH 356/370] Update Source Serif to release 4.004 Now the family name is Source Serif 4 (upstream issue 77) instead of Source Serif Pro. --- src/librustdoc/html/render/write_shared.rs | 8 +++---- src/librustdoc/html/static/COPYRIGHT.txt | 12 +++++----- .../html/static/SourceSerif4-Bold.ttf.woff | Bin 0 -> 110552 bytes .../html/static/SourceSerif4-It.ttf.woff | Bin 0 -> 78108 bytes ...Pro-LICENSE.md => SourceSerif4-LICENSE.md} | 2 +- .../html/static/SourceSerif4-Regular.ttf.woff | Bin 0 -> 103604 bytes .../html/static/SourceSerifPro-Bold.ttf.woff | Bin 93248 -> 0 bytes .../html/static/SourceSerifPro-It.ttf.woff | Bin 36200 -> 0 bytes .../static/SourceSerifPro-Regular.ttf.woff | Bin 88596 -> 0 bytes src/librustdoc/html/static/rustdoc.css | 16 ++++++------- src/librustdoc/html/static_files.rs | 21 +++++++++--------- .../unversioned-files.txt | 8 +++---- 12 files changed, 33 insertions(+), 34 deletions(-) create mode 100644 src/librustdoc/html/static/SourceSerif4-Bold.ttf.woff create mode 100644 src/librustdoc/html/static/SourceSerif4-It.ttf.woff rename src/librustdoc/html/static/{SourceSerifPro-LICENSE.md => SourceSerif4-LICENSE.md} (98%) create mode 100644 src/librustdoc/html/static/SourceSerif4-Regular.ttf.woff delete mode 100644 src/librustdoc/html/static/SourceSerifPro-Bold.ttf.woff delete mode 100644 src/librustdoc/html/static/SourceSerifPro-It.ttf.woff delete mode 100644 src/librustdoc/html/static/SourceSerifPro-Regular.ttf.woff diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 59dc4ef9449..8fb6d68f3c6 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -26,10 +26,10 @@ crate static FILES_UNVERSIONED: Lazy> = Lazy::new(|| { "FiraSans-Regular.woff" => static_files::fira_sans::REGULAR, "FiraSans-Medium.woff" => static_files::fira_sans::MEDIUM, "FiraSans-LICENSE.txt" => static_files::fira_sans::LICENSE, - "SourceSerifPro-Regular.ttf.woff" => static_files::source_serif_pro::REGULAR, - "SourceSerifPro-Bold.ttf.woff" => static_files::source_serif_pro::BOLD, - "SourceSerifPro-It.ttf.woff" => static_files::source_serif_pro::ITALIC, - "SourceSerifPro-LICENSE.md" => static_files::source_serif_pro::LICENSE, + "SourceSerif4-Regular.ttf.woff" => static_files::source_serif_4::REGULAR, + "SourceSerif4-Bold.ttf.woff" => static_files::source_serif_4::BOLD, + "SourceSerif4-It.ttf.woff" => static_files::source_serif_4::ITALIC, + "SourceSerif4-LICENSE.md" => static_files::source_serif_4::LICENSE, "SourceCodePro-Regular.ttf.woff" => static_files::source_code_pro::REGULAR, "SourceCodePro-Semibold.ttf.woff" => static_files::source_code_pro::SEMIBOLD, "SourceCodePro-It.ttf.woff" => static_files::source_code_pro::ITALIC, diff --git a/src/librustdoc/html/static/COPYRIGHT.txt b/src/librustdoc/html/static/COPYRIGHT.txt index 24bdca6544d..16d79032fcc 100644 --- a/src/librustdoc/html/static/COPYRIGHT.txt +++ b/src/librustdoc/html/static/COPYRIGHT.txt @@ -33,14 +33,14 @@ included, and carry their own copyright notices and license terms: Licensed under the SIL Open Font License, Version 1.1. See SourceCodePro-LICENSE.txt. -* Source Serif Pro (SourceSerifPro-Regular.ttf.woff, - SourceSerifPro-Bold.ttf.woff, SourceSerifPro-It.ttf.woff): +* Source Serif 4 (SourceSerif4-Regular.ttf.woff, SourceSerif4-Bold.ttf.woff, + SourceSerif4-It.ttf.woff): - Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/), with - Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of - Adobe Systems Incorporated in the United States and/or other countries. + Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name + 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United + States and/or other countries. Licensed under the SIL Open Font License, Version 1.1. - See SourceSerifPro-LICENSE.txt. + See SourceSerif4-LICENSE.md. This copyright file is intended to be distributed with rustdoc output. diff --git a/src/librustdoc/html/static/SourceSerif4-Bold.ttf.woff b/src/librustdoc/html/static/SourceSerif4-Bold.ttf.woff new file mode 100644 index 0000000000000000000000000000000000000000..8ad41888e6e3f9f4439052ae6b14ece2cdfcd7cb GIT binary patch literal 110552 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Ǭ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 Ef5?p+(f|Me literal 0 HcmV?d00001 diff --git a/src/librustdoc/html/static/SourceSerifPro-LICENSE.md b/src/librustdoc/html/static/SourceSerif4-LICENSE.md similarity index 98% rename from src/librustdoc/html/static/SourceSerifPro-LICENSE.md rename to src/librustdoc/html/static/SourceSerif4-LICENSE.md index 22cb755f2f1..68ea1892406 100644 --- a/src/librustdoc/html/static/SourceSerifPro-LICENSE.md +++ b/src/librustdoc/html/static/SourceSerif4-LICENSE.md @@ -1,4 +1,4 @@ -Copyright 2014-2018 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. This Font Software is licensed under the SIL Open Font License, Version 1.1. diff --git a/src/librustdoc/html/static/SourceSerif4-Regular.ttf.woff b/src/librustdoc/html/static/SourceSerif4-Regular.ttf.woff new file mode 100644 index 0000000000000000000000000000000000000000..45a5521ab0c77a02ebf55a3f7305faccc02e2894 GIT binary patch literal 103604 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 literal 0 HcmV?d00001 diff --git a/src/librustdoc/html/static/SourceSerifPro-Bold.ttf.woff b/src/librustdoc/html/static/SourceSerifPro-Bold.ttf.woff deleted file mode 100644 index ca254318fe9ea9fc0f3313bc5df7ea5109f16921..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93248 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 z z`Bbuybec>KhsopwOgG{X@4J+acwcl2`yqoTo=4MSEv_A#lWoE||Um&u`o22A>R+S&qNX`y_RMQwAc< z-ixO%q7KZ>xo^3JF7px4^@H=@qfc}+F=t{eD6GMSYf3c^o%DFFUmucc6birD?iVW^ zMC;7Ect?1Ax-}v?#LH&IGb{3dGA}Hoy1LB)jZA4(*etWFOVWfhm=g(;e7->w0~{9v zj{Q6d?Wv%%IC7_5fqP+lG2*m_+!~8qW$FtSnlDOq8`W|44qL$R1hk?BW-N;4Y0lIl z+##&J{{8QRFLKSihWDZQM=?EX@ZSCe*YYrr2x3uASN@`H5mBLN(bK*tv#^dnDHA~-+cy<1y{42Sb*QGOsjZTVg zDcxeWY3mcAkkM=oHg&CIAn($$g*>B0eEe1e^G=uEZqzt6{SJQv#J21fwNs&UYxJ|B zN~2}8RN@%#3HtUWkjlUENN@7)1bCf_p8*`?1mH^e{Xw?;ex|&TvH}vOG#|62t?>I= z9)`KwiBwdaNA^Wi^!zRgak~d*@ot#R@A6qSL9NbXb6}_M_S=2S&3+hqHUO%51j|Fn zMSb+$u-xae>mzEt!{fmZ`ELW;Kpjj3Eq0SW0L0_k8`ueU1bCMT77iyxb&OBh?H-*b zq_O&N9UuO*I;gSQoROk`H=&Bg@@v`}A+%^%n~dRlgVz#BNQVa6$_!uHBry0@f=$APS7GgnEAW-s-u_0rfcU zI(t2z^dCFs?>$mzQPA}$i>(TgpkB{PoC3S&T(Em=WEKvF7OWqxe#rF%MZ^$lQ71*g z?oCcx)S~tJ^C_GPRQzC`1ZayWaAS8@)NVDVA`u>DY^qa$+j=J4XFN!8}ha9^o$SVE+@Z?^X7A&l|L;*-}`FYL(Y&#y{o z7xMYA+CEl+I{bid1-_~7ZOIkDcV`HADF4e_e_hj~;w@9S?bO$&cB5Mxv@{c1gpJ$1 zv5P$0SXzHYo}m>$uNThQx|_+iP0>+1pU6k2fYE0!y~~MP=uXi#Q8o*|a(kLOozBjt zQkT=&RjQsho6pakSE-&mm(S0h_hK~qWGwdNH-=A6O`RAXJ~1_Qa=1CR;>67Ki52nK z^vM+~;BTEWw2@FIWhwm}d6pBd3gG#A;DQn!ayr6FW;ZT!Z2d`d?JFy;x_0830esV` z2ZY6}4Bb~-tIQVV_50nNnjAi&O|tG6^YRS!zIIxb>@5)HmC zBdymo?qJ16pr#&0EHMEVlL%Uil{LjTzJ#6?kJnM3I=<{h1))%& z*E74xg?huAC_RE!AFf<|B^s&yco;ACbgZYjy$xwmb62$u;Vs3YL~fCzmi3j5 zuoAQ@A^jB=8%pZX#>)B@1Ygx&?V1tzy1aqlP>?^p-rMaJtmqn?<_Cs?K)(p+znsu- zp*aH(9#sL(v;pn3doWZWy4#6O1x~j)Fr6aXII2%XUx3Bw$0QyV^9@#g)A)b{8l8yZ zW~6OKD4H+`g_42sCcVYT7t1qS*CI4j`~DDKvn`EYDx0kc7h4DO`GJ^34V_E(pQv)I z&99Nf2J-pA)*?n$b9roMt2jOzr+Yp=lMuJ=Zb9v7ciJj* z+zr0{-9F(-bmy-;o)ClAtlm5(tJQEv^!)kPTg0O@V+c8GU-R=V)dBC+p*o z49QQ{X`;3hn%bArWa4Uo+*!1NZ{hP|3crB|P)jd@l(1gZI*8!kVD0f<{BuSzoKEGA zKs|UVsvJz0_mxGbX^f+lu0t)1rl`}6{zm8yzYE=lv(fiBFspM2AzHY-Uo7KF8Th9;+ZJtncUtQv;(<%B- zv;r3J36%i_O(lBYdr}golm6ZJsxvTsgE;O(uk#el32V$jic7BcESYGdWWnYW3O{d4 z(AKk1m9hn49Ia|@+fazKss-0+l=`SarBt*8y-hMxAF@rZix!)|>ah3JZfH7p#l*g9 zG?+KZH+-VIL+G=GLjGWYM^41A;ym2zswML@#iWS@MIk1NPn9%{1w8j65R>RxezKBn zvQ`R;md;#s`h(J|_ioth8EDE^j?BJ-Myhd}PD=q=z!xV|%j*tW#iR;0sMrbSM-Iw>a6BMxiPptsso z3Z}bxcfj^7odUJSi$iJ2EE;r9qrq9bj~S!cB9)=(c7|R zg;pfhNh+C4GSV6F1-6ctRyUm=Z<8zfW95;M&*oCWGRkdrClK0zJr1kiW{6ed)dxl-E_~5|6WmnW{XpgjaZ$~_rZY#DP z`q8LBZ&&FpQjKP^b?T`bRF_JIm)&(qCX!Of)xD|2vI1R~6y#A2?e;>%73>XK4s@ar zv-jB-;v_5?O*#?UW)$F%Jrx(+s?n=W0<}P?D+W>}k!3RFtwxaOw$J?b&1$GvdqAQ2 z%`Tr4d7bWbp_Fru_SYOvP#T2Ke};Zn@Qge+)am75G0VAcG&fO_J0M}2kE|xGN*Ppj51?fZ*|v*E9U+U**U9Wv z@Srz%MINsW*YmY=Al*`u3Lqu=&gPep& zpONi~;GxkGzA`MR^SE(oE_x=El?3|}4(l~qhxvLnU%*GopwXPr$gWod>vcxpyrxN& ziLcH*>Cz%6+UAh0IJPQmHRx@q7kcC5xFc*9`dmI9(O7>+e`hpSaB0?CZFxG z#?vx|%BqiT*|RGPwfkX2eh*?(d8i#K<&4PsMh8(rP`|jZl+7-v2os~ezATwo=ZdfB z9U5PeDO-lxzl?4d>^iT#Pi~bfUCQO7zVK`^qwhQdBi85C*u`4qL`!u}D~S|rg+8O~ zpkO_}Deo>Kv>%n?-jG-?jpl8+sZ3*L69Qk9JRA4ca?Tayz$toOM)Iy*Z5`+K@3^G% z++sB1%Gf5H8CCPXsmXnn3y(})P;D6cF6??&N~{c4EQ3gCi{m_{D(^8^+P+$)ld4k%vL}jJMe*O14DGauy{leRWPL18{|r*x;2=uYMN8I z_CPM?)LUg5g|BTg4d;1%G(8*(II!35Ywn4xi*>dQO-MAN?4&;$l}Ynk+a`ClTKwbW z9QZu`89vMtf-ZLh9reAE0(v7|v4~1R?qx=_{qWi9psargUDMws>FB7vB)jUm8*k%p zrtY}n(i_BAy*9a1iEfc@+`4*~thPh8ruKygBuCFb|61|omy0ghzvp_{2dudg@!UvC;Nb_C(5{aO6z)e?fnrlZS}xK8IeTDPl6+>h>#ZDAga?rv-CT zDEw1#Rnzr{#l5YLxY6d4phIfD%;iXC+6RRf-&9=F+B~3A4XeuAd#|`c5;gCbY#;Wd zv+)g0I%)InXgt4qbbPlZD!lBPuI-i9-ku7{iOrzT(;Av%wGi#N#ExnhFZa;Kizik| z_D3q`FVFVr0}hK{6OE;s^Xc|n>tWi0u_?6l?kG%kK(!47!whb$53+OddT6 zFk()J`z(Hy)i85V}hKT2g*mMNGk%3zYoY*`BzL|lS37psr1irNn=RH8f=l>Vr zoA6IqxQ=%Z4X^87Qhqms$4%g5bQ1V^4BWW@r|~dw9n!FPo+IVYXUg9~>U|UHy^ON5 z_1?hy90$LZ#d8Dl5}%uF-j1&Uo28xZfl`TUwdnPtC3Xw^ryjB5Qdk@KEA zyAKRXrn=H8oZh=$>(_-hdWa^jl9^0SYvKTR>N1_4(u^F932f(;TE+6+WLjG{5@%-UhEXb+ock$8TP7EgDqDLoi1uWMQsu}hQ{ zr6yd>ReOu^>W*rz^$;VWc9}|^o#~m`mJ>?&K5InMJUDEp_=0RK6xDlmor&aBv2H`5 zN70{Xf2~PJ1q?K=ONNkMZ_tUF9VT@2HxwUz|A+FMKaIj@t!7-=yCp)6t7Jx5?JauM z=7G#38~z2E>FY*_AQY(og3;}y$U+V6Qdlvr%?FW98*cAdAYw|`$CCmg@(tNUhd-0kO)lbDOVf1-czgy{by^m8j};hM~BBZBd^_@7(`x#{=F|-hwKNcmWmCllJ#4ieEpc*ZDyTKyVU1baej3%G2 z_5+jOZ-O5jR=Qd(-EosipDV&j!fCa+TsEt-@t1dcWQT`|FLf1ofStTJHEj56B6E9kmX3XMwLcGG4BkXXTYp=>SS5yV&%-B5JJVEgMb_Wn z;xCHfk}d~a(pCFo`$g@&ece51No9L2!-a_FRXmE_R2`x@#??(k?09I z?UOrJ4YVJtzV*l>Z=D`v;vt~nHR}7|Z35jLARA7(o=dN=aYt)`j9;=O2sNxxBkefI z<+v`;ETjIIbRZC!MSEKDPrZ_Cz(zYde>jM3fvm)<=&P6tjuD%B!6B}&xz$o1@sbS3oAf@^sYQ?H{*+Obp~FePT73)^L`Ldy~j8U71(5N5?Y=vk2;MVIjig|H|53&5?GGsscltRfORO+e72 zK5;haqdnl?B+mLuFG4nF%&&EKMrP7^i&3T2M%{C()mFOeTl?x=-y&K>uc&gQpe>fx zt`OrPS3+P9L)S`2MwqUp?b}!IhwI#AHmTQXdWTqEeHaL&QLo;umgz)Rt8fm@GXcHF zfYkjWquD;v6w6PUTymK{Xl<~koO9j#n;y#i4JK^nI9H~m1EDVfcsjF1jiios)abVKLX7Kltr z>aok_t(_Z>Ds9SIYhWOd_YVZpW69W9_Ljh4AU76Gj%ES_{-u#h7&$%og{5Pg==?MG za*lza_n{^tf$OCs##8r`VO{E^0pB1Q2^`f=3tu(RcC;)G|!hI9&VUBzAO#`Znh~P;nILvvEUEPpII=hYH&>LXmId zx;-Lz@N`((I!qKcz?VEkuWtE560u!M#o4)VMi~AHD%8dOZR;S$gQ(a}Ki!XUI|{ea zA3u(ls6H47r*WuyoF1?h623iN4FJQc$6#pGsh#iPJAvAcGxyqmN$&>fsPXN+?@TiE zB-^R)PBPog%>Cof1I;e7r?FJ0qj)BR$R`qTO(LJ3LO&ZpNE^`2o|CtBo;O>235YzX zMR|nGmBFq)p-hOLez+*kZHgmQn#~6XT77lywq4kM;@{TJ*a0KA$`O!2PAeJSXuiE zkoW*XwvNH}KCwnjXv%LSoXZ6US_3Rir1rtyzCKjn-SrY~g*i4v@9m~tK4daw5?+#+ z*de7wch!0MgARSv+&mt~_t25>4^Z*ZQaWTG;YT)BHr_rxcgNbwTGw4Cq~hd(Z4T%U=)QyEWhaKlub7;?JhUj)sQ;$jT?boEw?-~VZ@aR4@Q#BA?;Ipq zTyNp4pjV=_-#EhECRW1`)U_v4V$rBftj zmT1tIMUxSnsJ0ZvM+#MyZl-Bs15vHa&=Xe=X7q9YAxA(hKpT1vw{#Xxve{hJUeNQ? zJocHydFOcb9hhIm->Pd}U1`bcgbh`CMT@Tq_KEa-+)Yhsjv^Ea(F>H;ZKLu+rM*w2 z5+Mxf|9F)S#^NXT6?SH+wk@r}v7Q7!tyt4LJA=${!z8(Ck_=0BO#)N~sauGbLyVU5 z8nV_7{T?L#+9lVAh?qnSC(bc9PoncS-nnAcU8|edCitUvf1)sv;@?cm+$~gcsvJ$& z2KnLjx{*5%oPXz##d6mr>gb-WW51l(wJ)YQai`JIuqt@OssK&3G^=cJUIEGApF(@d z_cF4c0=tg788|AZeKU0>!RRlv#LPR}$YpIkJcE$tWP2Z9#6R_^rFNgnrI|Y?XRe;N zvi8Pc!~849v#10k_J+Q`+P}GW;2DSa@it-#ChMAodK4&E@Ol`^S=CFOm0I7~rbk+` z@d<$x7xvW+iigvBwhl2hf((5S#dwdc=blM%)7v!A_#RmRNL zPvh^yTvO)Qxxic6T3t}`ob&ZS`{$NSK6lXbb@I|HuDFz}BWn1YP>Tt)5Jfo7Y_V-zn;@c)<>_YBx%`Sbdsi`- z!h%HH;Z<0b7ht?XSj@>_>Th2=5R15iO8Y>%c9_lar7S$lY3nFDcV?lt$@=sCrb$ul zA0*M2vs}93G064xKyOKk+?-(-*UywQEFPaQNpmxYj~!!jhet-3?BT=N7R5sPu(G9m zUYYo3dZ^z42R8rz>z@J97JC1G@X%N{Q=%7e&Hd^9fNqv@eDY}kN| z*ZUtiYq%G6epxCvD=a>>9t-e$^55*=;Z3%;+9N-UQ+%t-8n?f*GpBoKr`*!%3S>ph z%I}9jedWLOnUGHVkGv+9t#o%NMgN)Ogkd+aSze<$f#SBaP)w_!r8I}m~e=tAr{hdMBF{2tf#O2AWJo^`5)#`jfP!W0YVD5zE1ca5$*9| zIQO!OOfPdXHH&9W&6K?I$Z5HmBue6!~F2}4xwD&PIR=`qZ+9KB-g7oj2`YSZ@j3tye7dP zc7P&S*;JejNhKG7k%cTBP7pm2kyTsDrCfI1=Gha|QLx8OYFaPevgN|orMcj!@yv4q zy^9p_`Plj&%;yP;7^sj+)jKh!3 zkbeI@=KXUx@QYcv866{V*Ziw=<_s1>D;wv6xhZhOCNq((1I{j&Hcsi(x~^Q$a-TgQcJ1ys=jhx1j4@;l#*(kBIJeYx)6tzD zkNBKYzKkE06-M+%g-E1_`DvuD<3PvQ#-ZuJ?5@qD&|&o0!V2^|o&{)264_gH|Kx(4 zne=+bwc;zWXHz;*Z0%^OYp^}EVYc>K0iiolIGI@&j)oEPMG zclYp%nL!28cxD3ozA_kC;rU%MsrHY%+kpI^zW@C{?fl$99=XHyRrC_+Yw%MNt@Q>~ zLa)*6rBW({f8$p!NTw{ARQ~hV^v3LZo%l`A8^0&IF@i>T zgcdl@tsTA2wfmM5py$|7Tzj1xEjyQ%2P-Nxh$|pB-PNY1wAYiOJDL(=OK50N0V0yL zrds<~JFMYpzibh;GT)R>?)Ue#%IaOohc2%grLEAFNe~a9R|5350Po^pWwW=f5X!hi zZE3`8Whf>M*)>*~N~+TE`_PvQh@o{O1&h>nc|2{h$)rYK_Qa5y!&HVm7?BgVb&s_( zz4s(g0Anv#ztmEv%Pp=Mf}lRi1blQ<%D+E%*9%32inTW?lH1!qC@ZDpXtyF+`y0}5 zYf;?xliEe-qMzI@Pce0DgE~@6C4|oYJ8LK9g9Wq-$s29EhtnPKaGJEp{Bz0V-03~w z9dWxyymc*uEkw&ic@3#u12ip-_??OAEX+aIk2~rtfX_F>Rq(b`A%Jiyh`$rCRiiF{@xC$gDJ{Fdt9|&vvgg^Y=55Ffw*I|m}iUCKQ zg!&va!Z+fBz@fxqSy~z$V!vTvXbee;2u;g+tTh#pB1smZYY{6)^=WBIX96^^0(x+{ zpNEL;7Gr8(D#;vsw?2gQI2(qi!$rnXt`_fW? zE4`*t9+}kB@m{Ms7*j+2TLW}NB=FI)ADZHDgQf>N_y`b?oDf79C9d^bX~W~4z#pNXa75VeCLnUp)bofyZv{n6gY!k}E` zoegG+g(PD?QndYOg3;NzM5;IeyCt;wIHo0+GK>~fCOY*;`a$DW0h!TFGk*op2N6=m z6Y)4-B3PnAm$9Pn>;b}KU4di|$L<8Wv*j!~)eq=KZv)+Sl41YesdLcu=tJt>sX%DU z>No537?YV~mS))(*qXZoG|RX(r;AO{Nr+w>pr`6PIZ6dn5}&s2S(HwcB@_Ln4^r-8 z5JHs3Nnv;@IdpE@r6)#L@r53p#RowM2|rZ!;Ag5-Z@(3x4g2(l=5r^HUp@fVfisdu z&hY^rrsogJ3bo3J<+b=6tyg0fbM~%Y zb?)9(`AhenaUR>WzjEIA1=j#ALa-WK#6B+oEjikoQKv<)C`Pw*qV=*Ny0RG|OCq0{ z=XL6pt@+X6jRz5*NX_4ykuR|7wKRP1oXeK#cP-T;qatPs zE}=@L`a?DUw%f`h`O(;PU|FQtBBc`ctV^TdizNbW$Zd6@C>d}Ft`L((6Vl6?FKTVM z{M;8-2JJzM+f%SXS?de(UTYJ4ZG*~eX~>>f27Z0 zbyrLE>}m86u>q2ej2{%j{|C>05{m;`(00PZ0C~P@UdMZrd=JlLwe|+Z2We0c-{GRc zhL+frXC0=DVTlC@Y2%4lLLd{=rk7fo8jlJ_Zg9iO*H~Ngr(|rF619JFjm{+lnPYY` z`hyA)syk1onk5scDm29( z1rlMZrKYN}-Y_B1ZeKFr$y@_2_@C|<9m&-C1r{>d@MNt)q~#Bcv`q8ZwF!a$p1=jD z1aQU970BVDt2<(aHwALB=RSDU8%qOM2x=QG+g?kQM)e(YoKWYu8OvaN7_ zk&l;Qtzi=KVk|-u8skb$NU!I_!A`WHSyLPT6V;!nh2N&C#tZaeEj=r4SnEcHTr`;y z$OSMKr|o~e=nE@|?dSX8uDdW5?FxpwBhPx*1yi{~lEl6kE1jGmWvj=&azW1JigfkF ztz|SKTP(@{GCvtTcv;83!NGkUmmN%`&?7jBzB;jD#Y8Q4&B2LtTU*YZJbYDtZsW!| z9-9B>d<|CsJNRBrOw6mqSqCyoTK(i!vlkNpDFTn+Ufx{TYIRlAynpc%2i)wZFi10XCdmPXQE#E z#Zj+dq2be6xw7unDHiK~9q)vvpkHw8=nJq4BEFT4)C%ChR-p2~cb#y9B=78>5&hQ= z6wM63#|b9N*<3UKwHu{Z_Pv|X8C^5PyW%3=mENUMum8Z$!U=m_Uypie4OoERyX$4c zv_I3{T3{kyN$0!zVQj6VQcI6JkY!d#>!1y7|FsWn{Tq@WzW*H^95f~N zc^BqqPDwvHll)Y8d*_BcS`|6UqQpc>TF;I4aq?a z!;_2q;CV+I*e^YJl8gW9LUuGjR}dV_70|(j8hBFZ+bY!HU}_MVP79nhE+$2*A1d#^ zbWYIY`gwA2H1n07gD0AhB|b1n*C2cUQ&Q+Y(ZTa2&~+dFsW=`N?cWP1iJ!fH>C8_m zd2jxNDSnUpv3K?;fasjnr2y87p<&hVe8hSo-gjc9{Fbp&?g2O{hvKAMXdyyF%KaZx zPQ$|gNvzqoIV%9V-1AI1GYfx(E{E<~u$u6FtktAIgN<_7LablTGyNW4!Lh37_x{Gb zmt25TIu>rC;XF*}vrw29E1KfwY%-r{z>o5nsQ%UW1r#i_#kzEpnijI=Ou`LZh+jW&#E|s#)s(Xg>yMK z$hsy(`)%t@px5G*x3Oz>@jdzY0(VLj@F}f&k$8FSlul!Bab(3ouhOCwOB{XA{$8t5 zMq5$m2ix87uRS%ATr)hhHaUuK4@J#hvBEM~sO?7&e`@_Xu3|W;cZ(F(fdVpS1jX9k zYu23Sve{2K?{u#`NjR_lMk* zf6h*3>``4@$(IRzO~rspqKvE4?(}#DZGZBELbqG^8_NCBkGiSfQf@bO|Mzbx^?2m6 z-gbnl-CgbcwqB{y-2AcrHiB8BB zzG&?8_YSRCHF~@E%(Ni!pIXYz&2G5ya@@^-j@~Z{`ohlp2ro!(OB11IQM`V~0l?wH z2!Q{Zz<-UJ2)qycL>hb_z@I1Z=h0OSIQ|3+r^|nU#q${g|20!ST3^+}ua(#VpS1M- zJUPK>$HXD!;0?7e3_rZ~ONH8tz1}bRy3uV<{x~N=&(|!%bXu}*wIoNcsDN5L04=bB zw;;{t=rBQQZq{qb$1dtf)S>?IT-1$1=dEv>*)(mb?g5?AjlSqa_O{-Rb~iFN7h!%k zXSd{pxq(uwQzh*yS&9jJPMF=8EpE)@GR5>C;&X{)DnV-iUIN-0$1$FJQFcx+SRWjV z^KgzDqI%t+Ah5n=#dXVabNkvhP6&te9)EH&mmUjBC998WO>Gyh?cdew3m;pnNpG2& z*plX9(%!w$UOmspX)V{=QCe8M((R;Ms9JaR;KWTEz=wM$a*fQ)47(BHIWrqG!d%C} zWz&b-a>C5Ue13Cw@3tL#GMlqJMCvg?Js$Q3Ehb!Zri1k8I({Twrnnugmo+s>Hz0Js zVwt4o>_+p>EM3cWv%sd-&s2&V(lgi4l`%EQpa$33YG7Af1pm(g{|C?}S-C9Vh$d=3 zIt};3z4^5%QI5e)_rzxCi3nqDFU><|G#K}GFq}_qsIIzpZ0N>qvDIPWu)*U?O=i=R zS&a%!B0~zHPOr(_bJ6Vdg?$?R@%4(#mhp+L8OrYK_DZu^p}(JL)yJS!DW+BIGV?6q zH%=?}qAuiWM~|U)X6_k(#@Og>Hfm#w@CJ5OGvvma; zef6d*{?v|8ckS1m2;VjGF@9f8itZEVYImY7^)3L^q_S1v`)a$<`)>M{GzT?Bz`Jt= zJ@OfAUE@RbgK&v;gmmcUH%CTl-@)5nAC`Cg08xbX(wYlhT6;v61I>AdN|38PhA18; z<6{qu4;9fOr=6l$I_(t2A6rU^WXWPFB@-pfv8Jt)>Gb5*Cit65Pi#X#)=b;2iRUd!=_6eaU-!>`R~^s&g|c4sgLwe8<4%Fxt;0a zxq;MJ$~zFMk9K6qY|c5lAc{}gwVY{J@@(x|I1#Ka#b;|{WpjnfM-@S}$bP#L|?Ypp>r~Q1+ZR#-cZPeoPB%>l}Q3Gm!~~gJW|?wr1zN z;?)v0eeGs69GxCLv_HQqBv>moCc-h7+oMu@CVK~`jr#Lugrbn!6;NxvV{HSg^~S@i zMUuw(!$oYT|CU(C$I^s=U!o1tDGD2?Dd|RpMr+?0p$Gbw?8e(~-?q zIhY8UcPU!endx^aANx8N3vRve*vfm$$l5WxqYY_Bw{ELG*8c&F_S9~oQRalTCr~pq zSX}!$s!GW4<{@$`{V3rjyN(C$EnUU${c7il4|Ud_YTvLs|9JoVZfk?FvtlK!Ciq`` zix!Ue-A=*hCw~t$2rjvd+&9O=1wu1}`3xtTqC<~%UJ70F?NM}d5d}NfZzhW8@8t@@C2l)kNFHU6srZd3B$h82+Z?kYIYURLRX5sQh@E2IP9_2ak$62@%HJuTU z8WlP8T+hNw4fwo^DZiY+JqT=*Gn6kc!gDnXZ&?JtkcC$k!9^_Gipm^#6AMoPoTZ2G zXM&*ztmiY7&!A=wo_#Dl$K@M!fQ1)O3kSc0g?o^PgWt)*eW;y-$H2mksENgMBL|NI zJK!&-C6ls&98t852ay~ff(67o8mR?(S@GIQS?z;Oe^`N&;;GZkRd*-4x4--C=WD*4 z2z^X^y3y+E^<4oIF}dB_Mces6Q;E=IM;l1ni2YAt7A{8T(QRPhA{K5%I~U;iZ5A#? zD>(4CShyA~BXDB-6Ff}}o+N=s>uUlmF&9qgE;Do&Ipswx+={B4@-MJ(Jt}kHkF#*)qVjLCa4iF;+tq>XEZl*9us}b4 znT4xSj>WT#YGUCjRABMc=|7j@PZzHd0X1>TXHbE~(?acI;W?D!wD$lDF94jy&(g`_ zXUaQSxQ~=yO23?elT{3Xw=nHm#(}@Z!nJ5k9bS7K;4v0%L)%%o+)RmBxD{>X;CY*c zOKCW5BLn;{unt<-SYN|M!Wad#;ldgPIj#XwV%$RpquvznM#ZB$QtN|V7M*c6GTj*( zb?}!P1u~(-YqpyM{+_ZSW^JjO5Qdf8_H57i#*|L)wO74C&)7Va?yl0V+|f23OaJ36{Ytd;jC_-$ZO|@Ee6SB-JG85ZSRG^^N-$sGge;iP zdJ*kxKkG`ZWPqd;0@*b-MlVR((4(jwxx3NmC>Zw7wZmgu?Ri*kKlEm8b6UF4gMIBq*l@r7uwN~B!Iuo!lh^jD|y`V z9;SSlUJ;U!Tp@5F@2d^TL(4dDF#{I@{CpZe1DDp}^Zx+&CHMsvu4l?S0KOJK&cc-( z{1f;s7Oo|5LMOoOEZo8Sc4Gvh9h8WLThCJ7!}}V;2fAHO7VhJHvoV{X{rF`TE@$Yc z*R#7wyQ)mPK3~TVBj*^w-^Prb6)c}sgg@;Je||?x5`ky&Ua;-`P!qA_iN_P2bxDb_ zL#I(X(tKy_%F|Ytc(2W1D7&iP)zm(9=5;1Rp^8x0&QKU)DGV&Y(VL*N{?14Ox4Z`x zNO?OACq4Ckrl-EbaJX$z`2by>vtD*BUN4snqQ&hK6-vyi`M?3TWgQ*t$~iC`Y#J`B znMS$W-L4Umbwbw9gu@-o9PG1p<$Mp^A1}==9R?6bF=B zYR`~1`)^V}d*Cw%0nwa_=6TYO5Q@V8_ZZnH!xg)OjAmokvir*HA) z_I9AWf!UbGriO5t$wzAqVgwa>%?`jQ@~{6l#}@q1gy4HY+F7e^<_?VZ&_H!r%F^R* zioqUhQ(kjMyFGm7LEqWk9nJN7+^Ll98vqvBQG{8@?84|Qalr(WJtA}~5i+pbTrLKh z?a5bBZ0YkmQ5)bt8xl2l1a1HM+wFx>?Egbe z;O_O|o9#(DhX?Kaj^vy7$+00>bInaQFt@z>Mul;9`rcB7!!I*POzNjP`woWV$+IVY zN6IuDuy~#G)GC;jJ<{7IY36@)xG>0+y_%b$2_K2BLNYgu6yBRjx$+`09wBR)%0;8L z6jNA)4yb;{T5e5J4W9~A!+%FV+`~S(x?2R!@qnFy0c4Pw`TGQs+bL@9kpUg%QuQ|Q z>XXN&q>ztUiOfcjZ+c;zg{UsKwFSBk)U)letX7^gCCVJqc3sLsxZJUNGDUF~u;vj` zl!?cC+zOBFGh5!!fv||luYiPhsWmjf5bDh!efSg1acB$Np@CmFn{y@!$PygYi*&N52A-bi3>pb4iF0<0Z7j(BGe(XT) zZbNY0il-(qL#8`kDLq}aGBkvWM*D2WKJ(v(}RBz4edtY;b@y+ z*Y?61IDSsOwhYUOiIa$FC@)yF*S1iLJZIoDnpB@UluV6I8664*GgxlD?UMf(*#4L; z^p4HXum9i;csupauchNSb_R80lgq=w;ANzDsta5^GyQ}%Sh;}(TzYS&^&&vJ;AL&R zE{r|Tg>JdBe+%nW_akuCC(Nso!@Bc!r){`^2W;tmn7(0uuQ!(Tp(2_iD&*j6KraMt z@6!&oHS{#02ah>1$joDpz%AV>&+s+k zym~dFG;X#E;@75x`)>KeDbH4UyUMMEK#AZ_g-#qV)p^3=x7>VCkA@YRn}kAR@yiA8 z&PUGlOHm5GrA4{UbHTEzYco>Ndx!d28~BC<&czm6n{;_Q(5l${~a0gTu|@zz!_9R6qFgL(P}vrxz#zn-)LT^6e*aO6#naQ_JI>qOWcbaLgQ<|y3P`A{=@BYA2d?PS1 zO@Yf3>uKqC#pBx5d2IOUc7Jp8`vgwcRV)f zj@7R=gXa0xQaE*H?jWC2v|O081N|~8e+$u+M2=G6lYR@*|3KB3G`{b}Eb!j$MTm=W zs_Pv`T6&Y%CO4^u4YSrSThEU}S+L&=RYn1k#|7@_8I+1Nkyx1~9T+O8#^DMkf)%n)Ef}_wlnJZ-H0gdYAy_D|q#&hLu^x|A$1kMw@ zu&^cS`@u6&ZB)7cEZIMC;Jz08dBLG5z}LI14lF+dR1z&Sb0hR)8|`Gt)&ks>(MNTg z5%6GyX1q?+@vwoV-@2sIM!A|M}*wn#A|?ss)yoa>_Pc97{TAJRT>DK$qW3tFS56WSrd9l{#nhaW%T7%AX#!zg}Y zau&jiC}>>4?^=u9#iS^RV}URVt8jB!S523J>xyi%T-3l|OJTE#kyA@BltUQX(y`|D zdXJs3X`)@2XJ!C$Z;rL{ajFZCsko0Zo8FPGRpN$Hq>{%Im(xqV_ZZ zW_s@499?}9S&7jgAilI%574-UW3D#fm*e?y7@nmgq3B zjYmy45-}CWF!BH}$krPK*@efD{2D#r8I?Af5h*uHSqeA(`` zj+&;c(-Ap*glq1?7G>^<)Hkj5XDa6KIJer4CL3<|(=ODN>f~Y?Ez+lV4Rh4)yZx70 zO2kRae?li*A8>>QS6rvprM0Q~;4N;8K=htk{<&rj>Dh)!ME8?$dX#e9Vp5z9#b&kU zD7)Z8y8}CoxO!ScpxT?tS#T-}mL)A6P#m{H`O)dmU z=a4Zd+BB@A>P|1perEacP8|!bPKn2I`rj&y9m&jo&cdK|MN$ATL@#Rd%JjiLgt+&b z2=kuO)9g^S@2?*7G@ZW!Jp6(fr`a*F-zS&5=aYK!L#w=MfT6V*fKhMUgK1w&j6 zAwAQ7!%43blRSsgWBCCj_$t2#oWy4 z9DeYz^oX@4-sl}}$y@+!fBhT$Fyjg0F(dza`@VC)1NQ3xe8G@B)qRHs8ui=lyAyJG z9eI10^W+{=0?gL79opP18RBzoIbqCdvD--=Yw7gW+o~_YIrnmZ$qn-glF@RTRo(pr z{TEdFFY8VJK#&fx>}tko$GgDB>uYKY{snYG>y)iFoi9{%&mcGUFK8$kThOc;wQkI< z(gmXC4~i&R?rB>w5Al@s7!RO@e4_Qo*!x-JsJmZ9Z|wozyYwV=!EH#$i^2}_RhqML z@!AwMP$s&(AINsx{1duH8ng^pzL83Jz~3+kI0_|8D2>U=51r$RKUi>LG%Agie$8u0 z@4l+X%xg}dZWL(+!Js$(RI`POtl&Cd+lBFgDStcT8?&@YO7AclmM&m1{;iiK?83c5 zZa@-(vYN#w3$!#Uds{jT_xP&Sy}_W;X}B?3ed1_1k+o6DOs|b?BICDh1Qnf{eKI`d zh~qEE)yQFFx>EBk1DE5Ah6Kas z{N9n~fi^n>G`acO2#Y`PTw<0A84lX=xXI`Yxn6-W-4$t>S1C&sI;*4uQ9V@jzTV`J zEEs$FchY7?wE=rUuIcmjOL1L%JNem|)x_8NN{K{gSDi&; z&Wu)QVUB*|5+$M;5FW7L{lB!5n_QWZ6HJvz&K&5a@!0>ykJMeM;+@6nhsA_N7m}C=gB;;?t!)36p(%=?1+#io)%hWPAt~l#spML zlEqd-xiLCf@apSYs<1ory$!uuwRa>)5Gk69A@k#kXtjLBi_t1H8Fkuoqg6qCaaU3^ zR~}(nzK@5gc`t-&K7^Yww~glc&)i?Z+J}(c?(c?eO)byxdEo)HRW+=H326x#GfIj$ zD9#LIoVkOCNnHVQftO9W06z z#X(Rdg4@XlhXfw2hYm31d89`b>B{)#*2vAJ&HlVEF7K3pc4JBBnb|FGc%Isl%w; z-qy{l2NVZ*{O8b~5&HOU@U!n)h!}iMyn?qcHTZOd7|31Kc6LS1RCW5XlzKx(Cxa%f`sfGpo*S05gqz=JWWo2fk~|$bvS{b`aXHkG^yEd%3Ox*|#()`vKk9ld!)sRW=uHH; zGJUs3{y2wM41XTVRvbOGQTh$*e4R{$%82GgiCecWmIlC4kN_Y!)?e1ma$;E)wK*cy zw`gr?OG(f5T$Zvbdwq9CMErQk3^F}`7ex_8EQUS*)?AmeBEQagM@Im|v$nbo(rdLs z=+siZNf{3b@e)Yf#K4N+pp3-~M3+X%nOWTnJRl`Q1B&3+ZI?NzgUwbRk#1D!Hyfp+Pg*wg6g^<8FE z>(TgUyfWSo&ujF&A!KOTvIDS8IbGqe$9PY)nX$URP zxS2BakW8qb636&rF zTS-w6QdQFDpUbeOrHM0RnP~Sjd&Xo7+Z#Sz?~tuK!z+j%flgqiciq}MMn!drnTgp! zkAz#R@4-EFuHp%nU>u4Nh~Enkf=Y@QL29(nav}(nvVU-KX$&YS@aUXh2uwagu8i$) z)_4YM=>4bj^T&l{8izEY1FJF$b_S(xZZsSN;2XzKr>1n7SY4(XKBa}(3s=BoB6`Sw zNOH9NC{WL4_`MZY=wK$x^o1_o4^+CpS3T?hvG8cT34TO!w5m6tJ$E#;(+oNKXLw2A zSVib{)pH@{RvO2UR3)0;48K?rE-xIx}1YL{5xWm zP!WvLoz4@Mb0ccj0zS~t+U(h9(S&7u)*%US@7q3BRJt4W%*r%62@(A&g>{f$c2S~} zk9$@8fH>kQRhm}J;>r0hmPW`iYKA#6nM>-*oA3wo5L+0l*3(&MQ+~VtQx5e}V{siL zsQOl(tYbCVFEck$Oo)9BzXmyTJ3CEctq+~*mfj|8ba0Zk1|Mi^Or)Xf@fj~wv4)!K zF4-8p;rQ}mr6jkHTw9(a`FDgDLO6tNBG7B*W=89GH+GF9K);Y`X(Aw=G%MT;#9;E! zC5u3Lp;z=K%u@RC0J1yOko^s!;T^*=N!BQOWU@-8@CI+m+k@G8v9xnpk{uf{X>Oe{ zcR(ERIaj*TcVcjQ;Bm(=%|wem8sFS#d{pL|p5g)BDx^3;JG|zXdmvL5dqf<(eK$V- z#HFXGQH}d83@aGwXxFYpf^J~NN|mg2m=>+|VERWeB3Iv=T;kt(J(`V`U24`*b8le1 z9=VBQIQE{e9otK^v&yUZK&`V}E(Rtq2gk2x#p|K49_Y&U5bEP{hfLNo>Ul@k(*SJz zn%nu6O{c4k(etWKsL_qP6Z{Xh2nq(b-~49klSmx_Rs&}V>G1VPPp2Ib_u}D`7B{2O zAN7xSLA?Hy8*g8YY<2CE%2JYA0_J|iw=MiYRCt@FNJr^nd46m1*wRy&lQaiLu^I8m-Q=Zgzb*>!*^o(iDX++?&H#i}OrGjgHL# z>c-GcsQ1SA9Zz0ywJ)+B_%C)mB?8`Wxh;I;!W+O!i;F|pPgeO&SF}irkj7-wos2Gb zv{nL0l0ngQyx{2++Mp*P>;}yMOSMKfjdJXfcz#l4&`bW7`k744^9Dj}AE&^{chF2D z#YW47!O*??B6>Wg8`onX`-KUt^y4>z@9wz)b(MW!0c z5uKRP_{mHY`kRdYb>h^&COM$nJc2LpbsU)rk2qgQ7Ux^L?J1UkSvOlhu^W&Kxf&47 z{mtgx`49J0bzTR}Rca2en^145s}fgb+j_3^2GvpmZcKEDOW+)>GftiA5q0E0T3sYO zK_=QS)5w*7gX%4Nrq@)Y2DLEUkpq&p8V|pwpsi38YjP;ka(g4jKykn#S{?##j%e|a zvL$L))s7$LeEV0!*Q;6K4R*92#w$hV547&5s$VsDRTNa7A2UABolHRkebTIG;!)Y_ zDtGi&8znC0UY?mx-?)9Vo41osvxhs?L1Hei5z%D13j%exbqB|ZZ{iqlS{3}}DFW)oES-y>ePl3;d@~n@JdO>nE1MR?ZaT-7Be`!>P{W~ zr#rkMF3$9LA&)K2Rh4v_=anVUh^SMRLaq;-`bf>%epR3nDd`#8n~h$H*H9){E5KqD z=n~vJb9&FUjPJ`f{6)DaaEkPDc2b<}bK$bR)=!}|G1li|uX+7w3XM%` z6{EY0HO259Hwk0FZAx5B?a*)BGv2mN&aq}F8SP>IpK$Kt z&WW~gU~CUn!jX#we2ef7VrNR!2t(_T_TkN!Rmfd1%%Iv+=7wt%MS+S+(j`_3Ry}2% z7V3Gne~@~tCGiadm01tl2xSAZ|09nLq;c}4z|jhJVmA-K>r2m19w2{ z386q#0095JAAI8toQ>%NGpl(g++vq4;w>WV5Bso7m!0pT06$+Ilkgw&9xK`NW3 z1pzW0=LI1;pGT&?-8{BQh@xnQX^HC~|XJf^VEb-!c~xaq+P0Q3PquTPe(spvLV8?4$> z-x{>KxtTWHpin3ktAxuLk0_NZ6stw6IiIkYE$6F5tVZUmr%;q+n6_Y;n9Nh3qm2hH zrKgKgipfKc)2(vf(A3QnhEvroGmcc%EmR__WyK`##j5I;IjdR;O(Tx}a%04jZVx zrSd9k+OI>i%3UUG+%{e4p30s0U@atz!0|kbM~&n@Z_3Sbz4l7fbT5|Drk&5&^k?G@ zh(($7C)*(Hx}IpSwm)`@UEX-Fm(0 zb$dGIG{Tgry8Z*w4;+mK05CfDRoQ#xL8xm@f*eQreL|;{1kEI);@WfK?j-rNYjXK1OZI6xKdz#0#zd zj|iq_p+{l^TZ}?8rnRACzj0BgZ7I&0{#X_E8_a z+jueVV@NrV5hvZ-M74&8Ot!A0oOjBy+V?`ct`lJVw;{70^SbSeph@o~@|Z<)6Dl!{ z%wlGdGTEhZ<(^2DA|TZJn48aCvfkGz{O|j?U+xD9fd2M>pIVyDMvD&L#m9FR(9GTMw(aXg?=YbMrN4_B~Uuv)J-*o@Zje8BCG z6%dcgW^+1S50p@?{ASK_`jJE6Cbt0u008*7UXJ>ePn(Cv`17w(WV+ z4bS_2*hu$(Ln06a8j(`E4I-gXI0}(UwhJU8kwhwiQlTC6wjR(f@QAOpcc2!G#A-(c-m-2Zzotr=Ud|47Abpu6nDP9^kN894?3R$#&?p8tqPpi|KCgxLj_pyYnkPfm?qJ{$GmCPx1KvC&e4o zh(sb0XvC`7?vO}-BvOe~GMzCQO~z7*)pET-p-?GQ3zah*Q7Ki*Rf|+}JYlg|ES3vZ zvRrXFUCx$^)bf0R!C*024HwfLkV$1SSdIQ0xY1}dS`3#mU9eeg)>@2Ka(%$za5-G} z7c-pDX?5CN50-Ph;PH4op7)os-0*pQ-kuLu^bnAO!3+f4ck>9`e=T3XB)*=#H(vcG zF~6JL)6mvlg8yi)`+3HRuKQWa%C`GO&I|AB>HmYz5J=R*W%PSQ!jVWcqE+m7NFka>#sN--tUJjKrozQA`I9`oZbG_hwKGEIgMZe42 zDu)dKcxMf3J3Uakotkh$P;7XeD+e~G!v;jd+>z4thCFPLKR3;=iir*H&s>j7zTi&S zHhIb~ud>wq1IZAZ4Zwr(y=d#=_W|ID)(2ub<)0aU@3>j4o~jg8JJ?!L_0hXm;Y(I2 z=?FkoDgU@e@1O(6Ik;dp8105qi<%b6=lhOx!yLaBnV7>IX zbk5x1%~_FI$~F3-bqHL&!~MxaXDb;An)G#0#!;uUxLcOeWPnpPl)#i;ohYzS8~0^t z%~#|zwEK18Me$;)hUh*1>C$*&XW$EjoXjTxj_WQ$yNO0)Bn(1O0gT?gZm-*3z?0ps z9j&2#a$iX$maVWa@37Yg;=$l|KEjC{{&1<~;+_((#~v=|yMg-<=6W^0BoLmV55j?Z z_NWleNPpZM`u2VW7lC{Hr(8!j0+SF{fH}^NvW%HCwlB@5SGTt}L#mF_s_+pFF(SvAXakoGq-IQhrE+AQ$hStcYKg@A@x3tzw}|WkJU(k zN|=C3Q-FHq?*{ra#j7!t`9n9f3#P?G(%9%!lLml)Hqw`nC=%DRiU1r7dd)v- zw(I(%@$rG@_+k{a`7L6?3mhT~?%v*ZDdS9GK*FZ>bDlgWTGn9QR9!-G4507ogkCr3L`*=a)(I&f09!hYp; z7=G^AXj1y3+X7dTz>b|bSl9OT{>Pp$bP@Pr3vdLW21v`fuU%>9%jkY|CXd0Y(d^mIZDrd^@Z~LLQVGTvzsT6MFtm#dOGa<9K zKEYF)dm4PXj4LkXOdwYLX#waMElWTlYnxciE1qV(FjJ5Cm3@NOVWA97_+mg!KA=v) zJHj!NTN&q;fP-S0Oj?_>f=3Zig>><_urg`LI7t~JWQDY_iDH>_Bvn#dQ7u~!RLgUu z-R4)y83_w3H;5-!Qh3>bQ%*=oaiQg{UFjLP6G& z?4>9VS9%>T@jRcab`cTjY7A0I!Suq~@DB>j-jdLBOToxN4JH-tY3RF)!^j~GCQ*ip z6>@XuNDUIp>9)ur4odC!ekRcv`A|5cU57i!a6QK3} zVti-3@T?L8s}`>EF5d3|82em#m<@Jk2+FT*=D1p%%tJZ0a%4I5W8{Fk1<3=Z26s=L z9d$aGYA?f{q6>l7AT~!MuGbU)%CK3$vg!0s!n!$}i@E5`(1vZ#DRrVP-u~1RSl7d> zM4qe8qkoz<+&ly@$8@ojo^F8T6I#NOIJ;dXdyAR|$w`PkwYDpV+>R%bz|`6r1a}@Z zqTb}l6*H?P9je(yggvb`K`-o)H(+jDFr3qMbTB(zwglflq(%i_bEOzL8%DHo?B(}} zTL$+Ylw2mVqB(yzW8}8a?$CUud=n0+*qblkpGs3wVBd%;uu`F}bJd~;z}`*Ops3E_ z4+EBZZjP=X)dMphPoJ8RW%zNrg{93m{i0Yg%$X4AJ;gR8UNqSdWc#LbXulQ5<=vr# z%|zazq{P3SC7Tc&r$w76{~b6SXG=EK-%;Pm$-eUA9H|a}56Fl4Qtj=JRF4X>?*jNo z#rV!FVZO7cE8GvnaxBZ7DpRGD5Xv78$rwAKG58*3-|X;y_l`^MwoY$~A_vq6GQR-f1=lI+kpXSd26@H2uA54-)q&U)9rv zLaeeAUy#OOKkqFMva=6WGiCtb-*3Ww_XFpL3qlKVYJyrf90H zu5hxn+U*V}{SV717#Zmr>T9bU?CthPBRSwlVSWFGCI`kxru)Z2sMxN#$$Q5xBJNG~ z4G;3O|Ij-WWV6uM&pB%8ce%h*TPJ&wu)>XVP0a)(L}Y}d#N-4eL95wrddzyz{BKv} zePN@24dGSRmpIwlZH@=iLHAkN-&!0@jEzo?E3{3@&T^7OvB_K(tIyX<{lX>u8I*qV+~pMEL@KPo6YuK{NSugc4~QoWrZw_tPjGsE6hz2x-Q3Q^vx>2A-(QhtCUBaJv*? zn~WdA1k9;Pnp5y5(V``sXxK4>bL!AD!;|${f)F|P2yjAFS0U?%vWHpdtR;$I*{4ne z)jytP+Vq~0_PDOIhpcoD`&c;CQ*)tP$iqkG!lK<@qQYxVi zJEk5o@lbbHMr!ngN#)dMmH3kd9`iCUkTVE;bj!b2M0_kS*RAts1WJrHCGVRmOb)on z6*iAtFDV_?MXpZbbd_0zLW>=WM(jbDt|-wg{i4ia0prOAtDOY0pkl+?q74yFFqY3q zRpRP##AwBAoyBLovtJ|UyfN{-SyWI=PjQY|Q5-$?m(<|MWsZW;%B=GaZWZ>OiSuAx zINa96MjoHzx!8BE^6LH6z|{spvcuQ1e@VH~FNo!{#HC1QPbm1DzZT#vS;ogqVS!6) zt7K%xTx_&dWnEgftBIq(HG4AUdpLjmP#P7!&Wc;}%DyTGvIcDSV(p0*l@_q~`kGZ# zS4RRnbE;HNgB>=!Lj$kJTW;2E(rTe+D~rzvKj?Ur;i%w$%9l@3Q}@)Ti4F)3D=!nA zk{or?o>YLBkX3T;{CEkFSH?kl{QDx!|&2ccbuWH_KWnE+A8;`hsD>$31|MdC5;; zrB`R`>1Kaw`T}7^u79sna-EIx>Dkab0sJ?Shxpw=0N?T!E)nMd0RyGczg^5+KGv3M4jBAKa_!H?Wu*AJ+*D> zProWc>)_B;an69%5RKSoE>f%A^VVh%ICQRuDBXq08EQAt^7H!YEOx!!_0*Y=54lfM zTt5eI*p#H6gx*!9L)^_Muqlp%!>QFvCK$$X5<13?ujMs^oqB3 zu}GWrgnjk$zGwAl%)0Tssm))z1=h`ioHngahuY_T0o)-Y&QLNJsF^by-Pu1~6_x1= zE?wnW?qY7YJ=X_9JOgB&fisUVdS|FTD_)<)GwHS7)QfBn=5zE>n5nTQb)r=PE=D{` z)|el2r6c9;e{_dC?`V0WW^UCE-n*d6Z=tzSeL7 zP6aWJ)^Jf*r%})*1&w?d{{A|W#K zVL1t*nd%W%hOXN&vJZHHPF^i{v)f>@llBqme0zYQ^0iM>A9SVkR(Tu!+y`*i;%L;p zy?RGSyLGP`xmd%X+z1ieCJGP{036K)t*0ZWzFR}_wPiS+fkDRpiGk&x*)qTJ z<#Dw6syG@~Os0l7rfd?lj`7^ba}&;tQQfC{6XcCSu`Q3Gt^Ij(l?y)OLtmf3t#l6JYB|HBaUM1JQjI&KplR+C?C7UdXQ?!zNIb}Wpp3MF556PCg;_Mvu zNaN9uTVr}o>^8VrBWsylUM1Zy_^4WqU4L;Mmr53zw-2hG`x#S`e&56`KWp^a;hLEr~|XB76FhnOn4GIv@Joi2>(dJU{GO&aV< zeDmQYTT;D)~>l}qwAw!QAPc;R_X4u5(tqLl;}nKJra>eO>EOdyeW8 zTXPI@Q7{qPKs#J2K9PrBMcf5UVk(X zckm8W)d0A~03ON#V`m>j_P0(tqy%U=sSAmS;t}Imyy?6sV@cLyg21bws5rp^iPYbJ z(kI>;=UuY437v<49@4o9X@{^La*7V>ya^@^q7@RM)`_?ca@USN^*AoRbWBIV*$U=e zq*i~b3!WamWfsC&m(kW`x!ScQyv+Gd5O7P7nZ-)at#!)O+P#56!hNrLm7D=`gt%sH zb*l_|GH4ASK)+0! z=KQ`U->ZbLKa;2w>2))mzhe$+xitiRpw1jVM$SafIm=YIRI+e;)|+3j#+sLCLevqZ zTJUV*wz;5bD<=4Q@ujOE*pAuxGKC;`LwHlb_dg}~nLYwPs+)jpSUQqf?>mC&9m!LFB z)m>q&YxcnMQ1s|=(=%~z_qN4Fb_po|>c{J3Z?o%m{_-=pfYgyz6Li@N4d}0PA3&XC zlv$Bx5z4y2nu+KH2+dyZXVpC_+G75E7=VLW`nVbS9aBBs2 z0B9OZ00Vrhe1qfaO54h`AoDcT;5B=L1nd(+ ziq=FK5I2AjHGm;C05dh@O*Ld;HRN(NR~RmKE)cAYbdtC=#qqMaJp&Y zO4Dm?`?szF{8Ayq26JBOyyd$1#u@2WY1m`7?t&PZHp|M$l$(`K z$H%mOT*QMtMa|$;8#Mf0Mpru9z3cWw+8Zt3@yjQhm7p;St@Okq=_kehkDHV+EPmAf zo|*!$H<{+A(Fk?^M#mES_t`n8MdOf(>2-R>|N3}PIb|`sY$j(@+idFRwEJ#%ZFRLb zCQ0A8Dd*67P2S{W@1XkZ=;b;8(c$qSuc+$#}bHwG?2Oj@-bJ8il3?m zOGehD1fkn#E-N@!l#bu7I@A%1M>qq`Hw+zV$+|EzaNMS0T{f+$8!TocSnuAU4r=T=^lfcJ4%twab zxL4c{0|L1`3na+^N;<@1RXPll9@(_tIvv=_054e(b27|P9RRV+pPV{aQXM490FpYy z`|K?e!A2f@GQihK^rJ-z{H-zMlD`f z!V~pusdz;k{YG>CLcBH%yR0|ik#s(*yf@@gb$(;lwJqpA$27(b{cOvgZWH`v5crmW z6@KoU{){*o|Bnw0UKrV|4^nR7w}o{sp-<}jiS+i)5c7Lh<_Mn#U_ak8%F{}&`8OZ; z&%MR1oz2?<@}Zx$($IDFZgS=*5*gA4$Hga@#b>Wb_1?TBpj&9uu$tg?z3ja0&jSvY4 zs62#D0mQNqX_SN%0nAoD_+ub1W9BlVH~xr(-x@#Izfi{bPXbKY3sFX>kpXu0z)a#j za(1lP0HZy2c05^s?X@90YYIf}D0I6NYHW=D4s$I!8sG3l#UClPQ znlS8L(Kbk1(t9m&yO96*1biLbxog`7ejW0$>+24H7aX>0;0}TpGP>*Y3cwp2w`=qY zLdqzXq|YcFP);Aikp;)3PdXX6Mh|{Gz)c>)m=1qb2S6kbsGts!QU`%Hh@=iR;SSGG z7HIhzx>g%-R0m{92uD=_ckZDEI}0H*`F0+r!jFYLdSq7LaI&IH{&`sLD83tzS8kut_yd_3-%Gs z`!x!d%Vci7y==-9!PdV_-ZKkT7p5u_xI6aC_b9DFfxQi4+)ZTmbXn6C+w&mgPD1{A zb`U$2v>qNvY+7Aq))m_>fKflAnQS+ysj<}XEPA0^>AKC_|dK8oO&3V(P^6K*CE?-6U^yzu2-n z{Ep~7HS;WiSL=B8ed4>t&{D;V;y&>X!SznMZIHqn)A6w9IIdP7iBFJAdl{tK#k{Oh zWmPY2q!1(`y%Q(G_Oekjk1afrs~BwJe{`aL{5a>HW5D=MeSaeFhp27)_kaibM($Aa zgX)&)f$OPVqq;|bQEx!4DymkdIg{VFFg(*3Yth)$5Xu#Gk*2sS{L|1oRbCfr;x=MW zNu&oW&#tb#->f~N0#$zEI%-hzey9F`@fMirofu>msy8f8dgSWs?A&bJ!yMcwF&8NA zrM5o|0fir(JkU^SyhDZo8PhI2oDC(k-yQ>y*Z?Iulz|?Nl})LeMqg?bswLD$UuzYv zB@B0$2=jakxMcE}mbB2##MCWlYwSi~+;-M0;d)AIHOyIWHLfLy9AEkyfgNcFSzL}~ z;^{0~!R#S*CJ1^=PkPJ59`ub$qL!!|tA@~zMjM<>-;3#tW^o6qHK8}?k#@dwkN5En zbl-{b1G`@D{kwYS)l-fgrFO9RU-dA^1!>*IG4t{yX7Wtn1Lkl^s0!JiciuV1UAip| z1?h8O8K@;i)qO?fEQOpPOPD27H`9~N3>_1-!#~M%!!y2myS^00Pb=ateBXBdT00ub zeEbY2hLashd{F}*t~NVj-@Z&+BQHorHY3D;M_hTyrg63ocu}Naa<;Oz(g(qxhdrfK5wJ|G-<6T_wxKDHl=l`PWt%KrPqPE`? zA_NZ>f(LikL4(5pgS!QHcMtCFFu1!rfuMuC4{j6O-7e=n_r2eD|M~5wp4DBoYpQ1N z-rc==G5i1XY%(6ry7mBvkYDp9=$GWTu+s1TiuAO&WL&7ORV*<#R)dpxlDQEK;vZC>d88L{C(Q}YxjUJ&2-)Fl z)j*#Q&#LT>UI>?q1-0hWbTnK)GKSP2$ASD<+fK!+5+_#{KfU~Xphoh*oJ1j#FyTrN zR7*CocK!j6gZQpVl4Snf^H_ctR}E^7%w&3gM1r$sUwyr*%Y4E7 zCQ{$~yQ>0J9bpzaH$Q7+g>w4GLe;6Qt9UXq+$P}Jc*{WS(w!ZK3A^psKb_1B5GJ%` zkFc?2KZZI^S-$==vvv7=Ho>{_w#-CIw2SJX7svafXNRc9MP*h^F`dDuqBue;1o)M*EOiCBELd>OJM%+e)>r@JPsZ zaYsM%y(fPd4kyg)3x;~Q3LZOxdR=58y@)7gOem|f*MaicV7-B$kSM~0jd{)}E&97C z7ycz#I1Ao-?p@-|>7(&h0!& z5Njsx%^%l@Ad$@>VvdTD@RQdXvoUXZX$g}~becVNdG9#eA_`*g48tJFU7h|z;bnn! zO#35pKk)F-bU^&BqLT^Pu#5^R=+H!TBEyV6mH|GRu&$E@ar>8IusagR027@3i-vnbBoeu zA!^X5KD9F)rWNxvqgK8FAGqN=9@$ODKm*rLjTzVjpTp*_raY*;C7s#+aZ9Dlb@O+E zH{AtDQ`6?<9HU3QB{j`WbDHFHT8VUs1Ra@=6qiDierZPHxP>EP@6EC)-rbb_GN?LYv?)>jd%ZGZ0hd>B0x}r0D>oE=s3Z>Bgv(Er&9eP>OKVs*vDyxaS{#)|@HW;VxWO{X)pGmjwnF%i)N~8n94?-I_4v zY@5XhTHMXHf7JUBELP%@wx9e_m^*FiZhRXH48J3EbZI2Pb__Zy9%MOz6>vxQf+<%L zM^B613;ZFWT(Z>i6S_>YZ94br$5bwrpPxygc1)HM6;hIG^3SMdeZEXG8Qr6#(BopZ zTNwyUI~dh2?U2VyifA&H=iSNly2E=1Kd49rA=hYp24sH!V zpt~BnI{$vu3IrSQ;$raec-!ow|Lal1&e3+yLWu+mY-5?sx~7?l`!QqzPWT`i@90+* zmIkHWDNkVbU<~_vS@hDT$2Ic^Wn)RDXJbgGfmSrjc_(K35$KW0#O>mth2o!VQ*NrI zT&jB+Ts`f?39rZ7@ucPX9Ffj-W?7$QL3@^JXS}s@$(SOewQ;CAM}U7QnU` zT>=e2Cv>8gj542q@sO^UdPFJ$_;eOB2^)sp(X`HXwxJvQYi+JVu^}TJTxn4rkk+si zom|PzsK@&83x`M_>19*YkC`gK=XSBCs6SgC)9?LJc4-Y~sjYR!f64u@bA|+cZ|qdA zfdLOZOnY~%(HJ;^w@l?~?k*3Uw26SR58cKO5iSd4T{Ck(esW=bS+(-YdALw( zbz=3soc8yW**>fLR+(Bsl}Fc;)vMKCa0hlO?P(fU%J>A#6LUO_J|?lqY*MeY#hd(E zy0c`m>7ZXel!=dCv!qmM;K8iU$2=++Ox$^|}Mu$BKVt%EUL~P|ewk zsu;nLR-{z^9$VEpro(gP=&zpaaFyjfV}z3)IG5$Ol+4DO&dQOt!A_KVc&w6}TJLm( zJ6F+bdOpG2{f!?pC!{&#q{|)9s;fs@r{$J1+n5XZjA=_4moN0?@`xTO-}CTXn=t&L z&_pgO!DiDv_^mcu1)DZb)_$R*uXVEKk0mEW zUVsr)Q*g-6RpHA+>Q56xM5Ecj-;L&euTMmjhoAcziA4Ken9EO&YFjBeyUjAeo+U$f zkOJ`+m~v5W<-}D-y;caBtPmJVEzO?oPTUT%ckJi! zH}o6++EQt)`*?d?1|hw~pVQQ#c-%$SH#M&uR>A*df(mI8vj?=|&%PLBiPRdkh1F zEeyMdzE*Xx5*1T#C@dZw^*i*ur+0GGkB*2Yq60v4xBn6`rvLoH@t66DrVhLlN)60L z%w?C&C4Z#p85=J*Xy@O)aNWjGEl8PKTuTQ`yMsP=D_8v)C>c{QnhlI-f2|)Pt0%3Co{(xI-0)3nz7zXG&KQ1gi2Y=v{ zUhQ|Iu?f1wabXy^f{S}DD=GAmG=JofUPTs&|FFE!%a8jwk?h{6XwG+$7=#~AFK@5> z{p*F3?=-#KD+0d9#RuRKbJi1pURF8*yfU^3O~ndG_CT z*HbL*BQCcaPgBl&0;c9I=794QbPICPKrV~db%70id&eq%s25JiSz2t=lN5}~ClMF5 zy=iC(1U0-}4lQ&a2-bu^trx}5%w4pm2d)YvKs+VIpFC3d3LasL69prllPAfb!oCpq zz~Ykn6t1CSx)J?!m&{*~QO*mFolq+c#`hhj%*I;{&LcewB)NABJ>Q4pdzN7Y1)niA zJ6bvri8ir^4m$4!uE$ANZnz}3A*mX75C0f%f@vB}2-r4PO!6t2BdS|DneggLOhIS^ zTsCson(5oCzovc)^Fa)Qo*gT1=swM<5Ux)f4PB2hnlDU?Bu85YQ4}7q@Q)y4FDax1 zmQ&o5w}H97eB47&2C;Ovzf@q5$(U!Mr8%oX0_|5;yeoyS375Zp#3`+YpKP~L%VC5+pQ9O@TYOAwpISc#CXv17ZA5Y{*7gz1#|zc2tnt`5?xV@lNZ5SSARkF~ zLt@myx~y}yg16D&NCewR;@PdvsJvmgcRD{vlbCsEn;rqi-}AD#J>_B_h*Wv}j%W*c z;zEJ#D}XjToT43+b30Nqd82FGM4Z6txa*?zaKkq}o^CI7X_%Az`J9^EiH&CD3pa0g zc!cm_39VROqYb$x;+>nNS-``FFQiv)T>HZf=ImAGL|=#Qqc$LjyC_e`@lQVJdt|Y? zW}sGX*BN1FHDvl^{XspWZSnCaA7YjA?AM^LH0!ST@@jmLcu${eL6bx4VG>Vsu|xf( z<_`uMv-!GsG_DCksWfGJu8`!r)8Jc;tN9r}ben>afy0FF4{m{6N3Nf^3S+h@e<9YJ z$Z$(XO&+5x_)rvFPo7@d5Xi~fv8YQ|xY!3I^oP(_<^<@fSVv>!vxmYTt}xegYglsBf%(R?tl~Ruo9;5kRoi znzB_EtsIj#i8f!_H0B;meEuN4L(}K*6GvmwaS@`FCDE-otd&QdW@OY1Al8dPRBF4` zY`p$$;)2E$k+0dWr?hU!BL_`cCQ|t6sR>PKys@3SSG&?&QPS;Ii*~Vs=knjQ^ot2{ zM{OPC7K>ul(@nnkFo5$BFjAjR2-DaSA*ip0eJn~P32h}BOEGTD735xXT&OO6Jj_Z8 z+_LbYi*eAM;+wf}B66PcVU*v9FKqn|OZeZyf_}uR1aupM~C?s|l)3Ah8Tep!NQagK*DJq|dkyUI! zVXa>YdLn-RG8nUWc-nO3XkXA37aGj7lM`BA;JUHY8@v1Bn+y26Vr=cvbG==@eXCAb z92D|(i7I_Rbg!Upi(*P=)(?5f!ly7*Fi`it+w%VuTl78|eqgwq79rwv#G6>1c0;9L&vJ!+mc`eK z>HTRdH^P0We@jW5ftJy_V%}4QJU;b;$=6T77SCdGe%{9*wJeu&2>NnIVM3p zFJOQhM?H4HC`*pk#41jSuUkQ^Y(*{$f${9K^ih7ODHrxxfe(%mj>pP=vn`yR<@`#* zs6qtV648)6PaRG%8h+F+mw)wQU*uo3NcjZNC=XG#ajV=#lf=u}!q@4Vg zaF<=&>m|f6O#3nByBHPX65XTC!x0c1e+U%$q$YlnG|j^)nom(iM-7JqwzdzD3l($r zR&kVjsSGpf%?>t(k~rsx+u~#yUjNRh2!de&+Dfa za%K+e58U4sJsJa5w@M3)o1<)I1H!5*AlqTd%WxIAXwG@MZ+U2{-|B?otah{S@IK~6 zX@!H2JVZ23J;#;mdJ>IO3-w>emtraP)$PsL;*+&epY=@dIJT8w4n3&-Q5fZ{KF zj(NBbzhDSwp6*yX@A4VQEqQ%8Yx z*0^bBcb5=GpszG-)l)2XV~s1}PH%Qo29}ZgZ^`I;kPZ@*TXz#yve~S(1AgwIxGs=Z zHqgSyuhoZ}TIz)IMe(>x*Z&k@q?DG7o=zIv`@G9rSKv^FRUM$r6VSzAKZch$XNh9~ z_?&ed#^3i)%Ggmw%rw?rKfbY?LsP03@GD66uf472_sH62df+Zv1bJFd&+UQQbxd^@ zm+aqhM&Pt_7~H!kqnM)$K4qtnQ-gV8JHBZ+=YtE_AdQN%rJbivE8J35;t$x&Lb;D_ z|J)}r+H@sS9EojuwvNGsaZ;5m#;w(z^)33TXSYVfoz+8&HTU6E=O-hh-G~J)B~)H( z@j9_AjmyruHqheOQJe0A4wQ8=ryJR~cO7CMu``uiD6FdI`X>^8^zNH%vRUXr#JAI1 z4CAoJJLZ^S*AtSLEVPSa_Ry_Rd1d&iI(Dw;^AWfaa0>el-;{ICzHYN~bjFv7>pyT4 zj$!^yb(i2ywXOlW17ng2=GFb`i4k~{Xn(EJocB7uHi+On@zu>hggx-AVPgCXgYS%Lu*YsbOW6uIebP|_;a^9@R z`$ja#u_L4|pLx#&zHea9t+~g*DcM?;;V4f(uuJ+4>uk@*ltFc8IOm#4}GiO0sOk^vk36lv@ft7Ro0Ll5IE{>_8X9o21l_N_AUg# z*4tLwJhWA`uq4|4kU4O&uP>a(Rr1(Av!bIr?~1Xvt=-KUc8=;WloSNrp~4lFQrTPS z@f^iK`&dz|Rq(h7L7xpXu(Fbi@7P9J>Bc=nO^vWgs-XINYy{J~_p-TrW^~+o1F~Q%2|bDECy<^xvnxDl{vTile*na~Cw9 z$8pz=A%XRm-<=*|zCFdERN$|rrr68vQHlyq^#mWs73>mweO5C~HSgo`4m4uq1uAYa zmuxP|DiJ+{3@2EtJxvhYBjEw2Tr75hl-b5AdRX?q%q+{rEJr6G<;=sFd=OpzaaJ~h zjc+Nb25+DCgXb`;-Pc=c$WE(9KN$|x%`S1BwVsz|@i=_VC)?>L#0{)b1R!I0^u;qH zNsS+HsTfOxqM+1@W{APLYnpgmF{a6C(0^_jG_VT$KH@L3V?|{=ZWn96!~))otm4Z$ zoAOfCO_v^*QzAR=;Q2$Rr)ek{6^NN|2H@oAym;)OAp=hRmO&KDMqRCfD( zIO}P`_9PgWpP8pSD)!gTE9pQyoe(k1eP?7PLCV5gl6BD8FZA!87QEfaDPIAu9M(Td zqmFLOrUR_H6T{515=kW-U|$nI$z`bR;d0D5nkDs!oi`HBeiG5o`AjAR&s}vp-OP_2 z@0NE-v48iI15mG*SPPtFy=kMD@jdy_51=UqT~zLT*o6_OgSV=x z5zB+`K`j&ID}eNIgXvxz!i6bjrCi~6L)c;za$hK)`!QHHpKQQ61-`lY@1<*fNqnHq z@~(G0GwDkwOF!;ETD+%taTcbernsJw%7z1aKy5%qf`)=Nf>yXt!`HH;2jUw{i~J(* z(q~~yF1|5!6w|Z|9z2uECmpvuGyX@9M;o?BwOP%HSAWE3>_?lLOZpDy9+OYGzLxtF+t;vzun)`3GfX+mItgco=uy!<&4 z#rbfxe`8onykTtu_@bA>_g8(oSZk4<>+dmuWNEciG&`;#)`ZF>+6$&ET#!Z3bnpy2 zHr3kqJl1QpI9kx!=T844X~~r=YpBM}WlU36=eQiT4pOjOy}UNL$^LxYe3Zg|;k&vv zO?wOzJ=Hus(xY(NTo-mEL>Q}XZdz~TT0U*R6jVlfvZ6cHVm}Brd}Ylam>it@O3wT{ItgOedPN z-5~~3LszJ~Fx7%@>&$81ngexnGs@AFn#WmtdC*!ab;V+H3E_v1Z|nIAO^nF%;utrD z9_AtFrs%14o=2bv{Rzzjzd2{st;JnFfm3I^bN+)|;0U9AqMec@jklk7sdw607$95W znR4D3crCX2LK@i4VcW41l~R83;Jy&9(J?OD(?o~4!0RVoaC+uRp4LJP$yD()h2Ki! zdGWXg{m6MuEGTxI2rZ#@zqLyzU`swJ)r%>ad9QevdBYU%ngu8we*hRi5i#Ae7xR=S zE?jjTN`klx71)2PDm4#?RK<_#@g|>ZCl3AaWO6~9uV8DC`Bj`aqEfCR54cg$k(T<( zn>E8UqrR>b2j*tBty$pmqvJig>LS#0_H9Q!X}@}4yO}uV-y$2qqAAyPl-X3ut>UlI z$8S`CJE3wY2Lvhe(uts?%?E95a>53zJdLT7>Qf?Q9FpbE!@baB%CC!BM5AKiKOa;6 zbC51{Fx{BBYiE_+FhJWBw?i-bURUw?-h%`x@X}TTPiq6|8rV> zqGjC1r-rv;+OsB6h+_L~+jx?VF8wpk`MkpEZ20j`E4G9o&Ne)I$2RS&3KK|DtF`S= zb=}_jAg|@%Huka$F@{y{A1XXaVp+S|k=6t%bASJq_AIW2{b2>+=@gf>UA&cb=*$wQ zHaMdPjoBG zxZ%oovcAoCV%#M|-BnF94%{ME{NZy8{tCZ&`O+tIMiW(&zAZ$!!o4k3>8{|=l<<7x z8DPYLijR!$vg|H?<^OBQZw)aUm%zTef42o)Kc)AN*dEu6MTM1>t6bdQ@cHG@if67p zv9M80UD(60WC(LN{(Z~ei=rBdgpa845&M=GdC52cxxo%x-(HapiHCEpbHWK;vZhZW&vJ-EHM-U8ccpMu?EESr=NTH_c^a zeRJdP*)o_np=s<#_lI#r%k#PFmSKCo;U<-DDyu1kC~5=EQzwnruUY~G(9g4jfjY`0VIKHB*4JzYcq4c3e)9lvYN%s=mvne-;TZ=^1Z+JILPmsLKd`;DbZuYrYDd;8y8Zp4*-JTjDIiF57)xFT}FH6r3#vgmhwaI#yxk5Pi z^K7kC)AzLVbEudGY7vf7v^B8n?l|Z1yTa_O^)OKx6~nu7=vwD4&FkuJ7@gOYuBX#3 zLrN8TT(MjT_(4$3rx`}esH>sVnf)Sioc;Id;~3kdOyuizmsw-q@-6f*7pyj#1tZoY z`X8Pj;iHvzFa0~ut>hYdoH`V9Pw1pbPpYg$;Ww%;tM}L9M3Q3-YYCI@_WkpIW^bC) zR@o@^grLw4U300h$$oVn1$Z#Nqd&)(@rrj}IQf_tOC+kMcH6f&bv}Muw)xst*C?W{1#xz`%*}1|1u=_v`_q2DyDHSsyBHLxt=qyV4|)O zaoPO>t!!(beuw$pg#D*|bti@m<7D+YnP&{Zqp1tLT>b3u7;Aa0hk9wK7+iWCU4^4x z9y2tYk4QJ+i`LSa_>Ejo<8sb7LG#F(qYplT2iIu1fu;w75PF-Z_r#se}+v;WVs-;I}M4HKWCrahEm4#&K!3kSMXhgN1U z?h0+Iv2*H5Ozr4}rKo>SOF=SOqncomohpV4u(A4{m~I1;LF=2@UITgYzaxy=|!ws$aDJm!9((RB(#%qRGSi7J8kX4 zPTRWXF0Wpn*NEpum1HRov9t|qt>1JhoKy8CQ1ANP2`sJu+mZ{m{?Odq#I2r0vv6wEvxTY&?INSjx$huo_Bxsung_P0d z2J-?o1F!Dow<|g4WQ6Oz1`EEL`vN)Lc>_LEnf+}q8DH*npfpc-tcMOys#!El&`!{# zK)wy{y_3PS`0Ci<`KKYDJ8W}I)+V;x_v7^`zg$yUY z?i+5Z!CKLd{S*kP!~~u^LIJ*=!_^c|xL$nFpo!`dayjiP$PkLtK0`aagpf|GxLZu2 zmbB-w-&m~4wG^AynYLAb; zCq05{B4x-&T6`PR087PM;QHrmz9?1ZB2vbd4}UOtX0SH$Dh&VDWp8Nv8X~ndVI2tW zyeB41(XiRo;FSYZHoO!T*~;+}#i zFYV^_Jio-CV~sPis2raKO{2J9zz4p0;A_kFVKnntJJgkD{9Ga2J|Y39pF<=n9;Kh5 z%yg}?VF)Vb9@-|)Q#IAbdpKnzzs9}wNmm##eff_jU^U>itC@E>>FZUbhixT4pYI^@ z_UPhm{lqoLl)-3!y#d`sBG*DENW@eMub{}1&~n4ijp5)xNJn=N({dM>?(0l(A|h%t z!6MzT@AglRWk%B^arB`$r1DR69Fv*jWmn3}?^AQab<=@IK%`fGWBOS|$Lag?vs2fX z!2)d#c9rJfcFUciF|M^IcfGr|#1yxs>6a+G?ifmo6aGJMP|ov8;h-u%pM3qb^$HXW!Ek937|8wvBZQ9`0ZVaQ@(L) zh)YW=LP5oVvYlTQ#Q3#?c;ZI+%7kKv?vxMu)rrVL>>S{)W5Gu*-d)Y)uR1!0q4llS?ngax{x zk=IVp`}QSMd&BHH@$ln*lWU+)6zjVYO}XwwOGYN;s@lYF$IDI=u{XIV?X@dhx5Ydd zN9l#cU6|+LD5B z3yYG%Xb(IyaYxO`c-4j?6l-${PoBv*kW*0{qk|Dwn`KhgRUQ{+S|91n4r$c}kZ4mw zV4L`*(aW-dk#pqhqA+v>wW2W5-t>(Jv*_;KdGerAekS}>;+QbX;loJ>= zRW1#T+$y=;*lbT2I#B#D;QD`*UeRum=2A@{{=Sp>JJuykygw(YN5dK6Gky5;LAw6( z+xNyM(@-p}arx4wczs1H*Wg2N{2;y2c|EHV}5eF)zUVfbsdspe!_mX!g#ixHKJ z366^~my0PHz<}w-g!snT7j@@z^bU3O-nZyo?r7Kt&<^U!4&%ul(aEmB3G5xw4hhj7 zI?*l*5ey+~hbC(em*$#a;u4PO0)y!ivHAk9`tp}AuN_Gk19VWAR)##}})<~Ry0=(6|Y=7pVg z3nL$P7V1Qxns-UeRjojG@f~vZKJ*?#Z;#F^srtOJv)lDbXIBF-Kap%YaeevZ)iud< zA-%IU^5k%TOAELY@9MX`hCZWq&759%J_~fM6Q999llb-#UqhbkeW$Z6E^aSh^161I z9`RqAy0*3Q#9~#wa0H;6|j_~II<4{d9p#S)m?Yl98F_-Q|!ei1=Hj4SV~M~isM*PMVzN*3x`^fe!*}aBET%~X+D;L{ zT{k$gnF98pG;>YO!J`Il>xqj7b_PRZ%{bLMo=VW6db#px|3HHrkBkq>!8D1$2d~ta zKVFG3qz~VSMK0_G6qd4%5{Ax81){XGcQ1!-`#Vz=8)r<0y(|L-SVW8UWLQ$(9Ta*M zHZsrCRHD=p&R`(y6~~eyDT)vOv>yg)SYyJ(;A7r9pJodtWsvc;m70uPh8+s zNEmlQnixm+XNI@T<)S3H3n@i|Ho4*`rZcf=kyRmhy#wjOaJ)c}EXuUTYJ0l49_(;` z%R;~H9@L4%@6E*_O}svXR+O!IFE3t(It;wfgcl5Ayc%Oo;uj z2RDk4zUy;&)Tj`MBe!4{j^6fs3&3Wty(sHZV6K42=X(w%W)6_q;;-n2u0T=bL?zDq z$`}-w8NNBxzHOg#3)tAlQ^mO|sci^@e$+1RYzf47B8!CWakGGSl1sFN4u2E9?z+Gg zvQNLCjFJdusB1JTHAT%^iEd!qH^NyCLax&~;`{{7bfM}!0(eGm-qigb{_NSi_Os!) z@hQtdXCrZ{nU+5bM`8$~Nid{$dlYdZ2$o8y`Ud&A?oR;Miz*5u%mRZi$T)Bc zlEOu9$+43tbSC7f^AC#C7vdYPq|CKmLIp>cL3w{P}~aFDj0pKV}%XFNwTr%L8s05qD)|#OMOCI-wuG zLynX9j0G_KTKqu(6C?Ywdc1LombwO5p2CY)@$r6sTC;XuQ%h@JgV&O2t(zy*wE?u1 zSy}IvzfV8k-&VKQrok0;V6%D+LOWy<_!Arv)1dIcuSr8IkC+_Br1q6F{Y1whDKwM1 zA@f)={D_)2*?@QaZ9f92o^8paZCVX?fw6^yJ27os^?xX5GA8 zIXrF+oMCRgauFXYb)BrB(Gba)mZyQOjd8c$;(C`=uqX@o2%S<>C=X3BO{wmCYSjNW zs5Wa-OX}0VxVLf;m{wyE`E0RiAX93M#gpz#^SP;qH2&x^YI!*zyb-*S7Pa^`er6) z$&H0tajFsL8W65?E7Nm4zx}wZVW&5=Qh(8-pL>tGqJR~2p5o{_RfAuGKI;PJ!FwBy z*pxgTaAn=UIBnh8E{EGQ zXiI)Y&~DZZJJFSGl$Es<;jOkEwB&xZDUaekXmLF#3wba(1}`Dv()NT+H)}OL2&KYT5hxkFP6UNH2kO8GnbnHeqylWC3-8aOALbn`TOF{#A zm$`I8Mw(^(p50n_ixGtjovMDbh05)$g=)TT^Cvc0%dO4dqyBcaY+`HD zTuNJ})@fJH9@jWI(4nLy9%zrPvM0eYw`Pem6FKTL7izK7V77Vt0Cr>Vj!@%Z z>QMh)-4V9#uC@!`)$em&FAw4I=TN&O@2~A-hw1U@ zAT@*nql@D6OUccLCh;o$4jZDEb5P><@060a<(BT0%6GU2QiCCxY?nD*O0TnBCBBD( zD?OOr2!aMKX{q!063EdW4 z(l&X5uAqK|%#M>OZZSGp#j9drZd|opqLX!Q`_rbtc`Ql)zdz za(`^{YIOml0gwBjl|@P-BM2kQg<(t!pzEWLmnU)m$h}tyr+LDMgV%?yyLdVl{<^|0 zw|J(2{-j7;+LQ76YuNeo&PY`*R2NMUwF^$mqzNmafE$QKp)iW2LBci=X4N0v(}rwV z%kaLUq8)JY; zyIB!*sonsJ-$?9gk?~g|S8qa+z1%=X8^72fKpVf@fJ0-v*kDDgI@^#Y(%$MeCh`h^ zU*CDVR-A1hzS%#6;LG{k65!Xjy0!S+GT_(ux-I#*`vZ)Lz+2s{Xu7aBfG#$$(311p zZljoGgV>b0rGp%mx#fb8l+}xRXlS(yda!A=^LmVFy#f$z6BY!g0N{TRDLGHACa&MrQ-vrQF<@R|0hn3U}SKMA8Qmwxa5D5k8{${~+0s;>N_c(Z>in+Us)x9qs;$y*^!#6|9fwgqO0@ zaEq6;lV^AC?j&?Cn)_st>>9m#PU<*yBs%mcb&#k|J*qX@{4llYAkcYORZj9CF&Bh; zfG)!E?I1A&6uOU2$DdoE1oX&^0h#}GMz#1dN%M}sD2uA&GSmqq1!LI;GmjrSUGgk| zF~(@7*h5W1%^t=>O#;l)E#@f~*z*q>FgW*%(mIkluyyspl-nJ6*Jq72`{b75#uj8& z7a+ESCoTO5kET-75D(q_tks?0C4|Sd6TzBIQa{FasPeNKajz@nf@JY5CsY`-pTp#)TrPZ44RD%kv;sSEw{vqmaQ3Ohl0nv#xYAF#p zz+c>JzU|Bp`+b=Y6My#r3*@1cL#z|jltL^_)Ra;za`zNNOe_vk%+mfEYbhejVbjFd z2d`)h3iU5ik`k*A#ro713%n`8#({$6|q-gT^A{=#9kta_F!dflCbeaF0iV^)t9PoCE7E-)``U)dnA;1^r z-PM<+IEoTpDld~{K#QeRn2Ol1o%@E0|I4UQ990Q#6=yLHZw0ZqQkz5>*eH#X_pcPB zYGFBM7-Y$h^7OClrAYatU9|}@X6)37F+z9hdg-}R3y107{#LBgK^j%eZ&3Zu&@fIe zA9aY*7#?-V)HwM!P&QgOK%X$`5TRkiHiD_?-a{j|Xp|{yqcmiVk!BQ&@~L&`dj@h{ z|92>I-F6eJ6mi0peS*M^U`~w4Luzh}`Ga~+jL-vjP7Iv)(F_F6n_v?10)J&MNz8V| zB1?>P#Ue=zf2EKUL-XJUBv!hbk|Tb9RV)23@E^5i18=_>B?}!OvyOas{*-1I8*#-l zL3r86B1cf)r$800u~mWzA+Q`(8sO6#z3dmMbCdiUGqi=S0ge?5pieiN`W`{4!9JKL z^)=;RpwyYg|F5r9XBOK}qrpD3mH2-(9Kw<rr49``DqaB{1nnftb5ikcKl*IyXcGcyaQ1%_pRFQnuY3#a=fZdEp$bv zzaU}YlEqQ{2My9VdyF@*U}#YOr|84z<0O+s9mwOU;vSKOiS_*jF0SJ8V+g#pbN&}A zuxR)d`z&6E6??ybk;ThsClSp{c~x2jODo1wnXVjeyv$yjh?lgLuF63x#&v9=9B#inTat)3S1Mju zQmhgMtd+xmbShEE{4kp*UN~C<;-Gzt43@}70nZiii5trmT<1#g=#pkj1PIHDL*T&-ZNY&{q zivm^BMk2)w!v=`%MpMN?rw_yo03k~W8I0TOmWDTS-)!h4SyAQd7LD!JgE+G z%qk|&zkaTq+?vv-#{C@_cqnj^ei(_R^!$gm+0`To`nafKb2>`fEWu(QzEqt0R(+>1 z6|28NL58=VFDDfgzEqTo8V>kZ?dPQuh40TASkTuWW30>@Scp1ap+i@qzdCxEWI%cA z$Bw;^IGZ6H_Ek%;^siOsyXja94fe8+X+btImPB@AoC^eYvQ!IB<}9mDGll(5Y@n2{ zGnM_bZp9(4JdLS%*G?8J91KO`KcJd2Q3281CEH|Q+Xxx{%*--_gUw5R zh|sY&NQxk_J7otCn44t<2mc#5nVIB6shpW)M!_~S3kv>fZszx|$Bi;JGx-H&Y-;kK ze*wV5%gt5z4?Kmr6nJxi z{M#UuMpnkKk6l~_CzM7`hAY(EKeeupT}Vd5ApLt0JxeCl8)UyIC8tt`(n!l-_9c=P zAs7s!zZnjFi4^~8jF}HC#*L|nT*j^Yd~Yxpjwqd+`M__yZ|B%CA zwh;CPA(3*TQ&n@bsNnyglKN&!iD3kWAr-pRp$#|D%P3aOyd zI>;vlFrv$c{R%%)GRl_z7o?9^OE8Q#6b}oC-O$ucP~6Zc%Eft<%_wX&#p43TH)#gh#y71SqL~r8n6<=x zr1=9rSdR*!{V%wWrlF87f>#HlSvAaR@g6U(a~ny@_IRCKioQ&`^O`5(x?_XdxMPd= ze{1Ck12lie@2ZX*$Lq-2h_i9tW|uJOwfBs2BX^3VCYW!?UHqdD{$!d9-y-*=N;emY zO^)GC)!WlH&OL2tgk3;n!}x|#>6YGkLgALrnMwYZ)RyVoC8il*z988SS&XdpbQ;@F zcf4j*!&H-K;TfJ|$*aO}PAeS2;uje=Hpw#H1DIr)?tL`T-PvKKVzOt2?ch<}{!N*( zjq&uX7@=`ZvkkK)^TOYSep_;=+m+GMU*?(NOmzt`S4(pVGG~)%A8){$sbaDISC{{L zIh29^Tt+FokD9UaH%Va6$Xg;GE8?EtSR{<*;C2Zyl#OoW zZknhSfZPD)VT%Hg2LemGBUA_;L3?j4<^M6EF!gN18G?+xMV9C>e%s>7UG)q@o#;lu z{J%m1Fu$jsVrU)h{GTBFS8Too2>-XmzfCzuYB?d%4i#gyj1ZImI_g9_bIyc?eg&E`^P@Efp8Ipiwc zEg0l2vow)r(-$^vYY#cwqw6gbbS{rHe=hK~b1pUhsd8t;7Nres=*y;9rnfKpIf5aF z=s|CvzcGNoiX}sxY8U^BAMXhGoYiqU^hoF~NPg;h;iEQfJ9I}FwwCZ0TGv6<+H8Ci z`~TGSol#9TUAqq=s8mrvI!Kk?q&Jb?rPqKEdKC!0iAXP@Lx6~M=^g2v&_M_-ARvSm zs&o(}C;GhS``+{8WKH($Ywv6CHET`Q-1o|wncZ+`;~$f=k~S`()54Y(S#(mRw~{=v zq~mAE;ik5kf-!;vPJET=L^h9W`Dj+m9PWdZWj`7n@AcpnE?C7*aKMke!Vqh_?Zbfx{@YPhf@6h@@$8luG`qQ+l)rZEn=#k&i zSK}kUZEwAAy@z%zkawAvz>hbOrR`|d+oK5oTl39e+bw?>Uve${-9RsnvTY^PX@$B*Dz>H^h8Ko^oen!=UuNg-NNpjj}6uLUSF({Gt-TnAvAF zrL^^yDE@5jY%cNa%HfhsCEKmYr^qMV!H^u86~xrR+rbN(z9|o0eP=_`c&p9bRk4ud+O%4NYLF|@1&JRgA6(vpCdjzmNU4>$#P4AhG-)tYC6=j`0SkAN zb}35z3$vcj%ISbH|V5R{dx1C8(LyiLu z+@p9IXfo08!9fg;SG=jtnb|ai0kP_%5RCFKfeZuY>@cJNjAFo7Ir$$pw*V$f?w>$! z+FA36h79#-7nN4^X>ObFghPKEnP=iJP67On{#Q0dS;nKkz^YI0z^mnD79$i&VetVk$* zWgdzvPm2*|m3x}l%cVsUgzFaT7QLf>rpSXlT%pgdeK~#|P(ao83;Uz_fllbiW zHK7QRI$cERyU>k;?E|#d2`VeQD_Q;PkX|y1%-TO~v}@Y-CVdoR;^aZA3REVda3Kc2 z6D*-x)jxC{tOA#RTMU;_AEHN8i^G0$7`|u8J^WevQomESG+Bo;nE2SyAPq%`B3x^7 zx#so>EgC*0^a*A8YS5y;DDF1x6mCv^#(_G=^Y0ibdh4JV6lTfNXF$;et1;x;Z&m9_ zwyb`;&^S^9{%E(1pU!Oh+*qZKEV(jb?PoJYgXs{q%;(|(ui11&cxe10n=NG5>?7UI zeYw=ABabPJx0dH}uxmhaD&5=%m;2B!YJHo-QI!y3A+RiU6H0GyK&J1QdlkJ{5?t0{ z7+kb)(`eze8NX_OYv5iDQ7s3M9w<)%maaOuaMB6X!i$L1sEz$+u2ST^?zq$@WX2%s!Q8@6e?se>1 z;o~O{QIG4A5<{pX2nS(Q)U?6`)N0P4S~lYF2YqsDmf;Vqp1UZk>F)QyXA|OtlPK$o zemSefSr2J=J6;BmRua1lChf_|!X}c{v- z^=-xaxh93c8Lo7^sbIEE*A`RBpTWq&OX|yJ+c|{|f@L$WXJY!LBl8s7tjOzn2E&)Rr zOZgk-iD9uNYcfK`|3owWjfQD_nLqrA&pPAu)Uih*H&m?gEzrUv-h!{vJli1F`-)}$ z3I|^1W^(R)KDr|7bDMCpB?Ou$y;-yBdb@4WbXx7JaW=QrwWTo?aDy)Ey;Q(i@F=<| z#Hnz?GOhZR9n+nKcV+y{=#i;q`4!!-Jd40@4-I$F?Y_`L`K-gR>9% z9dFfmjpp%%&pwcKd@g-fv4cbHFRROI~;1ccDZIkS}S^zBv;6|pTHfuwKj13_$C+zS4;#a&}Tp;rROLPosx z=JDqOdpL79;B%_f4EAbSKbBRSPW-?OG@tu3M@MT1iud?0TJvh=Vv^jmUdqQ9g*OMZ z!s6AxF9YT_@#X+-z{~Ut+@`IdIJQF%(d~e>8{$Ai#x@1W8684ldI#GfRk@(^!bf#KpsPBJXWN7S9 zSZJ8Lj|;3$XG`WvwvJ{l=L4jmr0rUL3Ktdpyr<5VT?7*{m=Ow|@fjO)LKwL$*1XQT z%Pm4&mF3<}LmFoOW(F8}9T|~b!d-1S-yX3%WV*)tA-!#myRE}W9D1~!|C?rUIOXCU z;t*QnCMO}>0AxFujp;CHH01PlnB|GzpN{!W>E{!viZbq0lWS{m&d}UwJJWx>m`ipe zSSQ1IVP_wrc<5|6);g!5i#ee_r=juk_YvuB7wIiH_4Y>1?~~8w^&>R?s^g8)9q)ww zjZ#*);No3U@LEGtNZ|ombN-#;lFYPd&eR3?C6S#F(f0S}Ed@TJN36r92YonDv>I){ z0&PDhZNCt0KMO{2LEC8b>udCLYVyM<-37CB_FRp=f1KcLPs%O;2}oPj}fRv<_wvRyk8v zW;0f1a4WNEtM=&&i@6JnssENBvsqC4^q*!12er?E%;rJgzk$BbfWA*}bWQn~jk-0X zg_}#xn}t~$$qEga8aoP`;%1ssOu}a_5*JBJ2~}JklvXk{PEsCFE8b*Hby_!QQMwQp z1ohg>iJQvW35hSM*^TZvOF;E^oQa_tQ;5U~?{A3vP?v)GN8&dhCOY%$aiKyeXOVx! za&bKe^si6=HN{Ryf37Ej9u(G#|CjiGC@B-Wpr-#37bH*zoe$(tjcMc9iF7!k4Rk>V z9iKwHgbskxr;OF@DE}%5NvI8o9B!;=$NyJBaAC~CY8dbM^#2$!iXbNFKU@UC|4mW< z$4KyR9FI8XH{+xUJdixg%php#)6CN#x1Mc@d<6g_(JeS}+dS`?0+l#|cMB4+~Bf4hf&u_GmN{1&>UhuWrY$C0~(V(Nb1AMtk!-<`W&rpsq^ZCyY6Q&+GlJAX{PHcaOAwOu?PYv8OUUpC%RJ;#~U znjflB@F8#glv|Z?N?mB8HBp^*8YI>=aXNQ+>A;5a35ZPopvS4wSf@AY<9e4z_3{K$ z{Ae*lf&u+4@f|l}F4+Yxes26ogjWr(C&Mp>v`|?kCbekD`X?*;&G_kINoyvvAy z(~qmq4oAB}LYiglO}g0kL^eA|;vS8NIZ>KcTKS3uQj=C1*f+iw(P90rT>7z#D1=si z&8@e677zXSP7Hm^Yq??_9x{6L<>jf@Z!JEuI}wZJ{A>=vV&3fvkTalU%w!_XFwGEW z)1&SC-JPx7&#qT+SxS0sMK%VWksTvqQY+kjpGd#GN%C;+lh8RQEJ>n_;DvpTg8 zQgP4u<_Z-X0STSB>J-63wqwueSQ8x9cSr`=*F{xnq)x-tzVr9d(t8ZXvG=k35>=$H zKjT-TKRt7QFKzW}Xa~sz&V*u_PAd%}i`U%Y$IYd1rATS=or1OFDavfoeF5bZSrY<* z0R|_ELgW#h^M3-BzlxCIp%4rx`8Af=s2;0VJW#fC1f@g&3OAVFQO>=Rr{KIL8pY+Mxz>+b*f1{rb% zhW!7vJPISAV75%e3fs3ylp?4LmzB0m-xZtW# zT9btp5=`4Brphi7B>(Y6{6Wt#Mgi;pHR|9ZU<~YG6;^*ub@Bg8P8Jvv#-u6y9b#~J zPsNpqpnInw!mnY>+13`ZXOn7ZD=s@h+G#C{YUcw&DDS#D4Y8M3p_D8eey{0BJQ5On z5IrAL$m|}3m~Y4@%|mI`b7;BB-whyoeNBFe6 z@day@O%pNdwLncCrqcY0X`Z(f6*QfoeC#WUCb$>u(A z$nKDzM@CrbU@s?^UDR@wr=JC;S8NZcC@29)9iSX6v>p@zM}j1SDR`h!^on|oN3O%g zF)SPg+O;NJ^V>xcOC%Dt7I`yx?g+JmH$<~WDJEPdN>lzZbA}C}`9(3pZyNNbaAVRr z7GF(8^bRc4tu54z9{aRCsp?<7c5J5V3YMC4kzf9`I|ud(&~c2IU-P=X)!+gQ(pmw0 zqJ)6;E3sYMH*3GI%B2bDVMpi}fuvpA$b~u*L84+);rX(bxp9U}Sp-4Z>O^>?O^EXXFYwJ0?IY->?)9*fN))Bcwro7>&k zaB50l4$a!e3${T~zl;=QPRK2HD1WZ9P`?0iamIN^vM8?LJKw=DN>Ds%fU zp<^oaV*_8aI496DMJGG;KPmU$d3;PM$e}@Qh_bN-Z*83BiXqlE^fmwehwR-64coS; z*yylsj^yw#r6!O2Nxss#TgTlA40tn7x72mAa2Gvz!E5Y40=%)4haUeL)vYq$*cCA3 zeRob{xZNy1I;(3YH9SjM#pCW3Q=Vc5J$Z=c2e?h0-v@l%Y1NqLZgquweX7C-K}+`T z0iL1!bE-sk{3EM4K~jqIWUX`sdw2lw)PFNtU(W+UfV@5a)~avk6aY84S4Nc*2wJ>H z0+@uKQvs^s=L7&PxKN3c?0ilY4#2aO93-VS|Dj3@fZw_W;@-)EdqrY^&yLAAjPfsG z9A)zDJP`vXryD;zY0k_2FB1nqjByH;?76q{OnYTjZKM3bRg?fjRMwPN8b&#S3l;2P zw^mJKIu3wft90QW(>7sur zkI&BpT8tALWz~YxiinY~X$`wSzmL9`PF9m2M0QZV`})mC=0Nze@zqdepxPC6MEFmE zaLg6!&w9r&pPb8r(U1eqG?R2YD-|d9{2VQPr01`*l|-MmgFT1@WPam}Cna|y_nh|m z(a}SkE~NF`wjWDy?(DYrz_#7Mwk1n2{mi!cfE{4i4lrd0VE5*&7yJ8_sT1>-sY9TP zM}vPg?y{Me2XCud7=Bida1JK&Xi{Tr-`e-f`@Sd}$|!i;cJtAP(p5mI9c?~{tCj>j*4vfx zQhQZmLZO$q1~K|Dr5+1+y_YAdWt;l63)wm+9EzTVO8rq3<+}U=d}Rrhp{(i3cnSTP z8XnFCDJb=VaQ6xuNg(PCH@iVik`0#)*6D1EF%s-O{y}nV&m!skcTMJFSS$5Bp@o@=-IH;pR{1qb)w=r=Od5($o^sFk z?yH=8>P5q(2BjwG{vmFe)cqlJ?5jp9xkh{L&Xi=jUOY2SO&|V_^>`14!-Fs8Qxx{R zjqxFZR#RZe{j4)cKCkt)7sWbVr0BT*k1P=2?x9{lF~2XD%%J5pd)tpP|EhpP%lSlP z(uU}yLfDKOF=XLspa^|vFm1>?o3FH^Ep4um9NL3QkKzNp=ZLkBG^Zvb-^dVGsje3+ z;J1@nQ2cn3>+4WMtUP4dr37GW4#*W`xM;Z~;O#dCmoZ*MUO&jWE)UQnbAL4Bqq4|} z`%$q!nB;>u)}BJT^pTIp%7Asp&5)l~(s@xmg{(N;eVD)XtG>oJKi%%w;`N2D?vMo+?a&; zb!~%K~2MFLD zWExJgtVb}Dy?^nv<%jXzkHZd)TyTrSxAs0KGDF4&^?xVa< zYX#-WS8~p4f=m6{F?xQZ!u7M}shy+f{QW7H+vweq&BLIm%ay~R0pRhXr#^`d%7Us? z^wjXuOkX}tX4WvRDJuV4)QebN(O%Wd;vt=j#jSt?Yfe0A2M%Y?Bq#NS6AXuDrto{RXDL2_q%AbZmP1?&A9ldn- zvbKrTxqvf2=cXDf$rp6wPNN)4Hd%w=?i@HNb+SIQi2fAxV67(v&#x z2QAAwUl?g=I=k1~+^l4F{^D6ab9FF36PX}({ca|0=7`3lfh&p|m4r%3JN#_pp?h<6 z5q?~T++xx{AzIz0Ucq|XH~k3D0UCZ0OPq$qU##ghGbZG<$$j6~IXVBX7ghHjT=REE zVXsVesxq+8vHTPSruedBW?T_7{onH~qXL z9Gi-<;{$yR-ha6aeRt>|aZsgtPeI#}bnpfIV}i!8d3vJUY{5uj^J*R!UF#(&nfn}O zmS_38dLUh`MKNzCXr&TbYVG5yPYMjnt*Dx7lD;;~bN%%I^ z{@IFpkjU zq&_wBgaE5DcZ{ddrf%p#EWbAveUGpv1AtvKW9&lw6WnhQnKb0;K5$->5$+pb4unoqXAqw>HrajeN8;*F5c+-)KKG~yJ0vs9mF8) zHjzq{(_lTdPxKu~U!+90=`2T#D-bixWlN~>5fLgS7KQeZv|D%@w4p2ez+WJ0O5Ku3 z%}7m<#M_#eXe%VA8{%D+dyfNCVt$`e7w;x zA*M_Xuha2Pl-l@5EZ_1?drvll-7t#>)H#j6rTn|aU7IDaeON;C6XRs^v!T%qp%YfW z$oA^I=cMO!Nt44O8%ihH4bn8>C`tJc*-OKx*nhC+qsS z5$I;;$veL|Ne%OFD|2;IK56Z;E38LJ#KUYGo+o721_7d!CqWD{DXT-d)4!x3-1s&v z6)xbH4L1_QbRO?%o(~SQdl)$Sk9ED`Npad>MR4>9JoiZtP@FE==Os=MJaHnpaZCI<9IzpG^5{AzP@$7WCaQQon6)cOrijp2z?2*_T26_9rQY#Sy1HB% zMy26L9$7g|&xXm4-^jhJ(G(u7`EGv5bD0r2TCkyVyix4?gUc_pUEQ3?E!k)2W`pUZ z)K`FtxSe4&$)b>u(bJ}ApYg#EKPuz7sN6(~+6G69tnjEeWs1b%chcDVJ{dP7VVhl> z+9&t@vLuzv?~A@iob0vF zOY_p)glMMO1Zh0Yk`c_+4KMR>T*eZunmou5_(7xsK@zDVP{e|Y_Aoxo0d~r+H~Mo% zBp+oTAMVooM7_hb$)9mKkLTa1i1YxC`mo*&*O>k|_qS=^4zQSSJ~v`aS{gwSu+)d^H$yKUJUYNspYryWDSOzCOBLEIjuW)dG0 zLO%TH5xs|5`4*mY&Ni(yxlosjxUWs8If=L~w_N_1O0nZL@9?`^gJ-zO1pj{Y5bsfJ zR7|v*vZ~7H(8w_73l8@3FJ+}p_KpsFJG&@q3M$I%%q)nhk%{rr!XiRKR9p=G^gglj zpR$zQL;=2k7f?WxOPes(J)B46jOxt~lk(+bNjNpz??)#yt0i%0v=Tt-tVfeLwL0&G z$B=UB=c~8irIr2vYSChaMG#Q)JB~F!N-0*)=69NCe}hlXZQNuvo8?6l+e8vN4@kY);1BmIQ{4UmKvwi5LgRU=-^Q$s_XEjC-Fr(aOuQ&d)&d)h6 z(V_#6J~`dLAO2C{=a?sN``L(-Tl@J$0Da)uu$@KV`M3`j$z=OuBy`d$$go;C+_Pce>4(6zUa9d0|8CFs_Z&oXLIVN&nfN1WZ{yj1Hn*@+#Q zKqKM4JJy1qQDxTVzBkeF0Q~9pY}75}_MG=|U@mzAk#8>96{B{7ncoT73%x?4XdRmo z{V#e&Ch;a-+P}MKJ^#sKG0uPYDMjkksmcZUwd&79>Tj#W)CkMg-dnai(6t_$pEBOj zO*4)fPN+lY8H-P5-vHCItTIZA&|)o)5dSseEk_#**irrYoeZ~y;I#mHRxEp+*xJP( zc?4}?;_?YeY3Y2@+fAu5(ONP1%egzkxgX}-TkH&*bMD)6?n!sHX-qe+tm7IyspyWW z=pU)*EvtYnR`l&w^kh}AJXB8^&p(XrCYA{F-iBCpvB;bnfkVZ%vd;>@p_IuGCb5_T zu?V180#YpWsaSN1Sh%iOJX|bHP%O4yEYed9eA@CJza=WRrQhFipsBa!Qp1ki)<)RY zj%dr8XUmpu%Z9li6MRiM@zC<~N8dPG0wATGi>7h5FDqXXj!|N`QKo`X>VQ#}jZqGZ zQF2j*hNDV+{KCiag%6br5eEyQ(1mcMXlROPI9xQWUNrKw`E5`zS1J0 zV$84CYc%ydlwB))CIgK)Q)!G?UamUk`OQ%P!!2Em(7A0#w`kC9!1g8YrzP|e%9z5X z1k^vNwL|ZgCT%;7Fuz(2F}zlS(ug0dp3VWw?r0|k?{B8loiwz+s2*)QsSSL@NTHHM zMVUnFM-qOYRF+-umC%eVQ^P9>kSs4jH(y*2^H{eeR}Y7CxA1-+Nlq`0Ss$%r9NV#^ z`M}cE<6PYxyZ7vnPsWgJ1*3TGg;<~{nA$hW@JcjyyF4(P{=}2)-079BqyKnWi_mLi zLt^?j4-*9^2W*#Omxh#!Z^7d7N~rtLVowmn^_xqp5_pHQBcFIL_E#s{r&aui9Uq+C zxcZ4;z5DiDy_&H6eP=Eh4{Uwkk*miQmb~xEH9!ZO-gn^YGl$jfyKoIk!%p^{D!PMV zG5c;6{aCOO8vBY~Sy&m3a|P@+>y<+1!S{4=})tLJ;(!7k*jVZuVq6te2+&!Jn6@wn+llS)r9)0K6@}9Hvvjs9< ztT7*Eu|1%!xmRER&jph75W>brUB~EI!$9=o zg~94YttBJ-V5g#1?e7cLYlWNylZys`)N_`kqYs1DeCH^lpUDS3ihF(l88Rx9!sko) zbQOey$eD$J2T)(XzIN`R8k>AVQ1`Xhc{q!}P6c<#l%&auTd{^zu3|o)K!_Ze`EArr z;+{45)t7T-9OAnkiT%qW#ukbH^*M<_E%jKv2Qz5QIe zVO9i7N#ihE?GrXq`1+j!H}eCQ0-E#;Ye@REfrtL~?$eW2!*AK|KX_BE_Q@ZG@?sw% z62y~GILWd>RMr-c;LI0Aq*<$9yxsNoc#sW@JA{nCs{$OI^4{YF>!TrqGj_r zSK-YKWG4M>jsp6cy{jTGNxVq&h2m)PU#0#cY46b)mtt f7WG97r8^C<#}#z-`S23!^JU{=fAN_v-4v@4O diff --git a/src/librustdoc/html/static/SourceSerifPro-It.ttf.woff b/src/librustdoc/html/static/SourceSerifPro-It.ttf.woff deleted file mode 100644 index a287bbe6ed3f871376686682bb455d71a13882b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36200 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 z 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

=K7)cy&MM-4KyhJcQOumB9&yWI zax21{n5>+m#p zo^s^v+eG`FlFy(AVX$g@E2Jeqie3jfv0W=mQKE;TPip@ZdLs;QZ=(Jay0=@X|2`qa z20yKgU+G5&L-?rT8N6qrxk*0Gb}`PHs&0oC$zMdThbGBq(Q6eyie9JqchNnH--+&0 z{9W{B$Vxtg9+cZ#8qss;hB;1HC)USPwSBkJPaeHj@d$dq+&|ztsQqhm=t&4xT+3(^ z=xMlHa&|q~F4jLP++gj|b?{YfZ-pkw=g^bjk^Crn9k|4k#~dC1dn7;-><9qyePpaT zi4sl`yv-hVvE{cYEfzogG#^dTKy7wItV{0>#c9HJ!?IlI>ka>tTrs@v#^Lq87gO-x zOX7Q$(1dLuFc4Z2-(IAV+s?t#`@@~k*mZj8*;A%Bb(dc2GoODf1%4;&XX!JLZlCn| z`(lqdE_?#2{=f-ME7z=9NrS$S9KN+ zAHI0nf$38ZOdmLt-WNv#9Ydu*8(7-gnd=^)N#Wla?9bo+u1 zj%${aMGv#U)QI&yTm%zm%dKIMk=Y> zC3H)xjSidxsJ~>((-n^uBO*D{ejweI0?w-WZ zNWJUa-F9ndrYV;4M+c4U@@TXtogeIK_vVNDUOeqIJ_U`Zkaufu5C=&sS9r^DBgs%; zS9)*4(tL1XI9Yqc%dYo@=Uks%u`s7xF4OI$S?ZbYv%L6Be3h7PRXj|7z`Xn}OG#U{ zpnK?N{W{*>P}=J}(ZhTc#w5>>r@03!=Q7eQ&SlQ3ZiiOMXVGgREctiQJ&>0CPIMRO zlE01agSh1HqBrw9LZF`3R>3Pwb-Qh0Rqf|zyIUeD>G`{m8LFQ3*1X*zEUC2)`xYHH z`;8-g5l33D%yh7Z&f^j-i~gtq&vC}1!+8U=t;<+AJ!(&)9|X~ z?CN%f*z-NuKW&e$L%wQzD?}xqLr+3X@}uZ=kdnrE6vtC1=Ealp{FB%##`CD;v*@*O zr{v#7_rM)h`?12M!tEO2-Y@#^mHfNt9*9Uji(aevQ|OHlGQCt{$$4}g?kxX6-L724 z5I%>V1h3>r(Z$`JnVIMP7-IYu$!E}me=0Yl`J~UnX&N+L>PVcn)x+Isr%`GyH zdLzL)6+-kXp(6irR2&l*V4H}HR(vQyVx!(U+t#y1u5p=+5{25Mv2|$Ga#UEP4Hidz z=j_uOw7oI1wc8vDbipE5e};$cZtKj-Aub{?08(0RLyIHZ92j%kOByeUDf|t9 z#)3tpvB_+DSn%6K-uS%FX;3IMB+4)rT8uJalR+rdC|qm0b4}ENyd4DUT0d&daoycf zALj^t{7U4PEiK>+fp_H8GJ!Ghj(+q}E0Zs~ELVG`*;#5@smyWm6`*zKgq-ABoTK<- z*G@z3X8scD2f+Ik0rgss#=^*zYW%$FqnB6ztikr?%BU0umC-WYk3W3jHDst?bE{R) zf?93(4{G)C;{Bi3^xx|PwS|wZ_P^gfPQZx+z=<^<&xwD(1O2B=__$v7Z!qBB?SRYc zPg54?i=V~!f!6JzAa0;FF!^TVO6u=#dLu71UZFCLy?epi<=;sEvE|@imH6qvM{>of#cnD$SbFS|l9PJxX`OWsC%^H@EeScV;^=O04 z#@c_o)26J~)13^DS}iH`HI35Q8;PcKK})9Q;Pdq+sYc>Wr6$weTYVU#$Y`*0xWAZP z5z>Tht`=uvzC|7kD!TV(wNaz|p-`*UG3obqg{>w>k+nJ@u(Z$OLzIfFqbC#-29Rm4 zg(WLb4A8}{yu+SzxpHgYIh;Ora7PAh}(^%%Zp`Ra1cr4X)so^AJQYFA&4&_#GAC%Lxv3*WHc==B=?!#=cK z%FX>JbPCWz{~-4q-2(Km2=2)W&)-4`0`$ng*n2-be+FLy_m3WB?}KpvG)e!(_t^Uk zr2ip#{w1b??Y{0zN#m}p~s@F%}|SnF#I2 zYqQXXulh&)2CvruKWK*pG83M^0JM@7*7>F&gpe2vGWDBtZiFsg^~~asY0s(=UCDvQIszl^vGdE7eoXiH9L`*iYr{}11XiTD^GkL z(4Vdx%BVB0j2gYRW3u)p3YB-%PJQ7U-}puj-CWy?{E&h4(dR%`U66;6dn~nXVL(k34qp6ZXJta{W}`<*P7+H}^_)w%rDZfh{l+4NNs{vb;)tm8!KNDG&lYU16A^B{bDn2X10pL?}6!+4RLVFx_6;gd@ zc<{(U$z>NPGUK_KY<{kN({A+Ka8FPu6Yk$Va>a&w&awMrS8h)yrrRp(vR5zZ9uhlF zHtC)U{&#iH_thCI+wcD%{=O<>BV8YqkJA;=>Y@J!N9}HROv|uJAkbl{Jyr^_dSJYW zy6f7<7fI{71H1Y_A9#X!eQ$6#r+r*N*$dc8Dao3tW3&yu%$f)U|0=P1rc|7-ROWj; zC6}}4^%kA3k_TH`4$RH%FO~Ms%^hf|y}o8X7~C?mW=klvg+gRUk*{N8L+>neFNA|H zDQJYQCbr`m^s9p8+WVGF$6GR1lgALp!alfX@jw4weZP%&Fx}u0 z`WPM|U1e8y_pVB1Pj~m8sZf{S*AWVJ`21a=k75$1ov;5eF10_epc~rxBJ`UaaA`?7 zzeRL&0lt0&RQgV+oBa*ttiW~UTnLQ@d%If_a;I7?F&k7Ck)UmDdd(_be5jz$T2Zyb z-Q{i>Pvr76uhZ+&C_z83s#+7tN>m-vPt@l~8~_b%!C=8jOw|T_eGMDn{t8SM?m6uQ_g^HD6f30v3VHq|@|@EXaQ|iUJPz&f0>S?k>as;kc`v1z zE{gg5MLJi+$b{Wmtvk#ZBQD*Uxw$q^>rgN_(&~kNGPUl^Zi}V+%yl#SIxObSeMdWQ zJa^M&6F%R>Wt+~uv9r-4m*YD>%3hvT`y#QIr?NiJcbj~k^QBAn^4@>jUJkkj`dNFa z)PTKotLygCw|YohcB1i)=%jDO1+DGF#9q2`-LB0e(aDp>^exUMdwK8wyS-G1OlFlu zsMrSfvbQoabd0_19cAt1{=Q13igDKIROvg~*AC`a8&tDh`PGZ|a%E@d*rL6>>tpQY zo)@2g{`nlby|xvlmh9zi|G(|!K)Bgn{;+d%k+YX;2S+EtUX~{wk?rE_@Fn1 zRt_AwP;&4>Rc36_R{mnFFDTYZ&f2}=>dp5bwEH86PD&=%R;qKk>wr&V3-3^`QU@t1 z7dPZ;d!s!RvcpFnw%NmByDiM}RIuQrUWBwd;Aw-7fPZPR%ZsJyq#`q_@#!=Uhr*^6 z@NKPI2Q+T;V9}=XY0W;FTI*R@sF#WUf&=JfK)aI?u)hEY{Kvpw0XRud=b&6a3#Z^I zijr9-FXL$v3tj>EeuVFXI+&N&f^LkE)v5e1i{Edt_<53v z?y_FK{c`wkb=jd*z?z_bg#L(y=$Al6g_QFalyh&r94(8R6Im_!E|4{F0K9Ig9HpdQ z4!*Zh(9ynS1!1ZaWN3n%)1?`fJ`j(MoUG7 z?82zkYH^PCCl;%QURm#yNpz+{*ya>7cDY8I*7`Jz$f9LTLfTzk0ks7xl4w2X4k2Pk zgWCyRZvkER*6Bh`wWYHKVkWuT3WZH;0fliINtXz7Do;Sz5-)20Cdv$U#c`C8eOuAz zscZ4CC=JJR1!fyGP6H*gMhjmg#8RIW3q^b@{*~ROOy=UUzCKwzmsFB=Wb>mI$nQtL zB~tTSvO*J4KJ+!}n-Iy-HqF;0m8i!seExQy)*DmX7?snaw8#|L5M9w_wAeC1v(~G% z+r&~gV9@}U`#CHp=o9z*D}JpvuCf`_9G2@N;~W;9r;Y_^1X|G5fW?n~&(a9r->=W{ z0r-9b{{w;lp#fi*r|ze2#4Ln5dQTmK_7li!ECeXCQ)xt_r`Vl2>cfxBpPqZpc;k)f z2XYTs?tcJMn5i_iP*0&{r)n1hX_5jx#U^>+ekh4xc@EO}5m^-i-_H;VATN5F!2d$v ze*rjYE$S7dLRN}~QX#?<{NpQ~oelU)4Y*4mL=UhJ2%P3M!ST-*;po}s^tS^X%H`5y z0eZWx8xS9K#tm3VbcP0UhN+j42z`~+XoaTUbW60WD+-^N+tcYvC7o`s`>KzlmnaHy zzeQ2C-%<$rcomiLpDATMy2A+T-HlP;Bi61K^GRE`o@8$6vLeHZE3aM2Y<~Un%U|Ej zti1M0G8zndX)bS;j6snu0glJRADef6VI%V3?^9ZCMq~3X+n#)W8^TYVis0|mConqv z=GdplLh|axoo{wr+#wH*93k^67dBEquVc_cJ~Brk%dI)g2m~*)7%*n@qigC2Ixbp5 z02~Jj%8)+_`E$ey66Vzj(Jh%kjwY71Bvr7zsMnA8#VpyFA(~1>4Y8~x);F%#7ZDDM z5qy^4sX{$Y1l}b92_N}FeOF#!JE#dxli$BiNZ-?@e_41LP6iNCbRD%?g zYuMxZq)O7LBo#`2I050HDDJnk_lF4qt_Vv&heTRs35Yrg0il6*i!VVWeFLJ=yI24+ z9wQRIfm$HijDKxz;Nw+7ilN()T17mU_|>KJM{|#PC38)j-~&LaQb{;LG5jJ_mGi z_O6*wLZBV9Bzx*Qfl#|dC3z8o$}$2WEzKHBTC>4m)|QM}k(95HTjUCvENd+4Oa_BV zS2SiNv`ApY&*{y|SWJh`S{_(PdGxIX(><202rQT6|tDotS407 zL8zSnXetHA02vnA@UV}e{Xeb`Un**bNNJ%UqB9Caw4}L;GTFaZWoI&KvBZ+DB}i5g zjVY6iNg0bmLY~Z6XF|F?7_6j@X9^h&z7;(VUR0GDCwy5Pe)7AyJs}Otz4*o50u5=- zn`bLrApFsiAqp1e4-iF!gzkv6t~CojJv-Q>0q=GOQ1LE$k=pBGd#(- zLkX)P+7?@ph~zyT;aXN^Q>$b8aNK0GyJGf;qi$u+!(nbuay4nBhLR>)ALv%2*4YcY z$8Xs3)GR^>Phf=i)cmOHjN#GKs$|9NLnEIW8NPK4tRxM3;w}6lzK_IPD#wm#fEZ5~>eA8COQ)tT8Oy9Yym8}g>(<@2apU22XrI)fl1AxV2fSxz zW(v-n4M(I3i>xp_fX3&p8XmrCZtn8Ifh*>A-8wmW>#kjgSFSvq;|uyWShKS&EweeP zdPBdEKeb}TB*j}sb&4Hd_bt&(nv6MS2UxmcGCUrA{aA^Dr*S&L{zZy`dLXqy_G@?c z4ZBCGs_Iu;H@Hl>c+|8=BhVXMd3e_%shIL~mt7_IW}(X^Ksow>R3I8<=|pYl^Z0v& z&Niy&-{7yFliLQJxrVV5vb~a{xg$0djSa=%e{?A3DXh)q*A@zE^My5elvc~NYFf;5 zD6I1~+XipYVDSq@Yvgi+2Jt`8ow;myCS+jB7MxXCW z-zLpmU}wNx`w>P0>=w0z4ux7o__k-BvC@CwS*^UUzVhP30;^T^HX}{QTLMs1m)YxP_CXaeoDqm0+}B**Kz}MBBJ|GhC{AybZ;A3<-BkX;(Q1 zGRP7y2prvkP*&#ED+xlOl z;jY1F<_z|~Xq1I5ze;#~v9_M#Nh>oZqpJ36UnsR><=XSQJNI6{V&cF=&|x>|#*chr z?#{D&SKYL^e@C~o9*4Xi>h%jOz-DTYTXph2zJj7jOgmHX&;?H}Lp~WHH!XvFJOz*N z{=>S%JFRQC>DF$yBrJ#FGqY8h3|J6=yw-@Y1yVqL{g{pW@->}6p+}A&3u?$@nnH}h#jYMYq z2WBIzPVGeZpccB7l91RVckGOC>`L+UKh})UR;QqLL}jz7P(Z+@PD1J~pvVrXbH_#* z8%7uIGy43xXf)^%$b}N2Mq!lmCUPA`ODUH57P==r6B+dTg9rs|dSfPC4cc;T;Y2Us zU#xM8#1>D8UAPojRSND5-2zd=UeKMAhdh%lR>QIJB#g$U6&C81gePNdWPN?k=;fcZ1>JFh#P8U=euvkM0(XxUyT@R5A8&l6$dfKs(KlkrM8GsYu%)wm!%%tm5Z|U+ z)8ZiGw?)#*IZ6oFwH^{d+FuNH`Ie}tn;U~8X&CC(Si=K{NW%;fOL^G4gzV;<>Vmn zi-t%p7Y9i|nr?Iz%O4Js0>}`$h2;+iDH6%KWYxlL)Jy0|mOmUM2#|XSB+Nm&7XC)vL9Ju?!$CX?7gM(rNVHK?>Rr@> z57qgzFh%%t6t&>%SpIO3BtW`I8V7+i=W=ooC!`r7xm+A10cpB1+ZJvPk^;yOW^3x< zAVq?iP2+7!(@8MXdn|1l`e^1mHcAaaf7X-++RWWIK?pFd7;4J5UyS+avp)X9mE!23OKZs zrGAFy^06sa3o;%(@fjL#3eIoz^(RW*E$*?-M@l5e!MusOz@T`DA6T(7Lty zaOs?EuDW6ckegoD(YZd&Qp&5{zGiCW421};GXNK0LS(mDHMgBQ*;$hOqOl;q_JvXj z_3(p=>(`2$PSM&=V`evtNa)->bYu3)%x5SL*G|Bthnpq@q>Tt#)TKBy2l>St+MWP> zeLVasVHVWE>l#_{b@;G2WnZBO6yqP)a5a%d+K-0$xi?U*kVwsZ~W>9Er2?N~k4 z>$2f#my3U$FTc6Fb93Idaa6u${rXwSB^-@^02(bE_PVEtuieXD!W5EkAP-W;QJ~RVuUck_-3RO)CCh72;!(zN>$WjS$*Ypu6AE))UFT^ zE~`}`&^R~(N#pbRmahVVt)GeB*tO-NB=i-*oz*Q%ReSPD_!gh>bAhwbvbzAUd`U`3 zRWqn7EU0~@RC=uC8tgsL$XvS{@|e**I171s00 zbAA55+fbPvsy&Oci!8I$9!Kr9*I1E3lL8W>N1sK{09GBrnhP9z&ZT4TFM5s?!PVm8W`A^ZutFY0j+BChSwZ8ApwboenDsXSM_Vz9&!Jw zsYg7PN*+J&ZT0SNG)9;6>xIY~LbH#fIr`x=H=kHZB6269KQR)c<35Q=DS_ZvTQ?mU zik+Y`9kY3%H^k$)C6d0JC^uVOtk?gbyP;k}vM(N23tukNd^RO_DBNO=U(7_a$=YAP zHZ+-Pad;&9vfknLiS=Ty-(3EBi4NYDbPdzaV#?Dh5hg+dBB#jg9&=f5;d%~f`NOCT zwGTJmRhGvqP8_Z<9F8V^-bf@p+3qeF_))ph>WO=ufkJAg+udvAMdd07`liEbcW8}F zDUz?MmDBw)m&NK;>uvc+wyIXG8x{)L^3~9q7ZK}2Y3pGcPUt*BH6QKZhvXZoPgmE& z1|g@PK2f`y5I#N8p!{jbY2x}kw+_25yxgF0&h}Wfn9LPAK2@CQ>03*B`O^cH>dMVLd0_ z2RT3LWE%AA>x;WQJ9oJE<-S-Poo#!xvTlSWMO?cGyYJ%KYz}ZV&WWV!TdHe4onb!8 z|MdxVL{R(EUq1&;X06>eak>?4X62jnL%!LPu7e zT&|QlbXF(d9CrG%@m{50Yw^f65}rY6=ZgkP#oSk&TBX^nvP=9%^hbwM&SH#Jo+suh+$@DE@QilTFpp$0LJ$xJa`i*;^n@BAw~Y_c z259$qxe(y*Oy*9OGbw9!q&MQ!2N|8;;ELn^$yJfC*eXW*1Xer$F#|I;)0fq#?^mg_ z?3f~y1S`Htq~^pYKr&ok|8}U@5_d;b8hLlRcPc&@PWJExRu#kN%keX9?Ugo@Q5sH8 zkLHGgS-;(Av+~%Q*Z}_lsELg7F6y*Gj=XT6Xj?Yua`Q}p(RsCDmoIsbP@lBB+XBH3 zza^~A?U7_~Z!)J-sqXh?Ur#U=&tSPU=w%EC*_zeHB^D@=)TjzI5>qZxCn0w@yt{d- zl4ntie$A2>oNiKut^KQ_{gKij#xLV?+#S`ZHJ$jGXp2_ua@Ss5J(eC054K7)qEf-c z$b$*CuNpx5eDt-X93r|Oy3hr}LC-vt$>sSbi#BaE`S?h$Rv48Ml}Ii}Gt=lPyIuST zpCHp})~U1_6{Ay0L~>1QEc|;mf}%w#v=aZBobA~C(PumQn|I3MgxOENmo~~GNp82f zKr6Z&xAl};+(VKMMNe5_k;)AAo=S1es*z5sTc^>Rat8}VtEbeusz*akE<^EaGoXaPPIpJTIy3B{hQ+J=7O1fGdX%5#Qod*g${>k@QB!c zbEu!=4OPcTeH}11M`{U<#hjB(sTuI%RzYvcz)iZjalp{)mfv$X%g$3o&(6mGCuuZm zV@4D^!d^s;(Id&+yi{Z=Ih--li2Lqg3%oVrGHQ7ee&dGGJ|=FoL5thrbbB0ideBus zj}7QKPFkAFM>w8{{ZEoHhf^Rm*?FnZQfkPH_){Twn8hx7fyG|(SSj3i+XTLt*%n^x zLV;tP!N=AnqLD-*5*moZz-4$K9v{TdT-05yc6W7nf`hr-P#`$OPUQ!j3{s(eB$DL; zdO0?+c!h-PORVCyvD2e?#AWas!ai4g%Y)h67Kw;SIou`hcroY4J$+fN=3a011-o5> zPGTufm@S@x(&Vbx4Ry_?Lgzwhvc{}OqDt993*2kYGQC}xPdJ#MK_4fSi; zU98Sq6;_^6t2gj;77==?!S?Y`TxHN18NSNLkQo#%XaNmi4FcB1GYXG)^q@jZj^0)F zloHu65*Y~q@>0Xbi*k{IM_dBo;S=E~|MUcDOAMuSkyXib68cYMM% zvthubfjaERf2eb&j;dj}gaLw*y*=NiW#WeLc0pvbB-0U1g}32fJsGo`G+z=~WP;k8 z61%Xyv(WxokyQ#fDfAgMjekXazUI>inZk<~22Zi?58jm->%-rKFh}hV$i(*gC%-|} z^IpCjqXYv>CW?^(+Ov$MIZyGo(*XEQ zStM1-4FiUcq-BLwt&j;#x=QOu(1Ix+x(|8qeO!FLX={k)xwp5&5>YSv$qo%=;e&n% z1I(<5WWC^0^!B!tdx-x>orGS&0l+oX=zE+w$uDS*|n~-9EKWr}nvx2BqArGsIh3;s&i*q0}4QUbPMl zq}tn4>9)4CGp8dt0Pgd8A-$fY*X5j!Jp7mx1eeFdK2a%50LruNm07qN{Sb6n0(`PI ziehs9r42d!{w9b%crtCEe)#3ys1 z?pYq+q)@xXGPzMI*fP9n)wWbVS$Hp(ik45?idR&fmSBNLqxX5%nW5BJnqIqBFxH|{ zS%P_*M(<$H#>&9FcsmkDGrHf3%IKJhl3!(N|u_$1)OTwUgCPcjU62v6BUt?jAU~DqKIy>(BeW z!2r!ewbO9WD=&5O5pQC%3|%7KLLp)+e~b^Yqk$PRk21iXDR=yd^PJFuat2p~tVr?X zTIg-lGD~u*5FbrpnOkocDP($4yei{=OS^WLI-8yhp(ozJ%ofR6GX+EPvaELWO$xYC6C!edNd$7k0lhvhS>cC;QI5 z_D*!yT?p-{{d^ljH>CU1$RG{`B=FKKm9odX{v}QKq>Tx)G#Hecl18?;KQ4RL+~{Vg>9#c+;&@+GgJ`LHj~<|F_`5V8ULIMVBp+tvUWN{MG?~GOZ zb%8u{D?3=@SSJH6mPFa@_t2nv8WkX0Z21F3RJ0JPatmp=xJFeS%x~t>XtuFNNw{1nzz37gP9bWW1-=P;JM}Nx*a2M4iXIXBw z6Opoymo@TDq%BbtZr_3BqKP)X@OY8q;ctJP=A(xnl~q9M%(I}u0-B7dBe@8aYZ+mTO4F1}7?cIJ6_J42I*8b)E3iS6aTWX@9^c$J(%$LN$KRzrE z24#=H%|HI}g#646!S3#EiYB|+z77<*sR$>TX~F>o_B2U?;{dIvMn2QsqP0WXE8^ne_Jsf_+u*=`zz5YW;b75uWq=CAELP`YOT-zh67IfJyf_CeOgoHW(4CZn;> zX2K%BS#WZucDb0W*p|W?nAbp-+sIx{4Iw5nT`#|RGAB!dU`d`c&0Q6hHk_wx%_I2B zx9Kk0*f%YPE~&LjAsWH&npOYm_w1wJ{|Z*m36x^eKaI3#z5KjW(o#kyGfLB^oIg<1 zYOH}Q-aMC<8f7v@nqCj>on|{^X@L0K@bzb+T^q4f?$ks0G_6_`<_hd53kEj1uXXkgs6Zymhd~9P;DF~6TYKZ3&6Y#0*E1gYI zyhT|~K)$fuoftXUslE^x9M9F2+_%QX3yM`oX>AY z+Y43Y&3B`_?nLNTDY`|~4btA0O$!wwohF@XUlRE=U(8FZ-Kw<8p{o7F^l}Iq#D@SQr8 zX+x$jZ7X?#VIDslv{0BzFI~DG0=_VVcZ+J4o`BQUq)lm18q#^lw zu};%4Mbnidow;n+-ffBpuUUWXw0PYbG*BS&j?mGs(kWtg2Jja2$btV-;}*?-vGd&) z-Y5GGgvop~&eC{*CyVBU8#m!di-T@Wj#WB^KlzEEQkp@RT%@z`#wP?_1OBKcF{N-D z<7sI^>PY$hXsRuni6+x&b=;Q8j4PzY{1xH=PhfH1 zX+xA1XaBH&tUNXipXU*B+rtX2&~LQ$&4WS1T>rm{vQUm@4X|ttIqCI;z{Q^5==Jza zFb6+DJE7C3w`beJDp)w$E9X|ooI$K=UXFB~AP=%bg zP6-2uIpjb;a+pl`Hq*jF;~5s<2Px|Kd#Y#Q53~{T2JnMu4@JSRjWRAwQ9^7(FVt4o zQ}Fge3O|PR^(>r@5qKBmlyW&QAUW+6A~{{?Ns^)kQfRpp8|x_+{y|bW&<{xppoZ3Q zDXt(XoRo{h@ia-%0Vxz*itQYZ1(L$arD%f`PA zOH#B#3U@OOphL-}_$5iv4k;X5ihU%7n^JKpUL`43LJA3&Vw9xtQZ_Ed_iC%ji2x($ zecVA->=Eg$Pci+|^Ut?E|NO`=OF#Qr>6i79$QXJbZDre&UDA!-ud!=^V5RyU#xwOXks^QdO^iESk)B zeIhcP?wAWi)+VEU!SD!N`@^%TXm1Ghrz+uSy1&pHj;00*;dI+cnTg~;qFRiMq_g92 z)lrCyux;16@HV`mT|>#KXk*t*jx+(&aQB&P7Rd7-b7zBQ&J!zMkk{@5ajZ z%3w4+5Hp1xQfGg(u(8s2;MSIE&xNyUZF2VYwbOmODhz|B#Dn^mgPT+x#fLKHydRB3~Ll`7Ca;Pxa%JevtT zPTdG^;`Ten*PqkQzWpoJ2FuRQ@jLGrA3wQjbwCVEp*5sfJpoY)KdqodKuG=lN~^{G z7c;j`-@5-MTJga(=!R_VVf;6;ZgJsUYy-`u1UhqCn#?S7X=xV(3v_S)8U0SwW~u$( z|9*frSlUDfE2szUi9K|F?a|r;7rX$ugOL0GAa?}#e9XD3%?^6NwH$UaUW>m}j|kL$ zzZT=#cNec8d6=AmNLFw?45z?1E;|lZtIZI$ogEAB5D!wymao+@b?;SywM5{W50BRC znr7YHt~ug&Y6A}K6`7R|O+aUvQfZyVK7Z%%zMY14U$AU4Sy!MlPwo5WH@eEU{_|_b zbWUkk`nsZf2lm{s+P`MyNw03rMV*Y#kt91=yo=w4Se%-ilIluBg}J^+D$Uf(&9E&W z$8~z_Sg&`vS&lq{zATW0cUP*XglWDgbZWKx6X9&?(5it8HWmsSFBlj+e`De3H+g(C zD)_QY5>4k~JelAT!LQ@_woGe(c6NVn@BY~=`zzvoSs<>r=m+?G+(*vHVT3+VEIvkv za;Vq*Cfat-J+)ijG}oTTedd2?`qlq1BZ~p@Y@=eh9rH;ZJ)aMXi=BB=z)bBIm?-vTAkV3pJ^bpda}(?{>Fx8XDRC43G0L`>tCYKLow z(Iyln-|14uPKo4f5qHv z3U_RnecBTa_poV#*_nKPI+vTy=V!8P-zzNqgs$Kp11(~p-lcZY>Viux+=w?FJsduQ zw{3x{oQrSTa`g5iWEX}Aj-vNiTT(z7By^b(Rv;`q`auCbUh9+r#-=o)Mk+)vB}Djf zbfBIZol*M=%cY5h1#HDCVxf>81=Q=wW2~yx6tx8b=25sQji`|d`PhUUo~6XK+T*p0 zm(z-n2Nhg6$|k7^F%P|7>p)LPkENDNhqO&eYqiH}7jx-rS0FOqIK05FwI}rQQ4TR` z^cs1N5USUa!cA#Ji>de|A%|!&F~X0b1EeK>hF` z1^&#@^{mH6QqtS8ACvto@EdUQP#@6M0)4BWc9GG`0=q0&18Ncrg?@iar?+Y;-n=p} zduvC`H;HCLU6=Pgh*sXCdAxSU_jof8*LN;PKLv~)D7`)uq|Vqe!_9RJ5NRZ%5o8?5 zJ<_IeC>#PN9Sa3@Ho0CZGx=0r{YYOh-x_NX@bQ!_miD>F_zib|V74_|lPbw7GW@ys&{uu)9ywc2lywRRyo2c5}sz5{)p zdW0KY)HWT7A?#4ejB>`}&M=odmi3_-&S7@C`0CDe+KYCZllS>F=K2(5yC0S{C<@P@D;wf}8{w_eY zY#N}d2OvZEP-E3i4-(+1_I5UH3UY72zksw#4&MgsM=AUkK=d4>2M5q*{4PKk>QMr@ z7>^(+ehwf2YCx60YA(%=1ursEG&zIgJ_6YUkN_noC%Ju#rDEYAj!^}upAx750c~Es zR4_YQ9C|qe*J8`J5c6+C=>G0%T81gwuBQ3i(Fxp>!D~|?dxSU8lA+Xv*s+2?=dLv zJW}4V`MTmsy;ZI<=xvU6Cw?sz)2p>GXsLo2BIMhN;e0u0F#+5D>@q^;+;h)mE^=Rl z-Fx>M9(aJQ%gOjz>IQn6q+x_?D)oih3og)JNKc<;8XPp825HvecIvaxswTF4Qqks_ z$DEV$Sy4P>aw*kL9b=PN#L=+Ht$-VYO^OFwdUXn=E8>%sdv$V^Gwfqa9>y&Q)-ta<5swFGe(yb|KfyL&%smFg>~toLAoyFqzj(x0M6e;=NeCL zLUH_l<4HSp6Udzso)kDDh)3>HE-H`JX{4?r0 zddmrNUgwaOqp^bA!E?98Vr?#Zjno~9xTW@TAW$Z4Izn~f=U7XxZnC=8K)`DA`|*g^ zYW1=oilqG|$lKh9rTwMXYV&w(Y+Af93-!MpfA{zmb)Kf{9VU;*Wb}AmhmR4i@s!hK zbh(TsXX6(ztpdrphhA03L^tKmG+m#J4tULGJ}j*Wm#51^g~oyQcXDg{JFM3KF|qp%*FE?Paf&da+_1 zE?i^L>C{5A=5*EK6-6*UMSYn*^J6d;r8b$uAd$_T3s-;}uJFsJgF~ql8|0fci&t#B zpN?B7IDLxkn=~7t@dQpg?KI=o!L9f=J9g-9xS^irW$H?L{`fTX{K}R3Pke$+^MwUI zRatnJT}#C@)@wEbzXn6a-&Q{+)#4z>q<+Gk^~h{elV0l9k|R%930&|}CsQ;VZ4eeR z!ljA#^=VsXxliQJmkI`lL})aYJ*#Hg1VOJmE}$KBj3Fc5p9T!`l$>D5lGm7JGmJO3 z1#J#bz$&pS<(jf3l)ETCrqi{M6Ld``eF8B29Bh_%;VY#7f-3V0S_QTDzx6GM`&p4Lts+tb;2&`j6XwiJVy=Ednsun$5Mt#HvMxBfl_9H1Yk~rb&skVOUAS;9P%He_|E(j=iK@L^DuZnu$fUzB1T3WHKP8DZ~ODBi{O(RCZ+ zT8+Y}7)Wyfist(MZ^#@Z*D)mpxT1u@Cg{B$rmg`FGhJr0(%`eRH!P5LaA*gNGj6Tg zYCO47%*WKIVOAaZL=`$RsZ=s@2a`}ASE0cHsEtM&-_X}6>0@fdbp=MqoTx_AK7-0) z>N5C`tIs_WSBV=ALqtqD#WHWOrkK}CEIjte3mQgfSS+JR>0y|#1dF?Zdw`oPOE6RYbFEcrTtCB+kObMhVX zLM&F6+IgbAjE1}nW zDE6(2Jri>?3nwMMO5i&w0ShM*Pyq=j0v(~_==e}cIF^+^`f!O@)@nzN6AVJZ&wzq& zg9jh_C?B3#PTPkI;gzwXQ)E?VVzHdcB61e#la4F(VprNEwK$z-i7D+Ory~O^uEw9i z0t!>ySsr+h9h+qR1PYOR4Zf|uBCmP$xjC#HMgJ!(SzbW!x32cvS&Z?%(06aB9_&n4 z&*$RA)ilJD>pS@1IsBP=TqTo38Li&uqD@FrS%6T=b>9l(Gml;topG9h>tAJ?sQ9b|TG89?xUsBL*?>AuVhy4EERXIN~c%t zES7ez%%o$}7p|H(xF!*sJ_x^S6LktvAE8jPNb!y2UPidfai4uN1x^r_(lnVNj^dRU zhih+azW2V3zng@>(RJcbNQVAd6Usv&IbaGvg=YvR$jja@`~!c9+$#w$Jb>8;?ItDb z_m}Ykk+B7#2e|?n##P9m!_rr!u^9VR+l_uI%xP-(XmaS!H5pu@(>2+5J3GJ8+WHN2 z&!gM7*Nl&D+Xm%vyoT~ri*oW}eFQ@LAB;d;f!E@@8zT@PIJN&}uh+8ID4*)MphHq0 zcSvyq4%N#>?DZiC`|#!5LyoTnQhPO_Mn~qP-o}j?E*nlkf2-Mk`4jX#c0lFtUwau9 zENvyELs9R;7u5b`315MM-{JKNf}wZpJT?bj102gm%W&_oDr zJk2*2LMM+;ZVZlxxO4XLd87s=!XGi*{~h?#!TJq;ZjV!F6zCYarq;7zcD^k1lKSyU z?0nj$=8WSRDNn7pWWsR+pD(hsx8e!JA4jOQ-O9$@6XCSkpyo;CnawM?_FcI-gZ|me zFf<)va?xV!a)g7$=llvJUWMS{fYj&L-`grFNRy{mTS_?fL~w&BxTGyL36mUchT z{vh=77~C{s>v~p{GYxh()_3dcs~75L?x3CRtK%?sRC`z4%AAv0k(ju6bnN1Z_=@y7 zOslx|ZmiQ6Uyb*7@9S?peY2?!T@m-Y2swz>V3bsl>2=ej(bPjBtt*Uid+ z1*rHe^jsyGTS;m2%L7X^x95h7+jB!pXS@PAPij*s7y)17R41lhY=3d6_U5L-AB&rY zwmgj<^Y?0tPPJabh{L_^+Gt3QPpS8aJltk?@q9Hzv zN|2=UTRYEglOCfvF76#ZSdoO5=td6`x&t3WxBjE(vv6en?n9|*rh(`x6_mW0UIl&e zbXJ=z{0%he%Vc*+4^=n;EytXOq2(-AV-#~aP2Xmc>>84U!H{5olgxKHt5xQ#*fCUY zW-V8fB}2Z3^=eo%PU`+fcojUJJ|CGy+|-^lVVqXGoG|p>@22lXXlw1qTk(Tq$h_go zYmXu2n_$>#N6I^rET{lz?jE7LVXdsC?D%8_N@8f%_q@shjz6D zhH|dqs#3ImRnNMFFY<SqVsySN}s`#VuU=aQK=MQ+L5g|cw>)zee_U&CCRgEjOuc0{L)PwyW6vIrQ6N! zCux(?8`%i{@`#|rFH#u zdQfXJs9eUNJ6G)$F+z!gSLrsDv(cV_&c3OVnn<0V?v%>ggM|U3MQc}T>^R_Or|x!Q zW5D1`nykiP#$E<$VhbJUX8ddRO`0KM!>vQr6!WE2uYk zxBP-OPhO9-5N0T3n`RI(70iBXh3I0r1ZSdw5d(ihBBzxGiB=+2x=q0VPgAT|T6&Ra z;*lqiuO-(KtbI!&dGs;Hgt1-A6kB~++sLMxMZ=xj@;u0b25i0;%3XYOs0$wr{1s;6 zm}Wb($Bq#S4z;*lEkohrY|&L3jQR66{4d&HRC&`D1Q%^`@5I$RcK`R9z|g%{@49x} zg};?Oc*aQ=SB{>Px$umWFKUB&Zh|sZ=ns^(J`GxrI zXFrl_FF{HAou@HAY{6w9DhR%VD`}VuR(c|fL77M2J zanrzjR%o`lG`StCObMHB&?h0DI;#_byX<*DG#v(p*Ws*_1%VMgcoT#9gQmq3pGZzSiIOCxrFrMuRW_40Toi%(yL5{br( zaQa0{ILl2*BG=1bz#EEgOs`xi<%tA{DO>$5Cc!F+NXkc8W0DxeVp-T8bn;ByAzQo7 zH2DZJqdi*5p)DWq|GBQ`juJiR2Ri)C(*{3G%l+I? zw5c47L@AU8;_e({^hrR&2^t#CmG5-XGe@T40ce46$H>^F<&Ir#@vNqy-A+3F^eoXG z9q3*dtxFx#Te$)Y!W>^%Ke!v*eqx)N`tMJ9Lz9l;>W-0m*+~I+hbq{SF}Wm)^T~=#+7!BuGrTWhm(;`-U}-x zcCmY;X+gen=x5};lwE`2Vgk)FMQY5hDOkKA{lX$Lr8=`{J?{b$w%a5|iAWQ&XH!Dn z{~(&r&qgh7sl=Za2{F3Br(-1jyxMzdH#D%t+*YZ4dSv+KfojphX!If>f8R8=w>^GcwL(dJ^Ol)f%j@_ zS84t`{))F{*jkETC2!f;H+4!0jcM$=TB;{i5Ct3J&20><=u|=}gsZuTlugn_5S<-cg(hd+c?+-Vs|>?CRbC>t0ov zqElhEDN0+~H=dqdMbW^wBK~i@hY~;=d4Y=h3QRt94|usl+#JS2A+zLkoWEtIXzMKc z`nFYg?Og3m*~M46dQKjsi|F#Jot@hU#4F$2vXzfMiTBKIndjBE@=mHf_z3^vU9p+L z7`pUQ-o<;O(*tpQ58)>tdgb5H@5%XhjftpQ(4S26)Zze9kZ}yWQAw44Lnv=dTsRc&B_`eZf5=UH;2-PhOtPb^1k zuZ{*~Ji_}Dz6Eb#y;44@=ZW~wXfxX8aZeTuJV4WeQxDQy6NH&$kUz9mR1&Y86>6Pc zgGtTDryrmPpL`h4t&gv4v_q~tIaz2K=HbfGZwj~V&rNG>R$XY=ecKV~=hVOrBEw$< z`xjr-2L*<6V_1E)c#|i0gceR;|2nZMe{dgf)o^=ky%0}|u_zypwhpi2?K_xXoyra> z6$A3jjRe?opQ%>T4c%x`sAZ{{9ylVwPXzIPr`Kd<&P}N8rSh zAnpT?wS!v4G|$+(Ay-7<|_x} z$%(hK%&xIxWyidwBJrYq+dd(a=T>LyhA*=+?OHN%&uJug^UEg<)y-e;&Q9W0`9W?U z!QE8oIJqqp*bl>o@`TF-_i^ydouzWTKU7+uZ+AN-ilA0vi@B>k{iXi?LZ;!NgR>!v zt?VD#-pUu!4tq#27>a6WfpECL+^g5AQc-_bsP1KKI$vf-R!)=0^Pjx-B;LIjRq^3)%cm(ua+h?vL)StZ77QW&h`y%-klz2(b=?& z^a?W9Z{byJqvj!vsvhI0;H4OcN2cS+^*X6SCpQYbIvn$LNP>R3S|f7@B}FG2SsKAv z>Jh-Fq%0)L6<8i7X`Zd@YPvQ%WO|{-qEM(|>8bltc873-%~pGj-7_3+a8~Z?f+&J4S2o%wjx;Q0L}Vj^XZz2Zov+I=_5I3#Lz=@b#A5B;dxz-fGXmnPUUP@pcz| z?6?+puVL@$Dxr|SFpB?+oI2tK3Y$WI86g=g31q+R^*Y-|#3<(CaL zkEJ9iWXE&j@8c^KTe?vv2C_m@2>Y?o?cY80(C=Cfzi@eNq4Qw%N43|-0Y)7=zC}*I zdY?Xozrdch#17*xTVCCC;%koW!z3~iXvmr!Gobo1O;Jk{TLO}~sYXQqHLsk-&*bH8 zNe>&l{PQgKCR^osNiJo`E4CHXZEg0r$!^ped@h^WlFZnR;k3($XOV6eA;yyq8yxAB z1>WWS2A$lbGR5tcHdSG(BFm(*`3EE3-t$QCwR*7XjXdbH2zVjMkwjIlY%BGG%GK&z zi07UdDVMZ^T*3>xwB-`mO&)UTv_9I9^_AL`@@nFUB*YU~$a!sVp?^ZOF9n=A(IK~F ziEz`=xSr-?anV03d&gGpS7==pqeRYx)RU|1{gr@sd|<5I6f@{60{7O^mIK3mtH-`r zo=NwPy1jvffHyYmFS|1XZ5>sCXzyiOX6;mVMypuEjdi{C|Mm73@NFI0zqrnbY>~y1 zWyxZ)WXU2+mJBj8GsKPq4kryXX;Mm4X4*E}ZMVC{g)TGmwo5-;W@>k{T};xZEdS?@ zuEtlkM{>wbMTb7tnu%%Pcs-bp+V>$$l=M?Z4y$dG^^7um5tKF|Cr7`OY; zku|=q59W4ONm+EoocvXI2ayp79sH}2hyM_>X9}tS@8Lvhxq$A#eAKiKA0;l%Bc3%( z0$)$aGqEbx+|HWgt*)@wV2#BqO%)Ee+$fcotIDe@)9tESmIFQ(aCTkOASohSlD(l- zmCme;G3eu-biG2Ji9bdLnRunJCH&@mziKYxK3q}N@*-GX0C*VwvSNovj|=s>%8{5g zfVBW@w^CW8TBDdVADftN#AHSAY`pWkgO_b}`L#-!w7j)y=o_ba#lF?Ge&&n#K7W?? zeZ~l-m*xNsGF^&3G)q06DED9FGq>X?L$DuPZfMEg*c!pkGKrs8?D?d$4H4P|OE){Oe^!lJ>YJbPmp1Bb-TtI1tR@gR;xSOP$IF8_P>)zVt79M z3DeND{(85XlGp|q`Z1{I8B*roY@SDG9yBA&(_ax91`+xAH_|~|Vz?cY#c1CD&vhH) z|5=2{jRX91#J9b6)c$>XcSzEjH}Bqh_x6>xTIEF{AP#S)}xMjP4f=U(-EsYH;wBb4`d-{{wsbPBpBS zNKV%8xU;AK;ma?7q@P5QT|k@hsQ8)NL?W!PN|ySytb=>1Al3r25#$dbOw{PYzM-Cz zhe5Z(GZ}A9Wm!z_3Y)#qGK#te2YdXI+cHfu)uz3JVc9cy&x?}sJGaAdiM-|em?#H1W51o`Nj@(;rAeN@H@Dn0Q;MHkuEE_kD zfmn8axV#C*$ls+zqbkK5yBqgsl$Tv^b~^uwOvhbOMB==Jr*u_d3-0*xJ_vY~&j{k7*CBd~vwVDQ6LKSXd5oFF)n zN{J@(B&*5Hu@YF2L=}eDNFJ9igU#iBEN_tKe!QL(Mi-4A{9q$FjNPH%kA8|^(ejTK8E~%s99|U3+X>?$tSTyP;0}eOLr&_}uU| zryYF+Gl0gUd)GeyYyk12V~Lu{6dC%xwieq}AJY0XxqI=b-`Uc`=fu61@QftO0kf#u zLumDN+!{vRvsWV6(mCnp!~J~!MCaJ;qocQtkK>mdB zPMrG<2|4CWinl$BqmJEOH)4+DMlV~rRwukv7I8n`wYf3O4?V<2G0)Glam*(h!jhFh zW=R+aml12t0RJ6W%U=4wYOTS1?r{9yu-DY?7p8T55&!>Zlg*>jU%WSOv2hWL4VJr9mn|oWL!vqz&glKG8&4jUG2Kn1mkWI92DCG)(K^(7*RlGb<~W!3C-iBo zWnl6v-7DmKWO?#KmUKH~`b!iUeyB+EvDLJDpg_E=o?3oL&yxs4CJXI`F{8MDovWip zZ(AEDx<^!}{{c5rwDuygp&0zd$5sW05_!wTSW$RM;-@L3q;q(S4sOy!?v02mjOCNK z-)w2H5E&~Wl8Pz`LrTRarPZO+k6qOko4v9-FPT-ujIH~d>-RYGau-;d9X4|Av(jo# zSQVS@o9nxFK8_`{BW1F-8@Ft^scmgUIuxE6kH4Ec^5imRu9+u>${uGo^rucgk&nZi zd12~Zr~eV33o^YD*c1;ze8ZPnyEp8N9a~YLnSLIy%t}rAwxnhw%71AP(F3? z#_<=Xp8UdQY#RUXxjXJ3cwyn=A0-BdAN_z>jdI_XFui`}46acIW#A!}4qU^#$X>s( zrGqlT#nxc(T~yLggpYtrruaf`kh_vysqfVl;Oae{LMK)j13E zC@+p)(IQtlhT5NDc+ETFuJ09>Xp2?c^<-`086fh}X;wb^E|2e@0yI>dcWFkOfRHXq`(A~ z0u^xAid~gIf$?_{TnmfE_E!GaIMQN*krvtSk8toSC~kyNf>&eT@+)u#_lB9YI*Fgp zVXvB(7o+}!L_EJL;-BQMcJhz$lIF+W%gGc3=bE=2z=Vr5_LDpB+Wr<#^aKErX5MgjQc09O`eHx^go@m{y?zG zlb;Fj454Jr*{>BUf^e)PY`u@EXz1^xK3x6>uJg=0la6V(!sSwUrbzir&uf-WUjaN1r@ENZM?@h*?rny!FqZ69K&f-yv;S-3o=vV7 za8+*H6x@ujKKS5Qhdy(-F!ujJ#@?1+DVJYHXRr?*M^D&AE4lYLjapZBD}(~#`9Y$P zV=;PfFzI;w-g@EyI-_tZe15q@R)q%!dYPmGjzj8X< zJ-07Yf1Rh<+gfL~7*Ytu;=XjK+7t9kb{<#jIun!S(q?w`oyHvEWizpGIZnmbaXF84 zzeG&&^9;eVVHvn`=M7~AY{o6eSnih~Gq5YtG-A$+KTp<2 zKlHKs=gUZnd!(K#RZ$Ywa)3^>z8`JBL*{4l@3$AoYX@-V$2JHSGPY8o++~R}V~ZKX zR~6sstnkfZ!s+~!Go;VCJk0n>eeCf0!%|5c51$J&1g2Msqi!_tb2e_O$ezNTVcaG- z$uc);b(QFqT8muEoYWPJ!#ymaU)k>or120Wy}j*bsMbo#^j8eixWd?5Pa(l$I`N0hGI zlQ74vNAd38=MKZ|zkO8cD(H9pxR!7cx6t-obhz+m*!comA^!D8?$D4&_;hjm+zX-5 z{OaLwjXRv#V)FarDk2;Of+Alf+6bt4_KqhYI|C0I9&aHQyekaQdNttS1@%I)JC)(RpRmz_|KA%`8ZkHUmaq89XCVWa&xTyg@0&LE`v;d$CJjY!6)7IUc+uGaeG|R1; z)?WFwR}3GlmzTar;;b&YYj>&a+T%mabHjpP>2#L)=Nn37@SGxdO0l$i`}Y6dzFh&= zio{EWbCUwnq8Pg#>_!8)=c>87CF__B_=9na`$yKdz8o-a)Et9i(amJdW zc!OgQ9xyaPZVe4|?AUBvga~Y!V)H~28cffxaJ(sD-qzdj;|{EDsofebzfXIZYMn!P z8=Rd_GN0upMKn{+M|w;E%ia7Srl4sx1snCj`WPDid7h@Xc=_MIXkmVRf%(z=WBR#x zI+BkU>7ca;J8t|Grnq_Sxc&PykKnO|Q5I8e;rTdTL27E`&eeh} zh&Sd+G0b)X`28)zF7J5z-^s+i%J^r1^yT|pHavk{3TwBGU)AREwD?H1WCrhW&3krk zW&MHZYb3TivUZGDYIUY{G~ujHdSAn zwb}_K)*c%|6ZQ2IMU_UQ$(p-DGGPdz6{(1dg0&n0D*2AD^1Y4TaD^tt zx6S$+wq{NoX`2M0p-iV2%4Mdq)8HDtTODb?V&b446}AlGW#2@;+y^RMZ_x_u;*HhVqMZ)S;*> z-=$NP6l8yN0g0HHWcvIpe#UDku~CZQ@A&Ldrm#z^XyzGWB&H)-oUnAY1;E(@(BD7& zkV5dqFIqd@v2L%YMjLVk{2&WB95TKLnN-P?vBm}vAsZ%ig__A;Bn+K)+EUja+WUo+ z(d1Bj%%#FoVf>*J*IuEq-0qn1$Xu)~;2GQs5C7Lhs}=K>S)br}_%7xJYe948rhO#A zw)8v(s4hE{+1(lFb_n7srPI(lDE!M`1tTrt4x7=wAiw75+`+g`yEIZF9@rvE2(}D3 zeVS|>*Ui*%JCPhhqz5gyVk!C&es&R`-(T=^ob;%hJb!Rm%=-oTJAURNB9HzT=8PI% z!^I_1?j+^Pq;Bq1T_d30+X>+HFf;deTp1NM10}y?UR8n6Uvj4$d7Q)q*QINlOct`_*!vv_4X0Tu%gfg; zgpMJ*eb~V)M4?D+n2-CN+^Uj6zsKWHNydrjEre(Okmnf)QajKz!Jj9%5K=rUxe@*6 z@2vh~Vdb68XkfK`t!0`{Y;cz#@r?hatfuVD#RVS6q+98F_q#U|d3cCz-^Z}kAVMW- z#-dGUDlcHq+FyQUcJ=%`{(vYo9H7IRLQt_XU zJ$^vq!gDiz*VZQm$dmQrc=rFreI1D=LJ0Br1zDdb;_1nJz~$RL9{$>6Ye~Ca59)?4 z5g5c>4fVUS*_Q-({clwPmg58=DLXZfB9tc+|-G7jZJN<(wQqp1rDPgRvU;cKYSK|-} z@HsT2pgdyB{cpjhgJzj>sb<1@*w*MF5V3|!enLJ{D~{ZC@);ujGh!mgMzp?%tuS8_ zF|MWPzya1))YZjWi`+BLfNI5DqzYiQDsQdXjn3z-HL?F=V+>~5jqN>U|E@j8JT409 z;G%Y(f72*4BK^Yc>sop8wi*|))nr%vYYxXHTWpHmYd4CGs%Ae3(LcA~jP==FnSygI zvym+)92+dHY^9#H-N^WVVn@NW|BH4M^CTV<^e-AxNS71I;AM0I)7yyYWocQDY~obg zh;V}eogn5MxkFmz@lhH0YP=Z1YzISpKx0U)CEn%ATlgycvo4OBf9!F>2J6~@3i|03 zo{f=JQakRxOSgy&i^BS+{)tg!(j)!SgBw~!NF=6T_=qs=(3|T z9f2-Gxo%UNm35$DH?USWwWE1=eRW?{B=(k<3)PAW_}sS5^V_^`d1Fi7m&?c8X^vZ^ zr*;n>taoJGo(f%ykWW@s6}*P~hvs?asI7&prI7t>?IVoSCN~W5?!=#lue=gI;q}UM z3(a$$GN)7FS!jjFN}0^0?}7y$r_{ZKE5-1fL@FV+dLotl zj+IKTzsdm-EbgPax+=QOx)L&VJ9p!C#`d0m4K&j^pqDo%o^RG_H@$7R&WRv3J>2 zA|h94Ik${JS^d`f$%%BUYqBrcWHVNXl~QF#^FY#{b+!*VQ`?^F&(!uA>uY-x^5o90 ziK{H8Sg@kXE-NV&RhQZ`Qe|1GM6HyYEhTqn--J(nR4?Ek_B@49RJJc zQOp@JycQ1Ne&+=F=u}S7Y1ahrB~%PELjDLG<3Z)G_|8^`B%v!!0da*{RiRZWoVowz zmzFAOy%h|kuF$9zV}Zs9kANf+A^)VzX68*CH|b}wWdyoJNVX?ni}|gOSY-Cwds`G*ON%}dcD1g zM30X-XE%-Fy!W6Nc~){0B-<96tcH8PiU@yCq*ZDxfRxo5ZBPlwqETr?-d+?Bbok|E zl}>fJl>Aq&c2<_j{T%_OhH>;iyl41V^DLx>4JzoL7vb{E0IC{|rbY!|W{RIj|1;Xa z6t2*f$fQzPiB7>3-auA;AMa-M8=I z(b0!Nvax)8vv;r8KE1eU(e1v?wdIBC-s+f*?~=&X-un7riBc?a@ojY-^Kk43 z9}}6)q8Iq)?|#=T_=CV~7JT-n_ea`XhNe0}b5pj34|Pq30mjNLfn(^~PDV_&@%B(T)Q&!^}!fVX0n8;!H6~TW6 za)P(u_kT$6-xB<{aE#(}6ldPQy-*I?P0L~4m*vk*;vbF3k3TVocEvFvd-0uR{H1dZ#8H%HPV7DP&uB;dMX2VlA_YT}V zZl4M9>s9)IIysj*;F8Fuj%zeMr^ZH3^(o4aPst?l-9yK&z)dCXox<(aGCQ4ywwBw_ z6$O@QC)2``k!!n#ZW()d5X}O#F6`Jo(*pnkcXTNx@iv{9nLW{fTeT~RTXk&z!OP=2 zV{C3C5w6Kjdv$~R0hwApElO#=0dS=(7?fTG@FPu1n5!K`Y!5!PGrGNc;JLoqo$;Ly zF@4C(*8%5o9o7x%z#Ktq5Y}pO4cFruoUt_GBOI)_a;MKy+pJM>+4z0QG)Ce9L*Oe18 zY3=TT!zZxY$=&TL@py!uKDJ#rBFW9+$QUOot=OPRW723l-{=PbCBn@E02q980OkGx z(EkQ)t+zC`Bb?Y8VUpeBYrE1+QHLsyNAoz3ED$ntjLt+x&{$= z;ya^EFU5Dn)4s*%!N+~LB4)-!nMEC!=eW4%y0+GvV13uofxh>C>0_VB_dYRNe=7P_ zVVh3|Uy*ooJ@6?q4s>jHCcd1@!dLEpUFzd8bzv*dWz0IjO5Q3bs7MWY8A=6@{Gi*G zdusNFJtg&bK$PiwS*`>=nY&5u^GV?|l2UK(M(E-pGD{}#EYT4E$ErIcldJBGd|K^o z3|2RK)M`&-b+FN^ej>WLKNRZU9F1)r2!#d~K@%A7@cTQ)1HrL&zrTI#C0EzpuJ%1W zp2F|KDkdg9@1|p2aOiU8JU62-9*4gjJXo`DE|6!|JHi0<-A$eBU~lRQ4b)T(`tzd; z)$v^kS4S$9<&hS4vn`CR-$Ejb7Tp)--Ke?Qo%Q_YTB$=THDoNcg8`J@-gwcbj~wrk zq%(YhORm6o`bj&EjWL}-V#zL`EOO_4AF#3|i8R}5 z#~WALvvRvO5G=8kSZbWEd`H2n@$HHFP&E1)yOp&C2jwO4#NHC0KveEH>9k3b+c~R7 z4c_-ZgkmJ~W`4U|QL?FQL~s8fl##2Aep=rVi`iQzxLws^uV(U5bjw|2fU zGHVkxD78LUq{`z_DvX0|HJ!e4?fz+Hb(OPPC953HM7q4?>MQ0Y5|Y7DU%uNCOy<^ZevF{~07C&+?&+V<=b9fS0Qi2~NOL3+KJ)V`r zxCTZ3d_!y{d=^~aYk6tl_FKBX)BkA^yjkK6igTx7mpF)v5|b$G*ZCdzn?~lFd?)wI zv<%et;GMpAcD+2f{kqAQCa>Pp|ILp3MDSp4H@v~@1iAOZq?94;X_%II*>agwcL~yy z#J5SKZ*doLjR5Lg_wKzN-yXQ_@!sXWLnj)(HTmFaX3Z#l@^PlfZ@tbepCA7?{wez* zMzoAPf&_aq z$hdspI(P{vIQWYcmp~;4KTB~LSUC6@iff^qgFi=cMNv7gP+SS-6`X%L#ghemIl;a^ zPH;Q%h^>9UuBe;?6wegl6BKXY;^+d!P26_zT@(*PC8a0dKf^3Nc*$Pp{Rp?c{BDZJ zits*)C&0=n-%s)4_6jKO1P7-a3&r&X`j=hkGEO-bMD+^39P<&Mk^8Wp#|eof6a-5x z6)d%!J)TiFUVTuUyQUXJt?)Z6$9@y8k_7_NtKr9*lqlEO1s@sjx$t^U>65}&S7h0` z9Z@XHmO6R^56FB>8`7926N+J)l7uERY-ZZV>ITacFM(O64J>|v;-(_}MT$#coP(dE zxElHhPP772PKqtZ&%xc;&h!?cBe|Slp6Ppb=w$JsBHYd5LcDsUYnICu$*J22jZUZl8$ z#bp>@KxZhfWpOLU`_Xe0S1>rO_Z-F51$^0saW};+ysr>C88ax(h)Qu2eLqq3zMc2! zm3Hw36nFAIPu@ou-;K^vT$V3~Xt%?pU5#wJzQ~p@L}R4@_LuEv?CkkMc% zB^3~+oS_~l@?SY}9_ubIS<7&>~D+u9s-iq=%c?{pBe_PjoqfaW}>7a1WuM zXv5_F7WVx)_Wfd91YI2b0>w>5_*sg}C@#dfo8lF)ms9UKimU1SiK6%IFw4F_RD`?P z{wF#(p|h2xvm2MQ7B4BnU!k}Xx;XfY6qgjef0p91BK!=+wMF=I6jyL@zJ%gN*u;7N z0>w>SdiXAihiN$pmd+2c{nN$ct@D1QsNQah$BOViiYK6pQ+|x%#pMeq?&Q#UCHe@( zUGQh#6vdhT|2*6Ow0!bD!D;zx-xqPq=L;xaT<=+m6Mp0IG5%Lfe=V;ff6@$yB|C3z z6MOMqS~xjM?z#YGZ&e`XzF}ar+D3#1Qx*qflnG9{YOCrho!B}Nt)6rxawjDc5NR@g z#+CscrIOt1+O&@`a3EdQx!A~oHYhBeX!060d!&&yuL|)(P;3QX$AYt;C~(9IAd8p0q{f6H0*B^2;;ls-uSM#NYJ+L(+`QnEhp#aPqv6k zIF@E+Oo*L@j7bMOh7qRkS^NUUP2gp5A;#SluYd(AJ9BY6v~zG~t~|@m6=z}XEPCG! z8S*}{uMm1V+1=v;^FE7Tpt!vKV~{9K&<2Q(&e*nX+xDEXZQHhI&e*nX+qP}nGdu71 zUBulR8~bk~x;nZ$x+=0N^U3V4s?3A{p}y{Si`qBYhO*-5C+q}r%e>e9MZgPZ$>%Sd z6uIS;qtfP2pVP2 z29<0XYue3 zL)Fp{|4dLP14Z1M!Mm^44eu6Gr55hS-Mo-gq+cEx1Zw3&XK)jQ>g3a|`5145ADKPA zJRZ|f)L5-s-0wMIdd2nS-mzCQkmw~Sd5J}(7P<_c*LGPr+)Pk)y+9Tvn?WP@@Y^Fn zJ8HOc40X{@_toUPvHY$WclUtn7P|TELlmcw+k}QE$shj;n$f9|wQFpCs2j^rbH{1< zW;a&ay{yt2w1#rH2BBq*_Dm^Raz!*|S)8uLEU7{N=Gzh|Z*sdBM9r7~QIq~UrZmpb zmEXxH=S?KO&^8(Se|nj@diRui$ar=fg9P-(#GcWka_JvMPfF1V2JAQC5Q)ftW|Klk zD+YX9%+BD5$c<0aC-HyGgBSLH#wIu5e~b;ayVw6>)bA?sVv!1HL6XA@a41XUD5t13 zYA9SLE|KXstcb1MEfg{vVC;WY(qB|?b!GK7W$d}Y-Lz~gvtMOZI1JV<^r5E>LanIB z?nYo?@^rOZ_7l2b9k6|^tevguj;$PAw<$W1DHqjbx$PHQ#N)vuoF0?QP^75apc57+ za|cnN3+UYr|M9k2(*qW?8CS--I6FH%H!9|&)hlppn^!|+EYUh|JK?VUfvKt!F7GVP z+NuV0}?hI;^eBmz3oxk^-*7}x&h|U zBkU!&fu}@Z{$Z3=#MQ~zxUUkrCo)gf0a8~-?APwAEPz%0iMet-67`Ep<{IV&*trf z7V7)PjI0!g3V8B0+g(O#u$ z(Y?vQo=MH`*F9{*cMJJN>__*EE7|vpehe4oXln^!lw7&BTx`p3Ou;+5kUnscTNF22 z+%`?$jQU|on`jnQn`jYC&R93I%ZoSB&b8=wX6xWdQvXyN)saq4l-Lt{aiK{}_aJu* zy|)1KN5iPMM4M=AqE9t5d@oYK7_h&X{&iel z-e#Q`C|H>e;=q%97s^)11(e-MjQ9ku40*d+^{N!FpD1V;4p^QlU@4Q2X=mf8whrb- zLi1qqzT3Ro`ExDoV?frw#*XOhf-h2s26fSdO6PU_VVF?5Ba@z2idL~qhVR=rxo-1P zxv$60ugCcppT>l71!)fLOy_v_>zNm_ZXs7P$eKg6=(wUh#HvCx=W0nh%Hv`*7Q2N= zpPOiT^!1d8%d7zTPkRg7LYp6e&Z?G{nv>YsjjaXX(#3-~Nf-t3sHH)Zc!dHbNdOGu z5<`{)h|dx<4N`0Mik0*x!JEdmHGk6dhOT8%Dj}Xb8HDo((_sNUR{Qy!DeZ21;YEaBB9o47}OxG5pRBS@jSQ9qUok z2$xr3AkKO&L>>Rp6$BQ~iY6UEO2uX8DbV0-Ksu(?*A#koDOn}`ao0RGdlUH+5hid> zs5B8zOV7>a#EY5zMwiH%tsVQuf(NtEo+^t9R>k*xDsyL7BJr6O6Rhzjni1xDhwfY?AGOr0PnE-A zxAa{YarNFmB-q>&yTqWk-06byotTZcqPOC4iHeWx1pk(Dc+C4?q>H|-;tL|&2%zGw zZSGmAe)d~_6p4{MEy^pG^)R?ATgua{yd2`(I~h1oZEPBoVwszqj5Ll^x+sjmu{8PS zG*Iiwanj2+RjUZRlgb#cT39fhaM|&bBV{Nu7EWpw|2TvO3s%WfBc*k9KbJ3-4lP;8 zu^RV(o1|>&mx5z)mDDaM;pRM0Tw$IqWorcHtr^L#vPf2?gx-!nF>*%}wyIujq6c)Q zXK0~hdUVwH7tOI#j#C016`x1Y?A5KW*U?YYDRKcG0Y}!5-@}m(`4d6>BS+ zh9(&F>WT5<>vv@QSRM}-68p}LX!!>g5Cpd29NjGHsOU&ZzAS!(n6O-aJOV0&^!4n| zYMcZ(NpsBUcwk&7j7hSkVp*8yP&v23u~qI=Dk`qsDz_a=NLe_n=tY19RmG`y z&ns3;fq_CnQdH!TFi)I3&H8LxF4f2^VuG2@Cc&aophFmUF_e~U#R`yS#I6Ahn;}$I zRdrzr-Do-Cao~TgS6nrJWDnRlY_RGTDPH(7@;8i3pL@)POb0a+BCO2dSq+GnmFLrR zcSYtT`~5UQju#^|d~-y1uqI*78}gyO!p;}s<&|d2ys+*f)8HP=jgoi8u0llXH>x!W zVw&uH>XnUxM-wT_s!qHacY3(@jU241Zk2+@r%n)Oe3}XfNiSZTEPm=Rv#6c-BsqmR zHBgnm@F-c+qY43OR7Tmg7kxT-atUt6^u5#F>AiP7 ze4ULmmjSX#7*?rC>&QP2Ga%_x$=%|)b88ulEgjU_XZ#r@-uQoYRga=p9}!HDuO@!{ z7E&oW#^NRylcPo+lpxl)oD;ML=22wwG~_4`C;XbuVkV^EaQ}jA2mL|=4kfux+ zIdIC5MrxJYjgdr1rfn!)KP6{umTns?U}xdtb+_Q!8ZNo zw|j(ujj1MKKW^0iCm7jT--$ASZ^D#FF*_1{ruO!EdFkcOZ0MDDRzG0uQlGYT31RIWxu%=83C10B}-VT>bmmf%v;A;H)lSQ zZ_%}UY3}DKv6V7q#u@g&pjW(l+>iuDM8ClHIP=fMpLXj zU##xIq<}c1E+%9H0YX%@boEA`^7(ZwLiZ_bD=9>67$bZ?B05HJ=zu`Mp7?xHI68?| zr>}J@5l&EV!Bvj<68|pK)!AKCg}vKeRx; z+_W4a-JHcVKPjqTpfN7R9>l1fKsi$7V&anNGus`NP!P}89nQdr|Jj8lA0SRkg#TJW z({luK6Bg{~z!^VqlO^BmA=3+eTP#1xRD{CXCI#Y?z4SaTQ&|l7B6E9(0h}V%H!Y^2e3ViCyx(`5> z2!kMRoa-P$FSlxo8l*z>0O&91WcNQU%m=)bU3M8oUbYSQSJsF)&1La|R>CEb*h|Lf z5L?~41`}$MWi=U4iST9GE~c#;ho<5UBHqw;9i!|>X{}|2orUM;>$dy$+O30z`#nlu zZDthN5R!%zsz&duZ`!2Jf?OfK=*{0LqNQ`Dza$N#?Jy8-$1p0P(^(jU?@U;yHbGi- zusD3PUfeIvRF+=*gM~XV>QerW*~cjav9(EE2@ZT%Sq^{36UGg-H z&%x8ZVbU2T%6O~g_#D!r2tXHtd4P*}5xIK3I?wACC&LV@l8RRioDrzTy+^y`mkCce z)g$AjP4m}2^FTvTlHCUr`_CHo51^rkIu2UV9x~;v#PSl;z>Qz&Dz1pEVou?U7o+f& zrBsCFR<6G^MqCr?FdK9g@>EqVh%LrW&VLr&w@{#MB^|SdYk3O)CYmF&!eG<&b)|h^ zk=vKJ(~n$<>05ot+_kHFLK!+1x#)fRaUJN+XgqeYjU)MKo@3eyb{(IlLcc#4U-PDIUbN@x}=Sz9^=tz$nw z&n_*CYL;$Yn?Z4`TV1T`#=D`h%a}e7-S61_^c&diU>PZuNGX=LOwXmk)F2U2>AXHb zzgz-S-_+INaY0~`iARAAp077G`vg|MPU|ECP2=>;sH?S`23Db9L(glV=U@2Oc~nY-FEa|&+~7AeTHwl|SQHq+i7=mBh7=}EiXDRR+> zSLzC8C1h_NwAoJ)rAGzGm-pfXjcXfwtO`a`qflc^?*o;nz5pJ$S1%RWfb1bv_D&FrT zynx@OHQ|kbiX4>;&;!aH?{HIpnt#PZ_wC;b2G;xnKdJ^Uy}q1iuAn+HLV%D4eOt)t z`=)noJGdv|YNQ)+CEI_ZkpNJ!VNQ6eh*0pNP#_|h`dig=>4y**G@k8$B4|!wyUC9dZyu~N9WH5uo$XjVZ+D-3fz|0#0JZoX42aMd9!^8;k9_BC*N9Q z&vcmr$HixNqh^sqiT7IIRzL*+sE#pep(+?aHL5|5;zizc%mD2$4I;YfCgE?!2UPP` z1Ii{I1!~9L*uAj{CYTkQ4Uc;N(BvI8pFigRxN>qv-RG#rSx4oFFP+PQV`AQgxOB$p z)NCIMYP-q>uM^e+Nx{@K{%TuFb;;GImL^cX162(;Sujv5G?38Rw?A`Q3*NHW#18i7 zvDzdyi`)5$<%A!-(5tV=O#B495WTE_3J;xyFCUXJ?lrLF7e0#u2mw^!DMJn1AIBui zHz@<2E+hbiHo0B%wDPbc37U=M`gZD^COxyZG~+8Tj8R{Wk(ArhXRGNGT}TXd31tkg}(4g=qw9t79plj*Gnj%lW+#2H|jB9z`#HiQUv55$b-6+6e^oEX3_C2@IRatn>+~hFHA zrM+*-x9ThF(v`4&2Q)p4&>~w;+OWLP1Y)M%FX6byJIXv=sxE9UYk#kWMz;g;+h%8L z|3&R9dv7$stX-g@%Ch!2vvyULnQNx=^tE8EsCGL9(5YwUg=HUQ(6<7sWT-0X%WD)C zah|a}YVBZYcbR0UE6Nj+SJ)rfsE7Y`GwAvho;HAiD5g>%+&9AAl@7J!#nz5+vrId< z8r%`TWW(Cb5^X@5D-ErvnYIjDSg<-AP+%w5h4B6dhNMa8&NYeKeee^E1IqONgTpnM zNnVEV`C}W_CU{@8q0SW*xvHPOinWN&d?=i> zYzC@KTtR1367D<+zIG^Fsl)bovmtW&_Y2A;u3RQRQR9^kOEgBx9t|n{2!qEXy z9#~OcmaytN2g^|hDp9!N@@+LbgPEdI8rpC9yv34IFvu!}SFV{sp$1%MGPA)cef0b@ z`ii5l1W#-*w)w6Lu2tygZ3>QPHTk_ys_irHQ3~!i-;zI1j-rWhe@J709|mFP-B zYse?7DQRAV#3+xiAsN?7SGjPJ098wg2vfjz!oUz(N@ci`e?L=(tGH&SYnbETG`v8( z?KnOmubHxqQHuR+TbNC^d#Y(0Fs6p9t!fMMsT{&&Mus|D`XZ@2cB8Orb+7X@r_c72 zY&H}cms3ZGg^taJ851p!pY^VcMDOtA2zhzQm%Qj`6eA_JdKLIILnbPiIu`qT z7St0g%9tR-*GXQbqig7d_Jb;R95k*fh(G=^5awx3B=%ebvg~hG$_0OkBd>NP%`U_z z2Lt4cvP@K#Ii@)JCU!AU*--4dGrfF2BDMv$C+ctZ!n|1b>0=Bm9br&(sgAV6*@Mcv z*udZHLdh90qurODyk?y2?v+em?qa&fHsRhz=ZJgmEdmwS`A!sXy5ucKbs8W>utk$& zsAxj?#ZZz?vJ37rfu7NFQV~$|M>@!5tqKK?jo_(X;%?w-cU&D01t5l^|7myM`~c4( z=F++WN=LE)2FL?|-n{(i1FHQ)am9e(heVtM2t}2q1HkzQaCzErmB58RlMX<5y> zGcKOw4Y{cVoBE){;glK{%%;due0`-X%kGJmr1<`=U@WktN~_-fEp+7d7dCgbR zUlT}In3I1)zi|mqT@z4U3@c0;6Sg}Djq|V(jIzQjwNGbrLsgT!%&#+av33hYSlRqJ zNB>rI7;n3^@Xr;Yb`t^(^xKV%8v4D9KJCTeYK-JFvsQ!7VP!=ni?>rwrKjx`-6Kn- zaw1!K?|TYE<8Aa^)*Dvq&CLCk2est1O8T60vcoh!`!x(cl;TO-;YvK)L(EzdX}b_H zkyy(L$CsXu9_xt1a`*C;=Gf_rqI-iu+cjHNjMbOo9E#$Dwp`5^tt%@BN5H}95T=tA zlsK>${cy{;2gVI2msoGj_}ejhfzaoU!B*4PJIjRT3iU0O&0><}2$ArN%_dgEmT96E z+;8xNCcfn7u7~xOO%lRAQ76t-;*iUZY4MTfZLWQYckNfr=R*#Lad+q9yK=T_lm{)M z@3jX`r);!icCL%w5F7l0001P zfL0Si0Vn_fetSQ7MjO~0(+8%O^Nu)$&RaxVgjgSTp_k4(-v$1@K0L-@KW5#a%=3a& z){P4SWZF&(LUi7bOuf4~Y?I&xQ4G@{3DOKx&}6B`G47~pM&ZUlAP~Q)T@%sm5s4+@ zNQIKI-61ROvNgGPaa$LPM{eb3S->1>oFQiEy7%N38c6s+!kqLbF`ftYf>L@1jPy_sYJ!oO=aAv0Vn` zN3dP{B}y_~hLJj73QM@JFlH2JNM^wp*N#2W9)-7{Zwh$Oo$h5^Moi@&q zW?0uPv2I+|F3@&7Y~gxdHRz@Q!*U+h5|v3Bmn$BW8pd$tZAg^NA2c#ebDnfU(Y7Df zQ+-S2R8+TJhh&sFPguKdI@3LsIr71nOBR6PdK8Wr%6;CHnPz+L6{+f6ETv34ow4c7 z{?jKCWzw5$g|O{>qP^Pw*e#Ib{fJLyE@83men0NO^LamN;rm7afdl;&7Gwb3lxSO% zjb>GwT&>@zC^@J6CA3=}kLL@vy}1MfZ_|+o1;bGpfB#Nq#5?dlROFWzSLc-#Su=i7 z6s9VSmldXKoSPS#k2hj898YT2nvKF#hiQ$2e5wmu*|j6@^j$b%+~wdP6Q5!_4)^tO&j_X0&NSO-k?9~4;AYr zyWM_&G#DN4CkVJhCQ{}hatX(P`m}vEl-40)N?X5jwS5*=M7)qUauxcKLxSe!F|2Fb zh&S%-KQZoO2s!s*N1fYv)%u5Yw$7uhcgoV5_k7#V6JWfzLDO!t+U<+LNv|dH=tVPQ zDlzr+LS~Ut*`;x%?g-@qAe8&)o6lXcp4Tb7@B7%_(GL{(^UMEU)fDTEW^KNWWkD7( zsz!-nV&@k!VhPa*CG&aX(L@r>7%lhv19g8vk%%PnXkqR_sn20c?qSW&5mT=bF|VQ6 z|3A1?uwHRGozGW^)$o3SLSr&o4VE$-kV>aBS`SxpJfKo*#MfF4m9t#1TCM*&;#Bi| z!0wOb5sk=Zaynl37g4R)Y_>c8$iZ`yTLb>;wU6uN$Y1%ierWk6(|Tjcq=n~s9qrY; z=YPQy!+G3_B+Gg9{{ap1>uEhzHE4JHaXXex`%yF3b^A&8FIo=k$g(|-+t748j+)rE zJx;pdc;62j=>ETu2mpaXpp442@ceaf3fLZOncl;(g!sa&Q~ppxYQgUMpP zoUfeWg2U;2wp^f^;{yx|gTZRBm}-wiDwD=)_@ClNrBQD-SW0)sVzpjtHeAW}27|@n zaM@o>b3~)nZgV+U&hmuA<#B)BU&?UB)Ct5 z)qfK6d)Ph=ZtcbSjbyu>r=94yoh7YoyIo|x@V=h@|BN#@BDHWS{T`uk1R{-SCHoyB zv1B~8NICNvqtSRgjaW7J+y9km_`j9)`u~%tV{QKUpPbt)jovZ#XN>5S9}cusN)Pny-f1U| z_0s*)DSd-CYei-$+wh0hK4A3@=O+h^t!OxK(#Kv2TaC{AZdpo$0anRC0z-OrBF|iP z+=rzlSAoyKcH9CR*^{XXyyy6*Q~imZfiD1JG8Z2>wyOa3CJL32AP`;|FlzU@t#*3> zS9ZH*q?-20Z6%pVw%o3)-A)gP2c6&P2s>iv!?}iwdrG_xYbdYx2KGak>(%HIUwDQ- z5F7H@y<9Xc^>K6X+v^of1om-Msg`aSIxaL1W1Jm%86#_KUz$zZ+u`}rXxffz=G0|g z;Eg_nVp2b>3Y1CBtNZ)9M=XwI5rO@m5`ohLg!j!2ypkZ!78L%VhTJOJlDE{o0~viOBE$ z0AL*~8cOkW06w3JE?4VO6yT_EHJUPa@P>B5q;OCg3yo@0ACP1tbqSFoem$cAz#*^4 z?4x?Swl4|~4|t9*T3(CaJUT4TJ|ge#?QNGb)&%+wy+6hweSe4$I-Mv{h=M|U;plG* zSQH`6$U>S#Ak803xI_PhKmPHgGawHn^2kH;;0(jVQcCa1(N0u!SQCfzpOmh! zU%4KJoqIGGm%QjS!xqJ{W5o~Dwtl^n*b#&*0zYg44g*vJX*%_`Dein3-jB@WF#Ebp zeZGy{_W0bWj6BQlR}5MfF!T*?ShE-h@VP%0fkmC#yH!`2Pi z{2XDs`IU4=%)-hI;=$E0W6)LflS9pX5XaQfG82`PYIpPDF|u@x7WX>qNB72AYyO5v zI8>DFisX*z?Ig~F9~jtqvbMUpPOscuvARXCPzMXga&uc&>bgH{@t}xCb2Hx7N?+(l z>ys`g692_94TK%55iziuNgRo|jve+0iC_gQWd)nqCLF~U3c?yn@;}F7Rv;CzETkqo zo)fC>LjIn*o|`zd9O6I% zWr$clH+PoQ0MTDuTm+14mJrkMy#eYlb2o6zY>@wMB=p@Bn7N^#;eIa-+!Tgx#S=qI z9L?Q8#s`Q92O5TNsWnYId8%0KV6^~Z{mFV2cQJ0U-2gj5bO3Ao*?Kj1ac*&60lYwX z0dxH6dR2F^ZgE}#$$S5>_M*=A!ma}2>iPZn<@mvY@Pn)21Ni_l`~#r)2bj`}Vh6Jc z&~kqs)Dw4Q6K$(zkWyxJsPNT`8twcsb-__<*_@(H*)P zXHShCWjcszFU^jk6P{N;CQCiG#{=)mph>`@@suQP-3->*Omt>&!>0R`I^G6%f9eUe z^I=vZ$3^?mFGUM>9vqlsx=>12$6xXZHEv0q-L`_gSyi3*B-oBx%Y{R3#{*GdYHbai zI|m9ucXIfOnbm?0#q=WFj#dl52j<8NFgrE~*6}(jh@CD|f^QVDLEgtq@z=kO5p^7E z`91uW!L1uPn~AJo&d=2dsr9ofB$p}Im;*BA=F8`&!h{sqC%h80M5yyzrQiXuXHz9G zvSa8&pQVnQqcc$Dz|`BryLxyTZk%pmY4c65AVv&hCKzf@p%sxARW=yOuJIhocg10O zcQ9@BBw|eJ3Ou&%N}U9nSaOVad(L@l8P_&Z0}f zzeBlcMg2-f<-=s%7FZ}!&C~Q8k9*_O?AgEES3&)QNpfk&z1Sz4?*?(HOH6|C_K&pzT z;^9moR?&ecNMpaB^OghA(Tnn%fdyc6;HeJjzGJZBg1N zRfW|BR+d()&HkkCVHp`cEmd7@ZIy$)&F*M83+yPgcXV*Fe|&hlZ!DOK?V6jsXY3;U z-bByfAUBhQ-aaprg}!diK~t~O8IIa2(UX`JcART!#y>7REjTGUD=+~{)n?Ou)}7}6 z^yIG(OqBE_b*0rMcBWRV!@+dmeMaWDCI=H^gQJ7n6MWt?z?l;%|QEE)5o%btEHbWL$<5BX{Plez|Ic3K+;7;ey z?OV7npDo|^a!Qe--FA<~<@Q!jAwDf605~9kpEH*$TCOkrDsIL9)t7fbz5+#qxsG>S z5I?*xgXtHsBT>u&(S-iAdJgRgcK46G2>Gq6>-o1irdc~1v?7{i0_Pq+cCgASMBQNK5DT4^L;(!@ z)M^`No4nwt`0g9mgnryi>WNd{Q-%e+9=0PxW*|6T#n@n5+vZIWR~G1{b@Z>mr^ z-~tzz9CF=+R2XNuT8YzDW)TWac1Rkr2VuH`c+=F2Qu_t;Cu__$Vu-x*4J-3j1X#fs zK0_6WtH)u(71MPV@9~a4^{n%T`12-FK`~v0IU)sdw3uH~gCdqW@@(+ zgLGhVTH+gcypQK%-nq)E_LBov>jlXUUrR?5vZG!Q%4Ug55YL{F@i+-0y|-i;AJc^e zF0CvRkr=bFP?ME(XxXkNj*6@IWXkriNqmtTu=aYJ zlvP%T13I!QRZfHKH@rduuE(2i)~!=&pk^xy&j>!~c$8qN;C{-MPf?Qh)TRj!@DD34 z;~Wzlv{RmxftQe!v+sO)@sU=>L3;cEu;4b_6#L$AL9y>3X6)fZTseaV&f;WK|Iu>4 z48%CHLvw!-k#7S4$mDzu?I?bC{e->EbKrzHqMP*7074&Y12zss1M;$rw=pe7c?v$>tZ{W0sTR zl9zNAmxr?|%kcUb+2>m1=eTkJN(j2cC?mn1<--t&w-5XgQn`lrJzi|Nf3R&mFW`Sk zt~LvqMW9NJKsOO4f;31a=_uN6+MI@cke3G%;R%0anNyI*qHkyf9V9C9hg#wU7R}c- zh!+n0gJl$vyfQQW0ld`=tvh@3wnvZ2(+r0t&--(GpI-gd%gEv#i zPI~>}02C}2Z1%f8G(N3Xd0P;jRC>d{2pBHd%-7vWJlf6D7K#gqq^aH@7_f17AS7P$ z6By~$**dz}pX%NK7?JDW=agJ$BYe8n^o{`k{m6s=77zef03dTCV_OGXYa0L%VNq!% z08B%72P*(fQwL*908A@=CmR4v0MOre0e))%{nmm80Q}MXpB8@SIB8~qXR-z0gZI*S zI`nf&o2~ye{r=}6q}W?;yhDg&wlG+1d@5~=$R3Z6fj~JjQ4On+>-U8)(5yW*^Rg$m zPLcGfz_$zxUKM8bTMp8QZDu33*gkJ<27*ClyNl9Y7@whZ5iUQkug+rC*PqNdRoKVgi~##A3X(&L9Pg>V8dn!KlSZ$&y&K64m!(H6u;83n&`z&- zX%&jJN>A8TE$@3&jYO{-&6`*k+b*zf=4G{NcG%ZE?+f4z8ghn^IYZ8zVe8D2be317 zE;x6VWw?pC-gaLf2=Vljc?8TnLhGKPbgy`R7S5#Bcu_C1J($hWM`9$$7}ttc`a2u) zC|Y5B%#{q6xsm7$b==YNM$X)-9?B_PEMjgHxvUa64^EdcxyWeOnVyG#Dez&Zg6`Ea zLyHy4vy)Br8JlxdOIS|Qs3|CLI4UbTR~9vo)_nCO{D688Xsi5=_2Tj$J7rZ|(A%3I zzL)JFvOXRtxGd%b6FY^74x@j}8)LgR?ndUA+!;-(LXjO@i~kiE2nDvytE;Y^$_^;g z=^L+;4oPgF-q4mO@XBKv#Rd7|nbJ%8cu=F431N*^Raw;cejq=yL`y(q0rgjWxk470 zyu}(1`;7dspC#EnF^11w*J>v4T=sDST$O}r8bNWZgU za{v3D^|de|i6EaQ$G`AJfA>^7(2)hrl|GkfQG?|{lm2ov=(?cF&O<$7c_eK=As6v# z1SMn4Q*kL$&RaAR$P{Ir@pER1o+c8c2{9TYXbb4(+s?{3fo+M!&bH*>GPmb=iObD< zdHDMX^yHzPDSIIK^$Se)=rsX?BZDsc>XX&}*ysY^BKj!Vh^6#xYBo*1`wM}}E%k-NOJ znqicKiFqw1q4B<&((oh-`=hsA_9Hvu`Ys4C%C)CkCFI+5oJ;o_+fnJN6NK;QwFuM* znoIF>LPhpcBdJzzTzDuUJUkxBD0DoAs7_Kd%DG0^ap=btJJxYucQ|2sAFY*~;h?K* z$RZnQjsat?EHjUpo)6R1*1QyB^Hb=uw9WaqfmuxKLheZ&r$&*uvVoZJ!O8z}-Z;L- zk~qJ-<_vVJ*pqo0CzN>vhwRat=dAkV5$a2}=G@x5v?bcutN7n=8X{tH9U{YBalXVq zZPK+x#wTgRh55p9O4l5d`OS}tv029AjACewz=AYy|U(q;n1tT~>N_9ojhxOqi~5tgVQA67B<;Yj9q>%pR@ zaA*3Mxm2e}*>0m;QF$`vkbiK_c%X6^egcLqy;q<$B2@~u%!=W~ zXkW^g5|J?HiZmuBFN~*`E;Yt1uN1FqY*@Ct{09Bg9Z0VtVv!@_RMB0;;GCI~!sma) z3M-s-ablJ!;^D3fcc*?ZStnXYA=H1SIkVu5f6n*ju@B@(gDuHAW6{V-ej0Q>&Tr(7 zHtqSx!HRjJ5j(}LL1rOTNcuo6$03Pl*bpS9dq2p?N_K`TCt=_-immU%?^tl|5$uh{ z8Sv$Fe0jIiKddTi@|AZS3 zzUr9bgh#*_YfH>^9$L=I_*#IjelP7FXKV1-@How>`Xuj_sIBKK5|Rus^Mg;9qm6C% zNeSKz~M~XaRg@~%62NwN!Z0_X~^=F)Gf?QIL~L+K2$c0uI*zx z-e*lPU@B42<|Wbf7OQ*~wIl*YlvCUOEf$>Pn%`QA*cZt``UOX~*k2Gy9 z+TgY%YW7tfvD$64d2i}pgScjQ3~wD@+aGKiy+nCVeXVxk83Y$1O7&0uiA6kaeq~&z zi#rbBHoYFVBsX}jkT|YxH?>g%JT68tvXKDj7+K|+v0+P6ZcHccwupIC+G1%Ly_7q) zp%VYBTvRGz$O$K$c<~f_v$2YLwOi`YdivegA>vJSj?_~r_u%ZaUh`lrf6T7BLtK*= zW=_2#lfOytsbu0P5SLdk!FhcM?&^@pq7-EM+gCHLLG|8q%#H!EKtVh+X&*h>= z=AzH`tVj1ufXNUhg1sN-Cww^qh&@PvEsD4zEeaX4OCGbwF1t%CyT?48YUVs$Kw|tw(nc)m#3@Gd&|!VRoScOi#TyaD#{})XN9>8AJ+_?eZutVJ#|g0=Y4rw z38(=)s3Evz&t}PK(=j^ES^m0MO$37zadk`19Z&nB^c}oZ=PnH1Yd_rgaW@D&FhYxrmN=qJVm$kh>DUh?1bOl7O<3knlPH?gQFaGHN5Oyn_9%dR&&PW=1o&U7LJZJD z3_(y05Ks*vk_|AH4S`t=kXQ|&R<t;9J=x>U>h~SbkgyKrrN;sUF=Of475dg6iV$fb?b@tQs-v4`P?hleg&ld{pm!=W7BYZgYW+Lz089-hEqRu?@4!B`_95hMsK*l;kjMWVX;Vv3JiAn^)fGD; zQm1gzOzJn*^k7q=B80VaQ3$8-6^5?%)!$RbOxb_D7*<22`g}#|W!c*6Q)kCfyRCx| z2EsPc{Lf#xs}A4hkuk_P11wCQjj|`011{Z zNWKaMZt*>nE|FSkSnb3#4>~!}IDGL7rryYdLq~tFjW3T!YY~}uedNMjrNdB=5f2ER#AS*e7 zn9YaMk19&W$;T+CkF=Nsz2c&FmyK&!>XlHxd3R#>55iH|uRl;h%YcsRaiTHgCY5kJ z*=XWXbM)jkt8o*QL0g4N)rGJz@_~AHi}-YwO$cP4gQ(0rOvQ)-7q!X>l7}+{WK%bg z1dht*K{*zoopw@t(3eTbn6hhR4oHtZBrfPR%N|01uhYv6!LWWnSG>hIfVAZE&rzPD+f}{AG6PnAQITQurT>Pi z1TA0c_2Xx$#RvKG7xyrqTU}HvFj-(j z@7uZw-CnK|=SHF(kZ7E;8=a1hV8+iG?LErMX zLC4%f+?yIKo1)6gSKmKlXTR&RSEi-Jwkv=KQoTvL9wIFB8@zoP>#JYc{)836*%ZE6EugodeU3pV~s z$~q4SRAmhz+wuB$+z!fD#%eW*pub7Uq6gs}QEqMmV!V?s$L0ahaP@3E+eEYvc%XQF zF>e02?TmW#O$t;D!PbD&x$K&T2Mcw1bkvmEThpzuzBiW?Icn}4aKM}h8;+@%kX1Bd zhRn}WJZHN(`O*$>yn)b1FVFxRNB@vn>Xn#5`liQf2~8q0j8$@2Vpu|~J<#gV)RMNc zS>dm32XSnAdJT6*{kr_=*qbr;6>vby6YnrVgmYx2;th;u7JYm_Up6+drWVPnEEF_n zZ4hK>bPrro5e$PEa8GwD^uCFA^+=2;QMvl~PkGV2PF=JDD(y)JH~2+-1JwvW&Cm8i%O}Fb&M*I~ z5qB%QuMn7+N^qY(wPx#CvPad^?6t~Y?SD^4dp9eZMSB7Z-cDy6$3Q7$Yd|r;c%rPN z>(W1(TwcIKAF7>~r54I){<-P*KxLr&w;fd-?4C0mRlQ8v@W&>RY5dmzqfd*yJp8>KLK1G- z2dID*2(J9%)<>pRR81Y(kyqZO8%&oiE`yey0vmcO0m~4=<52&3Rm61PUz zf9HL6W$$^&nTW^;N-u@P4-0MdgCu%ZGaP`@{{Cq1;Y%zgPR0o7-yMcFq#%IXz=b6% zdJjMFrkL+-?PN93S_W4oa9F8_p`ah6RYe5YUSG%GIBl6xWJE ztX64+9c`o@qGDM=Ut%e7-b-~epxwvJ_9ANz-hKqpUO%iB5KY-3B`N5^a$s5)f^p3a zW5v}?>>zFUKd5>OsJ6DKTln6V0>z3IcXxMfai_RDAy}Yz@s{GQ!J#<8-KE7Hfm8moYNW+-uFfGIGYqI6GU`QW>LsTaJq@0qGHg+!$SK@J^ZMFuaw&f3q*8 zoV9*`HK6Kygi6hR@oe()a(I&RXp(oawEl|-;(9N%!h3ertb&=%cYabV>}7paC-kyb zuQG^N34@6=vq1W%x4s(UBGIq z_H$H;CzG0W?{}v`MkW?Y|c@~p6YS9rvvpD2^GS)J)Y~)AntFy(}<%uEa8iX3&k z&$hK7{~c`KH}63YTUX6H81JeT=qhba7U^lt-i@QME>wk83|Yho^0smZ9TF;wTF#NEhuZ~jy}rpWe)V@WuaOoI88A0s>^#( zhP#$N*zd|Q?Gwo3M@sVH9d*v!vIJb#WOoQjz!Q~RY`!kH_dXl!HmPJ&_*eK>wP`xU zHzTf_O0Od$sDrozT0J^VEwq*zy;LS9=>SPu!o;!i4xYhC@9}qte!!OKFmG@-u^p6J zwrz!Wjsx=|r*1{W^*xRIn<+VD-Ay`)YJ788@Z$pe5+>>*{A09c^(GVCL>PTV6F4#` z^i*S;Us*IC5tP%sgF_*HH^7V-%Zv_|SprEtO5av)3hUL62VX&T&c{K#tUt(zeI|~D zIG66Z0r5}B-mtmzkAb}vlj#NlA=2Nr1G|&OB|>Ev%xPb~QJLTdON7t8K;^fiYmv@+ zkD~RC^lO-k7SCxXjYdR;w~xwcULW7F>RjCJUoN1SkU&MGDp_tzHqv`>Imif?LLxja<5p2Sj{ELE#!AN9d5Be+Sk7c1!G?44-1RhUe_(rQ2xqz+$pit_U^y zu&z`VpDZd+`&9++IMcS%Y-(mkh2GU2ngscLLIl3#E~RO4%rIv41*WJLV$o%4RdgO* zL9iOm2l%u6YrWGSlOJeV&sAkq+&MPh+7n5fab^LRkEzY~Fp!~@Hx180s%sH`eD6Cf zi$ENS_#QK&O{Pk0UInntH`v`%c4$E=EC{1!zw%_ywOv3$GzM+M9>PWS++*>-aZqGM zea+vFfB`W`5~)~Li=O}o7*(%EYMkr zDw6C9x-Yxi7YYt(Fj`qO@3+OIQz&)#bJ_OcI@u-*EDf7IdpGS&j&0`0*xVU5W*MFO zQo1Yaa8{cq+)Fkv)3t3;VH^t`{)Q-#^_mOMqRLER9|oNp1pe`ENCiF*5!!nF>7l)@ z!#Flysya|Ucav@nRdh07rsB`vss`{C-Ag@8gNj7HW$Kaf8b88#h8F?VeuUi%V!c&Q ziF&wZjjohtr)nz%jH^0n2E2N8P8#Yyke!e`;QUvQ@oDvJt#pj5!SM}`{ya+D)oOiP zpZ-l4gG+Jwjqr%*@x)|Yj3}Sy=l5-6Ee$4lppXyFgY6Q0qqJgjLOH6>X4`9-n`m@c z=bIo!Q4d5_^~4;68fU-5z`HG2M4Z|zeXosN=>n!DxV&n}#Q``iz(BYw{Umj$N!34o ztf*9!?Ar~+YPhIJMN;+@lTf`d+2(Z-#%oQel^jEqpz@CIRlV>y0M-~P}0L*TsGI!;nbc?VgadP zM(3a@=XD-3RDHj4wDL^$xSF@vQLJA(xsb0M!DobB3*aj!#rEhTotobxn&XY$3@j~u zS#`(;NB18l%=PKX7laOqs!(IB>0H&W5*ftR9k#imKKLOlkz#qyQd1endTHX1Jez*8z+>H2j$BG6QggImk*0j zXRD(E(Bn>C8cPe`s5TS%#@hyJ8H7|mJi88{?x|k{@OtKJ?iOhVM7=YWTolxLkFFk! z1urdOKoGa+aWJ}bzhh3mE9j$Dp&x9XJ<~;>1);JkQ{CZbBLzniwj3;^UX319B)@D< z`bN9rUKT+(nMrL%5&>)s5A8Vw1M&&Yd^G~jeo<1{vmXI6p7HN5`&q(b9+$q}#$K#` z%cz~4c>T#|GSZk(GYIh15G4x}Eizk8Kk{w;s(rn-Ebmd-;DX6Y7H;UNL&$Cl3B8@n zAM|8{=1Qwx`~Ju}c&r|}Yn926FL1OzFWnzdyxz=xVu4w=1qS}Gd?sAX00wE1Sp~VY zG(uR8Xc04*dm~(>#*aCnb$qk#FAVSY5w5;0go|vOpXA+(>InvXqL@>QT!<@~mH1om zqIL+W&HJzM>pS0{cl#HOu=}q3m~{#@;I{B}Ix-+~_f>?iOJil>+uUjE=858roiIY0 zZOHds@C~D+^r8kfaW5}{Q<1QWM2M8C6;iiBcI`)zmx*UC-{A2UUpcGGhWO;h`%CaNvqH zA|a&y*oKQoyHiBs8{TqFtbkJTr&0#UVEFvs?lL+AR-zrSxSC*!#9Flhde3{2M{_wP zFS!k;79tZ3sYk5EE1)D3vIeZA@MSgusXlyel6DsnRN)k@r7iH&e5572wOaulk!QcQ z=b_>dVdlYMF+-%4S2!$kJke!XZkdwa;rwVR)JmTJV|2`@gDSr3!Zcpu>2dWu)jk0+ zEA0d%5%;oW`3F6s2tT~e-z@8nUl%Xad5QPQ(dr4&9o2!xNG-I&xss@Nmyb}{?(_X8 z*Fg5`^6M6?b5zSM*Anh?y^a%Xh;VLO@ms|@su(_Zp+=MiBxXoTKjaZgHq$^@?IU}5`v6aa z$=ptPQF2z~?{OM4d}DS)GX9dTi9bGD_qlq5=3`C@WWe=gpz1u4FZ~3oCAJ`!80DDz z28fc z>iHwjO}C?Z2j+eZBTyJAWggRyFZhgPxdbCG|6&z;Hh&W{|IDQV%Vx?6q<^o79d9}3 z|LY(Qh0qK9NtIxtdkEnJvS(w{w#PuB&%Row0h%r_O4jCLVxxZ4^@VMFVuiTg$0C@} zBe-Dl=-|%D3@IBAcp00hcGq+otJ$YIS6cfJ2j*@$LqlzIwk7IPOi!dRncQ3`jt;W= z$+2QVF`wHgVozhV%JJka$>m-U&~dD^YuWH&D*y3h=i%bWn(^uYt+Le5YV@wA^O;@- z`HzR+RqLsTqw}k_Kq;Qb_fSKy;}|!M{a)Gn0fI-MsndvmMP496B}4Yu(wi{$*bR^0 z7E!&AB*DPsdM!O_5^7AQNoIu#hKM(WVbVu9t^o0#bBT_^scexP3Jl_3rz* zT$#H%t}iALvLpZ}uhKb&LEi4KHuhZ`{@Wx{{vn|t{gm@LDErqfXbDhCpD>IrO34ab z=^6X&!igchhAd`M@UK@M*!-ZbF}wsZyoQXC?rTimaAy|#`evadxrE1gLf_RTuF->b z;j!YlAIDHCy_VM+jCXR6#Mk#xSeKYyx_PKoc6h9xa!k?3U42kL-bplHq+wzwPz5#R zK;Frmd1uRLS3kq^sqn!)D!t2+i#5;JWUgG(==~P^Y}qNoVg&dtjR-(UtN?#^5d|+w z4M7&j3?5#^x4;W?$ZOKr= zHcRNwa~<1fl9-2z5QUv@J?xczuhsK&AmM#NO;u3Yak9^hWNSq_ zI=cMH`Rp#3{uh|z#m>)cER0Q1k6l;IK~7%rHE>U^t6u)@ z?->J=IbjL^Hm(Zdvdem+g`{R2uLsz@D4SiwAR9B0<4t*4>szS|YT6^T9{_m)!|`w5 zqD-j%l!~Q=KUP+$k0DOfr+io=8AATbwu8V@ZFBz@DVY}D@673%zG7QTm}iN6NM&&#<_;v&a+ zaPj%~&#Dw06(#7=TzT9giNXMP@bZSgoOx-fbXKiPAZS=;S2 zvJ2xvPDA_IhGUM&-N#X_jX~rumed^AN)Yn(2sBQ}NONT;qr(g2oC+}e-ND^?5 zhF$v9Rj0we%B57#`((zVz4&7(Xy!w^t)0W%qK+jc>#Er&2C+)V#1X0qM(4P(EK=a$ zWWKcG;__6SPUoNRcy_k;ZS%YRLhwwqg?@Zr6JQP50;^H z5bo~ONe{`2>Tdz2>LjwI71aDf^-<%N_A6JOk`1&i$7Is+X%@Bj);UkL;l`5BqRTJ7 z#rH~Ryh*pxd0?o$VAVss7C;$)lD=XmwbJQdC~lHdPf7PlO%JjL%GQb|$u+66j>UZ8 zw;wfB~&k)APH?KP;HJ%}vMIu);YVl0vBh$3KL6BMy1qM)MKPxxcH;xRP(T`B)2 zh;*1dyN7(^a$_d={8JqBAs%gW(Mb7}6%}pLZVK*$y66MHtkoH+7Z&B5eox|%E^c>8 zNaKzm<Fl5|HA|3NHV7q9CnI0hd7d3i0F9{kn;Ae z4?xPo)iFhJ=k`(wd(3#FaWy?)m_lflr(R>R@(z<+veEAP7Q4*icG9M z^{UX^wD}eHtpONiokhM5d2ELUqUI0!igLe(*yjGIwdvVk3+6g)H_IKkL}3%jJern^ zbkVH9EL|Q#d9?c)3l;2>S0{&}-9%|y^wVLp`>jOf3tq`)Dukr!+D%`=m%N<$Q1(8@ zD94xUmW>8q5_nD0Y<(}KTV|WTjxN=Dsw2vdYHQ1>PZ6br7{p5GEl_8(s?MDCC%qV+nxTq$=vXFjO&PBT)j0I>hNo5}5GV$^&9(~LrPzQJ=o|4eIPaflSpvy42u zYl$9F5_7h6c6Mk64VGT069)_Xd&ei&nU3~;t%VUCdU?g9`1ynP+UmC6F_b&ni%B(B zZW>{wSKk8uCb#^)`xC94UHYE09Br`S6NAWY2r~)Dg{qGwcT`un+lf_HouEBAW?U{b zC9aX^j9O{Me%g(>C|@*iA>xSJCRM{)b<{{yt;)HjWcP6KAwczOK#upqc>=Y_`m6s{ z#7n7nly{Mf5B9>X$Bigy%$OHVS!-j${!_TK*GrT4dz?d>w)Bs)o{iCONmob>06~Gg z>BGFS%vo!rg{Sg%Z6Vnf14y24#ApO(-{dRt)Ff=TK`P6dvwx>9~*`UnzA}{7yEr7BHvu>w`Y_| zmn!c)=sfFMr#%gL7$K5Z+c@x&stj5qr?xJSGXElxS#j{lJ06yQ_X*Sh?D^0Xe0;3i zdAJL|4b>}JZ9QI}6Y54vMD1QH=fj%+u=+*vdbuXeO*dG(<*JG>m99er3LTsK_E41L zb7z!lf1wkjMd<6hO*eR6jmKfKN@{ER#b&g(5Bs+NVN#UnN_Jh^MpGO+*&j-EK7x)7 zS#a8(d%c}14`PPGH&}FfBm)~OcJOeyahmd*;w~O@Pfj(DiIY5i>SkW-_9qf!Jo?%L zXhq61&#@^l;zL~)U*LBG<#WpMs)lk!)L?eQ2>x((^--_|Y;o6_k0?!0@bVsJAF@opk~K)sLhqV= zt>9wbCNi3o$hd+HMw##zj%j2yBLbIw!LY0i+Rr$(wkD!bjnPq}$!hRAYK$;#k0Yzo zhiqw)?yo@Z@7Up<$_6onUQM2P+)Wm%qGQAvrJrC~Wu|&@f5vdwUM@4oB+Gm6}=_hmjbp-BssVi zA&J&2I6h1y4=R~awl=2`H;2i71CP%Si!nD;%#Q9X`WTpc9}%?nu+{uaN8 zdDeJc>bxO;8h^om4S5}YJ@%%q7SQfbo2R>pdNzL*pumXyxv?fdgAvueaV9_&9htYW zCqNe+wYhO8K&cX$u(2gTs}eP}F?9FEN1y{=JO*iMjfW*lj(Td3hfi5)YI1~!c~ntc zSzJ*Zo;QB1j+r#VY~_2L>WHSjRExEiFFtkuVLLS48`W_i^nOz43x?)IGFJtj*Jas6 z$arAK5zd2rWyMvpxeFmhd$idvp4N=d>UNyn`SZ@fiuFm6vF5^r5SM7P#4)ZYy~W$z zkr<@S&v>ROjeiDmBAJAsl0{i5QGDGzcmp{Uj|Oj9t$$kS>iB|wB@S6_WSwpsQ{E5- zC!}Ais?7>-zg7bEC#8W4Jys1>Ng(@O{3BEP*7;E~jP)-Vo5;}{QYsskD(jjmo33MP zN@E)sCtGYMJ7g!@Vkf(QlWkFw?O>5@bCT`8&)Qn~KGWWLYw)DqxqNyi{LI!lcY68w{I~xE z`GxG0n*Rv-E&Vg3tTFo*|C!c*VfC!>nN%E;)hn`^0o>zvu)%pS{dQ1Y;U2=GRagjN znkgEz@zPHL=Wp9+>1Sj7Vdx*cUSB+&S?p!izpp61P1uimO^bqRUY0<%HOR9w9irWD z%p3X=zpZs@7Y}umII7zn7VNsIpWE2n0Qr5A3l$bD@`s!UoYRD_ z*W|G;sSnwfL;P~5O8ZK?uWFh_py2fz-KH)bia7?HiZ`8om3c~OFL5XkPhwU>ugRg) z8*giBW%B$??2UIq@_#%CC|*^}UDM(VIfX~%P*ale3VK;o6{ong3qRV>mQEeiMb|rD zlJONvPMwn|{F)89=QzU>L%HM>i-s3)Ey2w^;bypL7Ry$LFGCfpW4FuJPwrXRCdoY7 z?4Z~@^kZiJ;Ovz^WR3~n9-q`5+tbA&Ccr1Q@V27Cei8}7P0e;z$B0lj994HcI0QzEC zxPzHMI@}|3_g=xR&dG5dGmYGR9(O8zj}GF&VMFViDS0$|!%M{o0OJfYowKPXCI@qk zCGy)^=Iug5_o8^st}M+sCIOn6!bPP{u8XTrI3)u>URjN<>Loc@haJ8`CnR?6?D0UO zp|l@I+Cni_F&E#c`Wb%cIGZn##BAn&lW0q1-q=1jaEKb>iGZ;2>Qa4Ci2BRTwQo=1 z1Jk#l7|4#xp``aAkb1!;4}{S_?_<#Ksqizec}%4yp$X=S

9MHs_oj@6Qz@1rU$v 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 psj%n$fJ$y5H3ZbI{&joRV#LmkS=BE9<$FpQ0 Date: Mon, 5 Apr 2021 10:51:37 +0200 Subject: [PATCH 357/370] change SourceSerifPro to SourceSerif4 in emit-shared-files test --- src/test/run-make/emit-shared-files/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/run-make/emit-shared-files/Makefile b/src/test/run-make/emit-shared-files/Makefile index 5c4825ae66c..d89b526d430 100644 --- a/src/test/run-make/emit-shared-files/Makefile +++ b/src/test/run-make/emit-shared-files/Makefile @@ -14,7 +14,7 @@ invocation-only: [ -e $(INVOCATION_ONLY)/x/index.html ] [ -e $(INVOCATION_ONLY)/theme-xxx.css ] # generated from z.css ! [ -e $(INVOCATION_ONLY)/storage-xxx.js ] - ! [ -e $(INVOCATION_ONLY)/SourceSerifPro-It.ttf.woff ] + ! [ -e $(INVOCATION_ONLY)/SourceSerif4-It.ttf.woff ] # FIXME: this probably shouldn't have a suffix [ -e $(INVOCATION_ONLY)/y-xxx.css ] @@ -24,7 +24,7 @@ invocation-only: toolchain-only: $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources --output $(TOOLCHAIN_ONLY) --resource-suffix=-xxx --extend-css z.css x.rs [ -e $(TOOLCHAIN_ONLY)/storage-xxx.js ] - ! [ -e $(TOOLCHAIN_ONLY)/SourceSerifPro-It.ttf.woff ] + ! [ -e $(TOOLCHAIN_ONLY)/SourceSerif4-It.ttf.woff ] ! [ -e $(TOOLCHAIN_ONLY)/search-index-xxx.js ] ! [ -e $(TOOLCHAIN_ONLY)/x/index.html ] ! [ -e $(TOOLCHAIN_ONLY)/theme.css ] @@ -35,7 +35,7 @@ toolchain-only: all-shared: $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources,unversioned-shared-resources --output $(ALL_SHARED) --resource-suffix=-xxx --extend-css z.css x.rs [ -e $(ALL_SHARED)/storage-xxx.js ] - [ -e $(ALL_SHARED)/SourceSerifPro-It.ttf.woff ] + [ -e $(ALL_SHARED)/SourceSerif4-It.ttf.woff ] ! [ -e $(ALL_SHARED)/search-index-xxx.js ] ! [ -e $(ALL_SHARED)/settings.html ] ! [ -e $(ALL_SHARED)/x ] From 9eabb41ab4299e290f43d614877947d6238c3a96 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 5 Apr 2021 06:02:29 -0400 Subject: [PATCH 358/370] Remove unnecessary exceptions to the platform-specific code check Some of these were just wrong, like src/librustc. Some looked outdated, like std::f64. Not sure what was going on with the others - maybe this check isn't as smart as it needs to be? But it the meantime it seems silly to ignore the check if it will pass anyway. --- src/tools/tidy/src/pal.rs | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index 1dba6b73b93..144529d8641 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -40,35 +40,20 @@ const EXCEPTION_PATHS: &[&str] = &[ "library/panic_abort", "library/panic_unwind", "library/unwind", - // black_box implementation is LLVM-version specific and it uses - // target_os to tell targets with different LLVM-versions apart - // (e.g. `wasm32-unknown-emscripten` vs `wasm32-unknown-unknown`): - "library/core/src/hint.rs", "library/std/src/sys/", // Platform-specific code for std lives here. // This has the trailing slash so that sys_common is not excepted. "library/std/src/os", // Platform-specific public interfaces "library/rtstartup", // Not sure what to do about this. magic stuff for mingw - // temporary exceptions - "library/std/src/lib.rs", - "library/std/src/path.rs", - "library/std/src/f32.rs", - "library/std/src/f64.rs", // Integration test for platform-specific run-time feature detection: "library/std/tests/run-time-detect.rs", "library/std/src/net/test.rs", "library/std/src/net/addr", "library/std/src/net/udp", - "library/std/src/sys_common/mod.rs", - "library/std/src/sys_common/net.rs", - "library/std/src/sys_common/backtrace.rs", "library/std/src/sys_common/remutex.rs", "library/std/src/sync/mutex.rs", "library/std/src/sync/rwlock.rs", - // panic_unwind shims - "library/std/src/panicking.rs", "library/term", // Not sure how to make this crate portable, but test crate needs it. "library/test", // Probably should defer to unstable `std::sys` APIs. - "library/std/src/sync/mpsc", // some tests are only run on non-emscripten // std testing crates, okay for now at least "library/core/tests", "library/alloc/tests/lib.rs", @@ -79,13 +64,6 @@ const EXCEPTION_PATHS: &[&str] = &[ // we must use `#[cfg(windows)]` to conditionally compile the // correct `VaList` structure for windows. "library/core/src/ffi.rs", - // non-std crates - "src/test", - "src/tools", - "src/librustc", - "src/librustdoc", - "src/librustc_ast", - "src/bootstrap", ]; pub fn check(path: &Path, bad: &mut bool) { From 1df9d498e19088c6bdd838b22cfd64397e42c43f Mon Sep 17 00:00:00 2001 From: The8472 Date: Mon, 5 Apr 2021 12:15:52 +0200 Subject: [PATCH 359/370] don't try to visit probe file this file is only created for a brief moment during the bins checks in the source directories while other checks may also be visiting that directory. skip processing it to avoid missing file errors --- src/tools/tidy/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index cbcc01dc39a..fcb27dae9ea 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -53,6 +53,7 @@ pub mod unstable_book; fn filter_dirs(path: &Path) -> bool { let skip = [ + "tidy-test-file", "compiler/rustc_codegen_cranelift", "src/llvm-project", "library/backtrace", From 6ce9a028a6a5a2e41851ed30b1a0c29e2e087cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 5 Apr 2021 14:40:58 +0300 Subject: [PATCH 360/370] :arrow_up: rust-analyzer --- src/tools/rust-analyzer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index bb1d925dab3..19e09a4a54c 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit bb1d925dab36372c6bd1fb5671bb68ce938ff009 +Subproject commit 19e09a4a54c75312aeaac04577f2d0e067463ab6 From d63b3f9bbb66b6ec4c7eea42078fca23730761c1 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 4 Apr 2021 09:21:22 -0400 Subject: [PATCH 361/370] Remove duplicate unwrap_or_else --- .../passes/collect_intra_doc_links.rs | 90 ++++++++++--------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 437f42b26dd..295f1087d63 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -377,7 +377,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ns: Namespace, module_id: DefId, item_name: Symbol, - item_str: &'path str, ) -> Result<(Res, Option), ErrorKind<'path>> { let tcx = self.cx.tcx; @@ -399,7 +398,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { .map(|out| { ( Res::Primitive(prim_ty), - Some(format!("{}#{}.{}", prim_ty.as_str(), out, item_str)), + Some(format!("{}#{}.{}", prim_ty.as_str(), out, item_name)), ) }) }) @@ -413,7 +412,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ResolutionFailure::NotResolved { module_id, partial_res: Some(Res::Primitive(prim_ty)), - unresolved: item_str.into(), + unresolved: item_name.to_string().into(), } .into() }) @@ -490,8 +489,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { module_id: DefId, extra_fragment: &Option, ) -> Result<(Res, Option), ErrorKind<'path>> { - let tcx = self.cx.tcx; - if let Some(res) = self.resolve_path(path_str, ns, module_id) { match res { // FIXME(#76467): make this fallthrough to lookup the associated @@ -534,29 +531,44 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { } })?; - // FIXME: are these both necessary? - let ty_res = if let Some(ty_res) = resolve_primitive(&path_root, TypeNS) + // 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 + // primitives. + resolve_primitive(&path_root, TypeNS) .or_else(|| self.resolve_path(&path_root, TypeNS, module_id)) - { - ty_res - } else { - // FIXME: this is duplicated on the end of this function. - return if ns == Namespace::ValueNS { - self.variant_field(path_str, module_id) - } else { - Err(ResolutionFailure::NotResolved { - module_id, - partial_res: None, - unresolved: path_root.into(), + .and_then(|ty_res| { + self.resolve_associated_item(ty_res, item_name, ns, module_id, extra_fragment) + }) + .unwrap_or_else(|| { + if ns == Namespace::ValueNS { + self.variant_field(path_str, module_id) + } else { + Err(ResolutionFailure::NotResolved { + module_id, + partial_res: None, + unresolved: path_root.into(), + } + .into()) } - .into()) - }; - }; + }) + } - let res = match ty_res { - Res::Primitive(prim) => Some( - self.resolve_primitive_associated_item(prim, ns, module_id, item_name, item_str), - ), + fn resolve_associated_item( + &mut self, + root_res: Res, + item_name: Symbol, + ns: Namespace, + module_id: DefId, + extra_fragment: &Option, + // lol this is so bad + ) -> Option), ErrorKind<'static>>> { + let tcx = self.cx.tcx; + + match root_res { + Res::Primitive(prim) => { + Some(self.resolve_primitive_associated_item(prim, ns, module_id, item_name)) + } Res::Def( DefKind::Struct | DefKind::Union @@ -600,13 +612,15 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ty::AssocKind::Type => "associatedtype", }; Some(if extra_fragment.is_some() { - Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(ty_res))) + Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict( + root_res, + ))) } else { // HACK(jynelson): `clean` expects the type, not the associated item // but the disambiguator logic expects the associated item. // Store the kind in a side channel so that only the disambiguator logic looks at it. self.kind_side_channel.set(Some((kind.as_def_kind(), id))); - Ok((ty_res, Some(format!("{}.{}", out, item_str)))) + Ok((root_res, Some(format!("{}.{}", out, item_name)))) }) } else if ns == Namespace::ValueNS { debug!("looking for variants or fields named {} for {:?}", item_name, did); @@ -637,7 +651,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { )) } else { Ok(( - ty_res, + root_res, Some(format!( "{}.{}", if def.is_enum() { "variant" } else { "structfield" }, @@ -670,26 +684,16 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { }; if extra_fragment.is_some() { - Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(ty_res))) + Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict( + root_res, + ))) } else { let res = Res::Def(item.kind.as_def_kind(), item.def_id); - Ok((res, Some(format!("{}.{}", kind, item_str)))) + Ok((res, Some(format!("{}.{}", kind, item_name)))) } }), _ => None, - }; - res.unwrap_or_else(|| { - if ns == Namespace::ValueNS { - self.variant_field(path_str, module_id) - } else { - Err(ResolutionFailure::NotResolved { - module_id, - partial_res: Some(ty_res), - unresolved: item_str.into(), - } - .into()) - } - }) + } } /// Used for reporting better errors. From ac04dbd056a94d59699be3983e5404856a9add13 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 4 Apr 2021 09:31:10 -0400 Subject: [PATCH 362/370] Reduce indentation in `resolve_associated_item` --- .../passes/collect_intra_doc_links.rs | 80 ++++++++----------- 1 file changed, 35 insertions(+), 45 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 295f1087d63..54d5f1cabfc 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -611,7 +611,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ty::AssocKind::Const => "associatedconstant", ty::AssocKind::Type => "associatedtype", }; - Some(if extra_fragment.is_some() { + return Some(if extra_fragment.is_some() { Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict( root_res, ))) @@ -621,51 +621,41 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // Store the kind in a side channel so that only the disambiguator logic looks at it. self.kind_side_channel.set(Some((kind.as_def_kind(), id))); Ok((root_res, Some(format!("{}.{}", out, item_name)))) - }) - } else if ns == Namespace::ValueNS { - debug!("looking for variants or fields named {} for {:?}", item_name, did); - // FIXME(jynelson): why is this different from - // `variant_field`? - match tcx.type_of(did).kind() { - ty::Adt(def, _) => { - let field = if def.is_enum() { - def.all_fields().find(|item| item.ident.name == item_name) - } else { - def.non_enum_variant() - .fields - .iter() - .find(|item| item.ident.name == item_name) - }; - field.map(|item| { - if extra_fragment.is_some() { - let res = Res::Def( - if def.is_enum() { - DefKind::Variant - } else { - DefKind::Field - }, - item.did, - ); - Err(ErrorKind::AnchorFailure( - AnchorFailure::RustdocAnchorConflict(res), - )) - } else { - Ok(( - root_res, - Some(format!( - "{}.{}", - if def.is_enum() { "variant" } else { "structfield" }, - item.ident - )), - )) - } - }) - } - _ => None, - } - } else { - None + }); } + + if ns != Namespace::ValueNS { + return None; + } + debug!("looking for variants or fields named {} for {:?}", item_name, did); + // FIXME: this doesn't really belong in `associated_item` (maybe `variant_field` is better?) + // NOTE: it's different from variant_field because it resolves fields and variants, + // not variant fields (2 path segments, not 3). + let def = match tcx.type_of(did).kind() { + ty::Adt(def, _) => def, + _ => return None, + }; + let field = if def.is_enum() { + def.all_fields().find(|item| item.ident.name == item_name) + } else { + def.non_enum_variant().fields.iter().find(|item| item.ident.name == item_name) + }?; + Some(if extra_fragment.is_some() { + let res = Res::Def( + if def.is_enum() { DefKind::Variant } else { DefKind::Field }, + field.did, + ); + Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(res))) + } else { + Ok(( + root_res, + Some(format!( + "{}.{}", + if def.is_enum() { "variant" } else { "structfield" }, + field.ident + )), + )) + }) } Res::Def(DefKind::Trait, did) => tcx .associated_items(did) From 3b7e654fad80e91064b26416a4334cd3e984a6ce Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 4 Apr 2021 16:23:08 -0400 Subject: [PATCH 363/370] Use more appropriate return type for `resolve_associated_item` Previously, the types looked like this: - None means this is not an associated item (but may be a variant field) - Some(Err) means this is known to be an error. I think the only way that can happen is if it resolved and but you had your own anchor. - Some(Ok(_, None)) was impossible. Now, this returns a nested Option and does the error handling and fiddling with the side channel in the caller. As a side-effect, it also removes duplicate error handling. This has one small change in behavior, which is that `resolve_primitive_associated_item` now goes through `variant_field` if it fails to resolve something. This is not ideal, but since it will be quickly rejected anyway, I think the performance hit is worth the cleanup. This also fixes a bug where struct fields would forget to set the side channel, adds a test for the bug, and ignores `private_intra_doc_links` in rustc_resolve (since it's always documented with --document-private-items). --- compiler/rustc_resolve/src/lib.rs | 1 + .../passes/collect_intra_doc_links.rs | 139 +++++++----------- .../intra-doc/private.private.stderr | 18 ++- .../intra-doc/private.public.stderr | 18 ++- src/test/rustdoc-ui/intra-doc/private.rs | 10 +- src/test/rustdoc/intra-doc/private.rs | 15 +- 6 files changed, 103 insertions(+), 98 deletions(-) diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index d474e990211..1c5f8996e1b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -18,6 +18,7 @@ #![feature(nll)] #![cfg_attr(bootstrap, feature(or_patterns))] #![recursion_limit = "256"] +#![allow(rustdoc::private_intra_doc_links)] pub use rustc_hir::def::{Namespace, PerNS}; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 54d5f1cabfc..3501b7d86a4 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -368,54 +368,28 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { } /// Given a primitive type, try to resolve an associated item. - /// - /// HACK(jynelson): `item_str` is passed in instead of derived from `item_name` so the - /// lifetimes on `&'path` will work. fn resolve_primitive_associated_item( &self, prim_ty: PrimitiveType, ns: Namespace, - module_id: DefId, item_name: Symbol, - ) -> Result<(Res, Option), ErrorKind<'path>> { + ) -> Option<(Res, String, Option<(DefKind, DefId)>)> { let tcx = self.cx.tcx; - prim_ty - .impls(tcx) - .into_iter() - .find_map(|&impl_| { - tcx.associated_items(impl_) - .find_by_name_and_namespace(tcx, Ident::with_dummy_span(item_name), ns, impl_) - .map(|item| { - let kind = item.kind; - self.kind_side_channel.set(Some((kind.as_def_kind(), item.def_id))); - match kind { - ty::AssocKind::Fn => "method", - ty::AssocKind::Const => "associatedconstant", - ty::AssocKind::Type => "associatedtype", - } - }) - .map(|out| { - ( - Res::Primitive(prim_ty), - Some(format!("{}#{}.{}", prim_ty.as_str(), out, item_name)), - ) - }) - }) - .ok_or_else(|| { - debug!( - "returning primitive error for {}::{} in {} namespace", - prim_ty.as_str(), - item_name, - ns.descr() - ); - ResolutionFailure::NotResolved { - module_id, - partial_res: Some(Res::Primitive(prim_ty)), - unresolved: item_name.to_string().into(), - } - .into() - }) + prim_ty.impls(tcx).into_iter().find_map(|&impl_| { + tcx.associated_items(impl_) + .find_by_name_and_namespace(tcx, Ident::with_dummy_span(item_name), ns, impl_) + .map(|item| { + let kind = item.kind; + let out = match kind { + ty::AssocKind::Fn => "method", + ty::AssocKind::Const => "associatedconstant", + ty::AssocKind::Type => "associatedtype", + }; + let fragment = format!("{}#{}.{}", prim_ty.as_str(), out, item_name); + (Res::Primitive(prim_ty), fragment, Some((kind.as_def_kind(), item.def_id))) + }) + }) } /// Resolves a string as a macro. @@ -538,7 +512,21 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { resolve_primitive(&path_root, TypeNS) .or_else(|| self.resolve_path(&path_root, TypeNS, module_id)) .and_then(|ty_res| { - self.resolve_associated_item(ty_res, item_name, ns, module_id, extra_fragment) + let (res, fragment, side_channel) = + self.resolve_associated_item(ty_res, item_name, ns, module_id)?; + let result = if extra_fragment.is_some() { + let diag_res = side_channel.map_or(res, |(k, r)| Res::Def(k, r)); + Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(diag_res))) + } else { + // HACK(jynelson): `clean` expects the type, not the associated item + // but the disambiguator logic expects the associated item. + // Store the kind in a side channel so that only the disambiguator logic looks at it. + if let Some((kind, id)) = side_channel { + self.kind_side_channel.set(Some((kind, id))); + } + Ok((res, Some(fragment))) + }; + Some(result) }) .unwrap_or_else(|| { if ns == Namespace::ValueNS { @@ -554,21 +542,21 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { }) } + /// Returns: + /// - None if no associated item was found + /// - Some((_, _, Some(_))) if an item was found and should go through a side channel + /// - Some((_, _, None)) otherwise fn resolve_associated_item( &mut self, root_res: Res, item_name: Symbol, ns: Namespace, module_id: DefId, - extra_fragment: &Option, - // lol this is so bad - ) -> Option), ErrorKind<'static>>> { + ) -> Option<(Res, String, Option<(DefKind, DefId)>)> { let tcx = self.cx.tcx; match root_res { - Res::Primitive(prim) => { - Some(self.resolve_primitive_associated_item(prim, ns, module_id, item_name)) - } + Res::Primitive(prim) => self.resolve_primitive_associated_item(prim, ns, item_name), Res::Def( DefKind::Struct | DefKind::Union @@ -611,17 +599,14 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ty::AssocKind::Const => "associatedconstant", ty::AssocKind::Type => "associatedtype", }; - return Some(if extra_fragment.is_some() { - Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict( - root_res, - ))) - } else { - // HACK(jynelson): `clean` expects the type, not the associated item - // but the disambiguator logic expects the associated item. - // Store the kind in a side channel so that only the disambiguator logic looks at it. - self.kind_side_channel.set(Some((kind.as_def_kind(), id))); - Ok((root_res, Some(format!("{}.{}", out, item_name)))) - }); + // HACK(jynelson): `clean` expects the type, not the associated item + // but the disambiguator logic expects the associated item. + // Store the kind in a side channel so that only the disambiguator logic looks at it. + return Some(( + root_res, + format!("{}.{}", out, item_name), + Some((kind.as_def_kind(), id)), + )); } if ns != Namespace::ValueNS { @@ -640,22 +625,16 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { } else { def.non_enum_variant().fields.iter().find(|item| item.ident.name == item_name) }?; - Some(if extra_fragment.is_some() { - let res = Res::Def( - if def.is_enum() { DefKind::Variant } else { DefKind::Field }, - field.did, - ); - Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(res))) - } else { - Ok(( - root_res, - Some(format!( - "{}.{}", - if def.is_enum() { "variant" } else { "structfield" }, - field.ident - )), - )) - }) + let kind = if def.is_enum() { DefKind::Variant } else { DefKind::Field }; + Some(( + root_res, + format!( + "{}.{}", + if def.is_enum() { "variant" } else { "structfield" }, + field.ident + ), + Some((kind, field.did)), + )) } Res::Def(DefKind::Trait, did) => tcx .associated_items(did) @@ -673,14 +652,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { } }; - if extra_fragment.is_some() { - Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict( - root_res, - ))) - } else { - let res = Res::Def(item.kind.as_def_kind(), item.def_id); - Ok((res, Some(format!("{}.{}", kind, item_name)))) - } + let res = Res::Def(item.kind.as_def_kind(), item.def_id); + (res, format!("{}.{}", kind, item_name), None) }), _ => None, } diff --git a/src/test/rustdoc-ui/intra-doc/private.private.stderr b/src/test/rustdoc-ui/intra-doc/private.private.stderr index cae5b1f20e6..392321f9c60 100644 --- a/src/test/rustdoc-ui/intra-doc/private.private.stderr +++ b/src/test/rustdoc-ui/intra-doc/private.private.stderr @@ -1,19 +1,27 @@ warning: public documentation for `DocMe` links to private item `DontDocMe` - --> $DIR/private.rs:5:11 + --> $DIR/private.rs:7:11 | -LL | /// docs [DontDocMe] [DontDocMe::f] +LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] | ^^^^^^^^^ this item is private | = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default = note: this link resolves only because you passed `--document-private-items`, but will break without warning: public documentation for `DocMe` links to private item `DontDocMe::f` - --> $DIR/private.rs:5:23 + --> $DIR/private.rs:7:23 | -LL | /// docs [DontDocMe] [DontDocMe::f] +LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] | ^^^^^^^^^^^^ this item is private | = note: this link resolves only because you passed `--document-private-items`, but will break without -warning: 2 warnings emitted +warning: public documentation for `DocMe` links to private item `DontDocMe::x` + --> $DIR/private.rs:7:38 + | +LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] + | ^^^^^^^^^^^^ this item is private + | + = note: this link resolves only because you passed `--document-private-items`, but will break without + +warning: 3 warnings emitted diff --git a/src/test/rustdoc-ui/intra-doc/private.public.stderr b/src/test/rustdoc-ui/intra-doc/private.public.stderr index 05b202e37fb..5d1c34b9168 100644 --- a/src/test/rustdoc-ui/intra-doc/private.public.stderr +++ b/src/test/rustdoc-ui/intra-doc/private.public.stderr @@ -1,19 +1,27 @@ warning: public documentation for `DocMe` links to private item `DontDocMe` - --> $DIR/private.rs:5:11 + --> $DIR/private.rs:7:11 | -LL | /// docs [DontDocMe] [DontDocMe::f] +LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] | ^^^^^^^^^ this item is private | = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default = note: this link will resolve properly if you pass `--document-private-items` warning: public documentation for `DocMe` links to private item `DontDocMe::f` - --> $DIR/private.rs:5:23 + --> $DIR/private.rs:7:23 | -LL | /// docs [DontDocMe] [DontDocMe::f] +LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] | ^^^^^^^^^^^^ this item is private | = note: this link will resolve properly if you pass `--document-private-items` -warning: 2 warnings emitted +warning: public documentation for `DocMe` links to private item `DontDocMe::x` + --> $DIR/private.rs:7:38 + | +LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] + | ^^^^^^^^^^^^ this item is private + | + = note: this link will resolve properly if you pass `--document-private-items` + +warning: 3 warnings emitted diff --git a/src/test/rustdoc-ui/intra-doc/private.rs b/src/test/rustdoc-ui/intra-doc/private.rs index 3782864305f..525332ddaac 100644 --- a/src/test/rustdoc-ui/intra-doc/private.rs +++ b/src/test/rustdoc-ui/intra-doc/private.rs @@ -2,12 +2,16 @@ // revisions: public private // [private]compile-flags: --document-private-items -/// docs [DontDocMe] [DontDocMe::f] +// make sure to update `rustdoc/intra-doc/private.rs` if you update this file + +/// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] //~^ WARNING public documentation for `DocMe` links to private item `DontDocMe` +//~| WARNING public documentation for `DocMe` links to private item `DontDocMe::x` //~| WARNING public documentation for `DocMe` links to private item `DontDocMe::f` -// FIXME: for [private] we should also make sure the link was actually generated pub struct DocMe; -struct DontDocMe; +struct DontDocMe { + x: usize, +} impl DontDocMe { fn f() {} diff --git a/src/test/rustdoc/intra-doc/private.rs b/src/test/rustdoc/intra-doc/private.rs index f86ca44403d..337102d6ab3 100644 --- a/src/test/rustdoc/intra-doc/private.rs +++ b/src/test/rustdoc/intra-doc/private.rs @@ -1,6 +1,17 @@ #![crate_name = "private"] // compile-flags: --document-private-items -/// docs [DontDocMe] + +// make sure to update `rustdoc-ui/intra-doc/private.rs` if you update this file + +/// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] // @has private/struct.DocMe.html '//*a[@href="../private/struct.DontDocMe.html"]' 'DontDocMe' +// @has private/struct.DocMe.html '//*a[@href="../private/struct.DontDocMe.html#method.f"]' 'DontDocMe::f' +// @has private/struct.DocMe.html '//*a[@href="../private/struct.DontDocMe.html#structfield.x"]' 'DontDocMe::x' pub struct DocMe; -struct DontDocMe; +struct DontDocMe { + x: usize, +} + +impl DontDocMe { + fn f() {} +} From 0a351abf83f1d146e2d259d404fb16a158721391 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 5 Apr 2021 08:38:09 -0400 Subject: [PATCH 364/370] Document compiler/ with -Aprivate-intra-doc-links Since compiler/ always passes --document-private-items, it's ok to link to items that are private. --- compiler/rustc_errors/src/diagnostic_builder.rs | 9 --------- src/bootstrap/doc.rs | 2 ++ 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 3fc63b4e50c..282877d5dd1 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -45,9 +45,6 @@ macro_rules! forward { pub fn $n:ident(&self, $($name:ident: $ty:ty),* $(,)?) -> &Self ) => { $(#[$attrs])* - // we always document with --document-private-items - #[cfg_attr(not(bootstrap), allow(rustdoc::private_intra_doc_links))] - #[cfg_attr(bootstrap, allow(private_intra_doc_links))] #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] pub fn $n(&self, $($name: $ty),*) -> &Self { self.diagnostic.$n($($name),*); @@ -62,9 +59,6 @@ macro_rules! forward { ) => { $(#[$attrs])* #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] - // we always document with --document-private-items - #[cfg_attr(not(bootstrap), allow(rustdoc::private_intra_doc_links))] - #[cfg_attr(bootstrap, allow(private_intra_doc_links))] pub fn $n(&mut self, $($name: $ty),*) -> &mut Self { self.0.diagnostic.$n($($name),*); self @@ -82,9 +76,6 @@ macro_rules! forward { ) => { $(#[$attrs])* #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] - // we always document with --document-private-items - #[cfg_attr(not(bootstrap), allow(rustdoc::private_intra_doc_links))] - #[cfg_attr(bootstrap, allow(private_intra_doc_links))] pub fn $n<$($generic: $bound),*>(&mut self, $($name: $ty),*) -> &mut Self { self.0.diagnostic.$n($($name),*); self diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index fc79fc10fb4..f499f1a684d 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -549,6 +549,8 @@ impl Step for Rustc { // Build cargo command. let mut cargo = builder.cargo(compiler, Mode::Rustc, SourceType::InTree, target, "doc"); cargo.rustdocflag("--document-private-items"); + // Since we always pass --document-private-items, there's no need to warn about linking to private items. + cargo.rustdocflag("-Arustdoc::private-intra-doc-links"); cargo.rustdocflag("--enable-index-page"); cargo.rustdocflag("-Zunstable-options"); cargo.rustdocflag("-Znormalize-docs"); From b1bcff0731f5ce5f9c2de2779b36f94b44946bc6 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sun, 4 Apr 2021 17:44:46 +0100 Subject: [PATCH 365/370] Disallow the use of high byte registes as operands on x86_64 They are still allowed on x86 though. Fixes #83495 --- compiler/rustc_target/src/asm/arm.rs | 2 -- compiler/rustc_target/src/asm/mod.rs | 4 ++-- compiler/rustc_target/src/asm/riscv.rs | 1 - compiler/rustc_target/src/asm/x86.rs | 7 +------ .../unstable-book/src/library-features/asm.md | 4 ++-- src/test/assembly/asm/x86-types.rs | 9 +++++---- src/test/ui/asm/bad-reg.rs | 2 ++ src/test/ui/asm/bad-reg.stderr | 20 ++++++++++++------- 8 files changed, 25 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs index 28000916e0c..a7a708fe7de 100644 --- a/compiler/rustc_target/src/asm/arm.rs +++ b/compiler/rustc_target/src/asm/arm.rs @@ -68,7 +68,6 @@ fn frame_pointer_r11( _arch: InlineAsmArch, has_feature: impl FnMut(&str) -> bool, target: &Target, - _allocating: bool, ) -> Result<(), &'static str> { if !frame_pointer_is_r7(has_feature, target) { Err("the frame pointer (r11) cannot be used as an operand for inline asm") @@ -81,7 +80,6 @@ fn frame_pointer_r7( _arch: InlineAsmArch, has_feature: impl FnMut(&str) -> bool, target: &Target, - _allocating: bool, ) -> Result<(), &'static str> { if frame_pointer_is_r7(has_feature, target) { Err("the frame pointer (r7) cannot be used as an operand for inline asm") diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index a09c87b3ec2..e2268a61a42 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -90,7 +90,7 @@ macro_rules! def_regs { match name { $( $($alias)|* | $reg_name => { - $($filter(_arch, &mut _has_feature, _target, false)?;)? + $($filter(_arch, &mut _has_feature, _target)?;)? Ok(Self::$reg) } )* @@ -114,7 +114,7 @@ macro_rules! def_regs { #[allow(unused_imports)] use super::{InlineAsmReg, InlineAsmRegClass}; $( - if $($filter(_arch, &mut _has_feature, _target, true).is_ok() &&)? true { + if $($filter(_arch, &mut _has_feature, _target).is_ok() &&)? true { if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) { set.insert(InlineAsmReg::$arch($arch_reg::$reg)); } diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs index ced7483b005..185d6ac8246 100644 --- a/compiler/rustc_target/src/asm/riscv.rs +++ b/compiler/rustc_target/src/asm/riscv.rs @@ -52,7 +52,6 @@ fn not_e( _arch: InlineAsmArch, mut has_feature: impl FnMut(&str) -> bool, _target: &Target, - _allocating: bool, ) -> Result<(), &'static str> { if has_feature("e") { Err("register can't be used with the `e` target feature") diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs index 0f62c19e1a3..90660dad4c2 100644 --- a/compiler/rustc_target/src/asm/x86.rs +++ b/compiler/rustc_target/src/asm/x86.rs @@ -133,7 +133,6 @@ fn x86_64_only( arch: InlineAsmArch, _has_feature: impl FnMut(&str) -> bool, _target: &Target, - _allocating: bool, ) -> Result<(), &'static str> { match arch { InlineAsmArch::X86 => Err("register is only available on x86_64"), @@ -146,13 +145,9 @@ fn high_byte( arch: InlineAsmArch, _has_feature: impl FnMut(&str) -> bool, _target: &Target, - allocating: bool, ) -> Result<(), &'static str> { match arch { - InlineAsmArch::X86_64 if allocating => { - // The error message isn't actually used... - Err("high byte registers are not allocated by reg_byte") - } + InlineAsmArch::X86_64 => Err("high byte registers cannot be used as an operand on x86_64"), _ => Ok(()), } } diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index c0e23b834d1..6c61f4f0d20 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -495,7 +495,7 @@ Here is the list of currently supported register classes: | x86 | `reg` | `ax`, `bx`, `cx`, `dx`, `si`, `di`, `r[8-15]` (x86-64 only) | `r` | | x86 | `reg_abcd` | `ax`, `bx`, `cx`, `dx` | `Q` | | x86-32 | `reg_byte` | `al`, `bl`, `cl`, `dl`, `ah`, `bh`, `ch`, `dh` | `q` | -| x86-64 | `reg_byte` | `al`, `bl`, `cl`, `dl`, `sil`, `dil`, `r[8-15]b`, `ah`\*, `bh`\*, `ch`\*, `dh`\* | `q` | +| x86-64 | `reg_byte`\* | `al`, `bl`, `cl`, `dl`, `sil`, `dil`, `r[8-15]b` | `q` | | x86 | `xmm_reg` | `xmm[0-7]` (x86) `xmm[0-15]` (x86-64) | `x` | | x86 | `ymm_reg` | `ymm[0-7]` (x86) `ymm[0-15]` (x86-64) | `x` | | x86 | `zmm_reg` | `zmm[0-7]` (x86) `zmm[0-31]` (x86-64) | `v` | @@ -526,7 +526,7 @@ Here is the list of currently supported register classes: > **Note**: On x86 we treat `reg_byte` differently from `reg` because the compiler can allocate `al` and `ah` separately whereas `reg` reserves the whole register. > -> Note #2: On x86-64 the high byte registers (e.g. `ah`) are only available when used as an explicit register. Specifying the `reg_byte` register class for an operand will always allocate a low byte register. +> Note #2: On x86-64 the high byte registers (e.g. `ah`) are not available in the `reg_byte` register class. > > Note #3: NVPTX doesn't have a fixed register set, so named registers are not supported. > diff --git a/src/test/assembly/asm/x86-types.rs b/src/test/assembly/asm/x86-types.rs index e0190d3bdae..b65b727d225 100644 --- a/src/test/assembly/asm/x86-types.rs +++ b/src/test/assembly/asm/x86-types.rs @@ -748,10 +748,11 @@ check_reg!(eax_f64 f64 "eax" "mov"); // CHECK: #NO_APP check_reg!(eax_ptr ptr "eax" "mov"); -// CHECK-LABEL: ah_byte: -// CHECK: #APP -// CHECK: mov ah, ah -// CHECK: #NO_APP +// i686-LABEL: ah_byte: +// i686: #APP +// i686: mov ah, ah +// i686: #NO_APP +#[cfg(i686)] check_reg!(ah_byte i8 "ah" "mov"); // CHECK-LABEL: xmm0_i32: diff --git a/src/test/ui/asm/bad-reg.rs b/src/test/ui/asm/bad-reg.rs index 016ea9329c4..da302b24876 100644 --- a/src/test/ui/asm/bad-reg.rs +++ b/src/test/ui/asm/bad-reg.rs @@ -37,6 +37,8 @@ fn main() { //~^ ERROR invalid register `mm0`: MMX registers are not currently supported as operands asm!("", in("k0") foo); //~^ ERROR invalid register `k0`: the k0 AVX mask register cannot be used as an operand + asm!("", in("ah") foo); + //~^ ERROR invalid register `ah`: high byte registers cannot be used as an operand // Explicit register conflicts // (except in/lateout which don't conflict) diff --git a/src/test/ui/asm/bad-reg.stderr b/src/test/ui/asm/bad-reg.stderr index c6b7d310dfa..2bfb4854c34 100644 --- a/src/test/ui/asm/bad-reg.stderr +++ b/src/test/ui/asm/bad-reg.stderr @@ -94,8 +94,14 @@ error: invalid register `k0`: the k0 AVX mask register cannot be used as an oper LL | asm!("", in("k0") foo); | ^^^^^^^^^^^^ +error: invalid register `ah`: high byte registers cannot be used as an operand on x86_64 + --> $DIR/bad-reg.rs:40:18 + | +LL | asm!("", in("ah") foo); + | ^^^^^^^^^^^^ + error: register `al` conflicts with register `ax` - --> $DIR/bad-reg.rs:44:33 + --> $DIR/bad-reg.rs:46:33 | LL | asm!("", in("eax") foo, in("al") bar); | ------------- ^^^^^^^^^^^^ register `al` @@ -103,7 +109,7 @@ LL | asm!("", in("eax") foo, in("al") bar); | register `ax` error: register `ax` conflicts with register `ax` - --> $DIR/bad-reg.rs:46:33 + --> $DIR/bad-reg.rs:48:33 | LL | asm!("", in("rax") foo, out("rax") bar); | ------------- ^^^^^^^^^^^^^^ register `ax` @@ -111,13 +117,13 @@ LL | asm!("", in("rax") foo, out("rax") bar); | register `ax` | help: use `lateout` instead of `out` to avoid conflict - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", in("rax") foo, out("rax") bar); | ^^^^^^^^^^^^^ error: register `ymm0` conflicts with register `xmm0` - --> $DIR/bad-reg.rs:49:34 + --> $DIR/bad-reg.rs:51:34 | LL | asm!("", in("xmm0") foo, in("ymm0") bar); | -------------- ^^^^^^^^^^^^^^ register `ymm0` @@ -125,7 +131,7 @@ LL | asm!("", in("xmm0") foo, in("ymm0") bar); | register `xmm0` error: register `ymm0` conflicts with register `xmm0` - --> $DIR/bad-reg.rs:51:34 + --> $DIR/bad-reg.rs:53:34 | LL | asm!("", in("xmm0") foo, out("ymm0") bar); | -------------- ^^^^^^^^^^^^^^^ register `ymm0` @@ -133,10 +139,10 @@ LL | asm!("", in("xmm0") foo, out("ymm0") bar); | register `xmm0` | help: use `lateout` instead of `out` to avoid conflict - --> $DIR/bad-reg.rs:51:18 + --> $DIR/bad-reg.rs:53:18 | LL | asm!("", in("xmm0") foo, out("ymm0") bar); | ^^^^^^^^^^^^^^ -error: aborting due to 18 previous errors +error: aborting due to 19 previous errors From 580a740bdd35706e487abd5beb76bd28f2be4012 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 22 Mar 2021 02:31:47 -0400 Subject: [PATCH 366/370] Add `download-rustc = "if-unchanged"` This allows keeping the setting to a fixed value without having to toggle it when you want to work on the compiler instead of on tools. --- config.toml.example | 4 +++- src/bootstrap/bootstrap.py | 8 +++++++- src/bootstrap/config.rs | 5 +++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/config.toml.example b/config.toml.example index ee06e1bd0ba..539ff06c5ad 100644 --- a/config.toml.example +++ b/config.toml.example @@ -372,7 +372,9 @@ changelog-seen = 2 # 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. # -# FIXME: currently, this also uses the downloaded compiler for stage0, but that causes unnecessary rebuilds. +# You can set this to "if-unchanged" to only download if `compiler/` has not been modified. +# +# FIXME(#82739): currently, this also uses the downloaded compiler for stage0, but that causes unnecessary rebuilds. #download-rustc = false # Number of codegen units to use for each compiler invocation. A value of 0 diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 3e7d1d54f12..59f22f3310c 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -638,8 +638,10 @@ class RustBuild(object): # Return the stage1 compiler to download, if any. def maybe_download_rustc(self): # If `download-rustc` is not set, default to rebuilding. - if self.get_toml("download-rustc", section="rust") != "true": + download_rustc = self.get_toml("download-rustc", section="rust") + if download_rustc is None or download_rustc == "false": return None + assert download_rustc == "true" or download_rustc == "if-unchanged", download_rustc # Handle running from a directory other than the top level rev_parse = ["git", "rev-parse", "--show-toplevel"] @@ -654,6 +656,8 @@ class RustBuild(object): # Warn if there were changes to the compiler since the ancestor commit. status = subprocess.call(["git", "diff-index", "--quiet", commit, "--", compiler]) if status != 0: + if download_rustc == "if-unchanged": + return None print("warning: `download-rustc` is enabled, but there are changes to compiler/") return commit @@ -1158,6 +1162,8 @@ def bootstrap(help_triggered): env["RUSTC_BOOTSTRAP"] = '1' if toml_path: env["BOOTSTRAP_CONFIG"] = toml_path + if build.rustc_commit is not None: + env["BOOTSTRAP_DOWNLOAD_RUSTC"] = '1' run(args, env=env, verbose=build.verbose) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index b9b090bb2d2..43ae146e866 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -510,7 +510,8 @@ struct Rust { new_symbol_mangling: Option, profile_generate: Option, profile_use: Option, - download_rustc: Option, + // ignored; this is set from an env var set by bootstrap.py + download_rustc: Option, } /// TOML representation of how each build target is configured. @@ -897,7 +898,7 @@ impl Config { config.rust_codegen_units_std = rust.codegen_units_std.map(threads_from_config); config.rust_profile_use = flags.rust_profile_use.or(rust.profile_use); config.rust_profile_generate = flags.rust_profile_generate.or(rust.profile_generate); - config.download_rustc = rust.download_rustc.unwrap_or(false); + config.download_rustc = env::var("BOOTSTRAP_DOWNLOAD_RUSTC").as_deref() == Ok("1"); } else { config.rust_profile_use = flags.rust_profile_use; config.rust_profile_generate = flags.rust_profile_generate; From f8653c9aca23317836277ef38decb2b220d9843d Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 4 Dec 2020 12:31:13 -0500 Subject: [PATCH 367/370] Add config file for tools enabling stage1 downloads by default Otherwise no one will be able to find the setting. --- src/bootstrap/defaults/config.compiler.toml | 3 +-- src/bootstrap/defaults/config.tools.toml | 16 ++++++++++++++++ src/bootstrap/setup.rs | 20 +++++++++++++++++--- 3 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 src/bootstrap/defaults/config.tools.toml diff --git a/src/bootstrap/defaults/config.compiler.toml b/src/bootstrap/defaults/config.compiler.toml index 0ca928843d5..883bfead64e 100644 --- a/src/bootstrap/defaults/config.compiler.toml +++ b/src/bootstrap/defaults/config.compiler.toml @@ -8,6 +8,5 @@ debug-logging = true incremental = true [llvm] -# Will download LLVM from CI if available on your platform (Linux only for now) -# https://github.com/rust-lang/rust/issues/77084 tracks support for more platforms +# Will download LLVM from CI if available on your platform. download-ci-llvm = "if-available" diff --git a/src/bootstrap/defaults/config.tools.toml b/src/bootstrap/defaults/config.tools.toml new file mode 100644 index 00000000000..182fb0fb067 --- /dev/null +++ b/src/bootstrap/defaults/config.tools.toml @@ -0,0 +1,16 @@ +# These defaults are meant for contributors to tools which build on the +# compiler, but do not modify it directly. +[rust] +# This enables `RUSTC_LOG=debug`, avoiding confusing situations +# where adding `debug!()` appears to do nothing. +# However, it makes running the compiler slightly slower. +debug-logging = true +# This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower. +incremental = true +# Download rustc from CI instead of building it from source. +# This cuts compile times by almost 60x, but means you can't modify the compiler. +download-rustc = "if-unchanged" + +[llvm] +# Will download LLVM from CI if available on your platform. +download-ci-llvm = "if-available" diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index 725147767db..a5829dfa9d8 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -13,6 +13,7 @@ pub enum Profile { Compiler, Codegen, Library, + Tools, User, } @@ -24,15 +25,16 @@ impl Profile { pub fn all() -> impl Iterator { use Profile::*; // N.B. these are ordered by how they are displayed, not alphabetically - [Library, Compiler, Codegen, User].iter().copied() + [Library, Compiler, Codegen, Tools, User].iter().copied() } pub fn purpose(&self) -> String { use Profile::*; match self { Library => "Contribute to the standard library", - Compiler => "Contribute to the compiler or rustdoc", + Compiler => "Contribute to the compiler itself", Codegen => "Contribute to the compiler, and also modify LLVM or codegen", + Tools => "Contribute to tools which depend on the compiler, but do not modify it directly (e.g. rustdoc, clippy, miri)", User => "Install Rust from source", } .to_string() @@ -53,9 +55,12 @@ impl FromStr for Profile { fn from_str(s: &str) -> Result { match s { "lib" | "library" => Ok(Profile::Library), - "compiler" | "rustdoc" => Ok(Profile::Compiler), + "compiler" => Ok(Profile::Compiler), "llvm" | "codegen" => Ok(Profile::Codegen), "maintainer" | "user" => Ok(Profile::User), + "tools" | "tool" | "rustdoc" | "clippy" | "miri" | "rustfmt" | "rls" => { + Ok(Profile::Tools) + } _ => Err(format!("unknown profile: '{}'", s)), } } @@ -68,6 +73,7 @@ impl fmt::Display for Profile { Profile::Codegen => write!(f, "codegen"), Profile::Library => write!(f, "library"), Profile::User => write!(f, "user"), + Profile::Tools => write!(f, "tools"), } } } @@ -103,6 +109,14 @@ pub fn setup(src_path: &Path, profile: Profile) { let suggestions = match profile { Profile::Codegen | Profile::Compiler => &["check", "build", "test"][..], + Profile::Tools => &[ + "check", + "build", + "test src/test/rustdoc*", + "test src/tools/clippy", + "test src/tools/miri", + "test src/tools/rustfmt", + ], Profile::Library => &["check", "build", "test library/std", "doc"], Profile::User => &["dist", "build"], }; From 448d07683a6defd567996114793a09c9a8aef5df Mon Sep 17 00:00:00 2001 From: Wesley Norris Date: Wed, 20 Jan 2021 21:49:04 -0500 Subject: [PATCH 368/370] Allow specifying alignment for functions --- compiler/rustc_attr/src/builtin.rs | 50 ++++++------------- compiler/rustc_codegen_llvm/src/attributes.rs | 3 ++ compiler/rustc_feature/src/active.rs | 3 ++ .../src/middle/codegen_fn_attrs.rs | 4 ++ compiler/rustc_passes/src/check_attr.rs | 46 ++++++++++++++--- compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_typeck/src/collect.rs | 32 ++++++++++++ src/test/codegen/align-fn.rs | 9 ++++ .../ui/attributes/nonterminal-expansion.rs | 1 - .../attributes/nonterminal-expansion.stderr | 14 +----- src/test/ui/error-codes/E0565.rs | 5 +- src/test/ui/error-codes/E0565.stderr | 8 +-- .../ui/feature-gates/feature-gate-fn_align.rs | 4 ++ .../feature-gate-fn_align.stderr | 12 +++++ src/test/ui/issues/issue-43988.rs | 4 +- src/test/ui/issues/issue-43988.stderr | 18 +++---- src/test/ui/repr/repr-disallow-on-variant.rs | 2 +- .../ui/repr/repr-disallow-on-variant.stderr | 4 +- 18 files changed, 137 insertions(+), 83 deletions(-) create mode 100644 src/test/codegen/align-fn.rs create mode 100644 src/test/ui/feature-gates/feature-gate-fn_align.rs create mode 100644 src/test/ui/feature-gates/feature-gate-fn_align.stderr diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index e58b266fdb9..20971ebb957 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -862,18 +862,6 @@ pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec { if let Some(items) = attr.meta_item_list() { sess.mark_attr_used(attr); for item in items { - if !item.is_meta_item() { - handle_errors( - &sess.parse_sess, - item.span(), - AttrError::UnsupportedLiteral( - "meta item in `repr` must be an identifier", - false, - ), - ); - continue; - } - let mut recognised = false; if item.is_word() { let hint = match item.name_or_empty() { @@ -890,23 +878,6 @@ pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec { acc.push(h); } } else if let Some((name, value)) = item.name_value_literal() { - let parse_alignment = |node: &ast::LitKind| -> Result { - if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node { - if literal.is_power_of_two() { - // rustc_middle::ty::layout::Align restricts align to <= 2^29 - if *literal <= 1 << 29 { - Ok(*literal as u32) - } else { - Err("larger than 2^29") - } - } else { - Err("not a power of two") - } - } else { - Err("not an unsuffixed integer") - } - }; - let mut literal_error = None; if name == sym::align { recognised = true; @@ -966,13 +937,7 @@ pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec { } if !recognised { // Not a word we recognize - struct_span_err!( - diagnostic, - item.span(), - E0552, - "unrecognized representation hint" - ) - .emit(); + diagnostic.delay_span_bug(item.span(), "unrecognized representation hint"); } } } @@ -1080,3 +1045,16 @@ fn allow_unstable<'a>( name }) } + +pub fn parse_alignment(node: &ast::LitKind) -> Result { + if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node { + if literal.is_power_of_two() { + // rustc_middle::ty::layout::Align restricts align to <= 2^29 + if *literal <= 1 << 29 { Ok(*literal as u32) } else { Err("larger than 2^29") } + } else { + Err("not a power of two") + } + } else { + Err("not an unsuffixed integer") + } +} diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 64ebe585dd8..e50a9d16ca4 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -279,6 +279,9 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY) { llvm::AddFunctionAttrString(llfn, Function, cstr!("cmse_nonsecure_entry")); } + if let Some(align) = codegen_fn_attrs.alignment { + llvm::set_alignment(llfn, align as usize); + } sanitize(cx, codegen_fn_attrs.no_sanitize, llfn); // Always annotate functions with the target-cpu they are compiled for. diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 040260f5cf5..b2d891b9674 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -645,6 +645,9 @@ declare_features! ( /// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries. (active, c_unwind, "1.52.0", Some(74990), None), + /// Allows using `#[repr(align(...))]` on function items + (active, fn_align, "1.53.0", Some(82232), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 5f2ffda642c..8f83589753d 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -38,6 +38,9 @@ pub struct CodegenFnAttrs { /// be generated against a specific instruction set. Only usable on architectures which allow /// switching between multiple instruction sets. pub instruction_set: Option, + /// The `#[repr(align(...))]` attribute. Indicates the value of which the function should be + /// aligned to. + pub alignment: Option, } bitflags! { @@ -103,6 +106,7 @@ impl CodegenFnAttrs { link_section: None, no_sanitize: SanitizerSet::empty(), instruction_set: None, + alignment: None, } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d1a3971f569..df292b14176 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1127,17 +1127,41 @@ impl CheckAttrVisitor<'tcx> { let mut is_transparent = false; for hint in &hints { + if !hint.is_meta_item() { + struct_span_err!( + self.tcx.sess, + hint.span(), + E0565, + "meta item in `repr` must be an identifier" + ) + .emit(); + continue; + } + let (article, allowed_targets) = match hint.name_or_empty() { - _ if !matches!(target, Target::Struct | Target::Enum | Target::Union) => { - ("a", "struct, enum, or union") - } - name @ sym::C | name @ sym::align => { - is_c |= name == sym::C; + sym::C => { + is_c = true; match target { Target::Struct | Target::Union | Target::Enum => continue, _ => ("a", "struct, enum, or union"), } } + sym::align => { + if let (Target::Fn, true) = (target, !self.tcx.features().fn_align) { + feature_err( + &self.tcx.sess.parse_sess, + sym::fn_align, + hint.span(), + "`repr(align)` attributes on functions are unstable", + ) + .emit(); + } + + match target { + Target::Struct | Target::Union | Target::Enum | Target::Fn => continue, + _ => ("a", "struct, enum, function, or union"), + } + } sym::packed => { if target != Target::Struct && target != Target::Union { ("a", "struct or union") @@ -1194,7 +1218,17 @@ impl CheckAttrVisitor<'tcx> { continue; } } - _ => continue, + _ => { + struct_span_err!( + self.tcx.sess, + hint.span(), + E0552, + "unrecognized representation hint" + ) + .emit(); + + continue; + } }; struct_span_err!( diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c5f929ab183..03fe5bcd297 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -561,6 +561,7 @@ symbols! { fmt, fmt_internals, fmul_fast, + fn_align, fn_must_use, fn_mut, fn_once, diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index afe52c97733..067b0e8cff8 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -15,6 +15,8 @@ //! At present, however, we do run collection across all items in the //! crate as a kind of pass. This should eventually be factored away. +// ignore-tidy-filelength + use crate::astconv::{AstConv, SizedByDefault}; use crate::bounds::Bounds; use crate::check::intrinsic::intrinsic_operation_unsafety; @@ -2884,6 +2886,36 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { None } }; + } else if tcx.sess.check_name(attr, 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, + }; } } diff --git a/src/test/codegen/align-fn.rs b/src/test/codegen/align-fn.rs new file mode 100644 index 00000000000..c5886cf2808 --- /dev/null +++ b/src/test/codegen/align-fn.rs @@ -0,0 +1,9 @@ +// compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 + +#![crate_type = "lib"] +#![feature(fn_align)] + +// CHECK: align 16 +#[no_mangle] +#[repr(align(16))] +pub fn fn_align() {} diff --git a/src/test/ui/attributes/nonterminal-expansion.rs b/src/test/ui/attributes/nonterminal-expansion.rs index b4f523936a0..d663431d683 100644 --- a/src/test/ui/attributes/nonterminal-expansion.rs +++ b/src/test/ui/attributes/nonterminal-expansion.rs @@ -3,7 +3,6 @@ macro_rules! pass_nonterminal { ($n:expr) => { #[repr(align($n))] //~ ERROR expected unsuffixed literal or identifier, found `n!()` - //~| ERROR unrecognized representation hint struct S; }; } diff --git a/src/test/ui/attributes/nonterminal-expansion.stderr b/src/test/ui/attributes/nonterminal-expansion.stderr index 9f7f185f947..75663a666a5 100644 --- a/src/test/ui/attributes/nonterminal-expansion.stderr +++ b/src/test/ui/attributes/nonterminal-expansion.stderr @@ -9,17 +9,5 @@ LL | pass_nonterminal!(n!()); | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0552]: unrecognized representation hint - --> $DIR/nonterminal-expansion.rs:5:16 - | -LL | #[repr(align($n))] - | ^^^^^^^^^ -... -LL | pass_nonterminal!(n!()); - | ------------------------ in this macro invocation - | - = note: this error originates in a macro (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 E0552`. diff --git a/src/test/ui/error-codes/E0565.rs b/src/test/ui/error-codes/E0565.rs index 3bf42867610..df76f6b13af 100644 --- a/src/test/ui/error-codes/E0565.rs +++ b/src/test/ui/error-codes/E0565.rs @@ -1,6 +1,5 @@ // repr currently doesn't support literals #[repr("C")] //~ ERROR E0565 - //~| ERROR E0565 -struct A { } +struct A {} -fn main() { } +fn main() {} diff --git a/src/test/ui/error-codes/E0565.stderr b/src/test/ui/error-codes/E0565.stderr index aa0951528e1..6ed90c0ae4f 100644 --- a/src/test/ui/error-codes/E0565.stderr +++ b/src/test/ui/error-codes/E0565.stderr @@ -4,12 +4,6 @@ error[E0565]: meta item in `repr` must be an identifier LL | #[repr("C")] | ^^^ -error[E0565]: meta item in `repr` must be an identifier - --> $DIR/E0565.rs:2:8 - | -LL | #[repr("C")] - | ^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0565`. diff --git a/src/test/ui/feature-gates/feature-gate-fn_align.rs b/src/test/ui/feature-gates/feature-gate-fn_align.rs new file mode 100644 index 00000000000..ea873dba269 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-fn_align.rs @@ -0,0 +1,4 @@ +#![crate_type = "lib"] + +#[repr(align(16))] //~ ERROR `repr(align)` attributes on functions are unstable +fn requires_alignment() {} diff --git a/src/test/ui/feature-gates/feature-gate-fn_align.stderr b/src/test/ui/feature-gates/feature-gate-fn_align.stderr new file mode 100644 index 00000000000..5ff124e48dc --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-fn_align.stderr @@ -0,0 +1,12 @@ +error[E0658]: `repr(align)` attributes on functions are unstable + --> $DIR/feature-gate-fn_align.rs:3:8 + | +LL | #[repr(align(16))] + | ^^^^^^^^^ + | + = note: see issue #82232 for more information + = help: add `#![feature(fn_align)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/issues/issue-43988.rs b/src/test/ui/issues/issue-43988.rs index 4b3a0269bae..b114e8e0333 100644 --- a/src/test/ui/issues/issue-43988.rs +++ b/src/test/ui/issues/issue-43988.rs @@ -13,13 +13,13 @@ fn main() { #[repr(nothing)] let _x = 0; - //~^^ ERROR attribute should be applied to a struct, enum, or union + //~^^ ERROR E0552 #[repr(something_not_real)] loop { () }; - //~^^^^ ERROR attribute should be applied to a struct, enum, or union + //~^^^^ ERROR E0552 #[repr] let _y = "123"; diff --git a/src/test/ui/issues/issue-43988.stderr b/src/test/ui/issues/issue-43988.stderr index f1205d447e4..03aa37f5207 100644 --- a/src/test/ui/issues/issue-43988.stderr +++ b/src/test/ui/issues/issue-43988.stderr @@ -26,23 +26,17 @@ LL | #[inline(XYZ)] LL | let _b = 4; | ----------- not a function or closure -error[E0517]: attribute should be applied to a struct, enum, or union +error[E0552]: unrecognized representation hint --> $DIR/issue-43988.rs:14:12 | LL | #[repr(nothing)] | ^^^^^^^ -LL | let _x = 0; - | ----------- not a struct, enum, or union -error[E0517]: attribute should be applied to a struct, enum, or union +error[E0552]: unrecognized representation hint --> $DIR/issue-43988.rs:18:12 | -LL | #[repr(something_not_real)] - | ^^^^^^^^^^^^^^^^^^ -LL | / loop { -LL | | () -LL | | }; - | |_____- not a struct, enum, or union +LL | #[repr(something_not_real)] + | ^^^^^^^^^^^^^^^^^^ error[E0518]: attribute should be applied to function or closure --> $DIR/issue-43988.rs:30:5 @@ -54,5 +48,5 @@ LL | foo(); error: aborting due to 7 previous errors -Some errors have detailed explanations: E0517, E0518. -For more information about an error, try `rustc --explain E0517`. +Some errors have detailed explanations: E0518, E0552. +For more information about an error, try `rustc --explain E0518`. diff --git a/src/test/ui/repr/repr-disallow-on-variant.rs b/src/test/ui/repr/repr-disallow-on-variant.rs index 90cad7e647b..d9bd0b0e38a 100644 --- a/src/test/ui/repr/repr-disallow-on-variant.rs +++ b/src/test/ui/repr/repr-disallow-on-variant.rs @@ -2,7 +2,7 @@ struct Test; enum Foo { #[repr(u8)] - //~^ ERROR attribute should be applied to a struct, enum, or union + //~^ ERROR attribute should be applied to an enum Variant, } diff --git a/src/test/ui/repr/repr-disallow-on-variant.stderr b/src/test/ui/repr/repr-disallow-on-variant.stderr index 70b45e393fc..f7e4dcc9d81 100644 --- a/src/test/ui/repr/repr-disallow-on-variant.stderr +++ b/src/test/ui/repr/repr-disallow-on-variant.stderr @@ -1,11 +1,11 @@ -error[E0517]: attribute should be applied to a struct, enum, or union +error[E0517]: attribute should be applied to an enum --> $DIR/repr-disallow-on-variant.rs:4:12 | LL | #[repr(u8)] | ^^ LL | LL | Variant, - | ------- not a struct, enum, or union + | ------- not an enum error: aborting due to previous error From 09ff88b600713a2bfca7cfdfd1828b519c907247 Mon Sep 17 00:00:00 2001 From: Camelid Date: Fri, 2 Apr 2021 19:56:18 -0700 Subject: [PATCH 369/370] Add `FromIterator` and `IntoIterator` impls for `ThinVec` These should make using `ThinVec` feel much more like using `Vec`. They will allow users of `Vec` to switch to `ThinVec` while continuing to use `collect()`, `for` loops, and other parts of the iterator API. I don't know if there were use cases before for using the iterator API with `ThinVec`, but I would like to start using `ThinVec` in rustdoc, and having it conform to the iterator API would make the transition *a lot* easier. I added a `FromIterator` impl, an `IntoIterator` impl that yields owned elements, and `IntoIterator` impls that yield immutable or mutable references to elements. I also added some unit tests for `ThinVec`. --- .../rustc_data_structures/src/thin_vec.rs | 49 +++++++++++++++++++ .../src/thin_vec/tests.rs | 42 ++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 compiler/rustc_data_structures/src/thin_vec/tests.rs diff --git a/compiler/rustc_data_structures/src/thin_vec.rs b/compiler/rustc_data_structures/src/thin_vec.rs index 4d673fd5cf9..00e30473498 100644 --- a/compiler/rustc_data_structures/src/thin_vec.rs +++ b/compiler/rustc_data_structures/src/thin_vec.rs @@ -1,5 +1,7 @@ use crate::stable_hasher::{HashStable, StableHasher}; +use std::iter::FromIterator; + /// A vector type optimized for cases where this size is usually 0 (cf. `SmallVector`). /// The `Option>` wrapping allows us to represent a zero sized vector with `None`, /// which uses only a single (null) pointer. @@ -10,6 +12,14 @@ impl ThinVec { pub fn new() -> Self { ThinVec(None) } + + pub fn iter(&self) -> std::slice::Iter<'_, T> { + self.into_iter() + } + + pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { + self.into_iter() + } } impl From> for ThinVec { @@ -46,6 +56,42 @@ impl ::std::ops::DerefMut for ThinVec { } } +impl FromIterator for ThinVec { + fn from_iter>(iter: I) -> Self { + // `Vec::from_iter()` should not allocate if the iterator is empty. + let vec: Vec<_> = iter.into_iter().collect(); + if vec.is_empty() { ThinVec(None) } else { ThinVec(Some(Box::new(vec))) } + } +} + +impl IntoIterator for ThinVec { + type Item = T; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + // This is still performant because `Vec::new()` does not allocate. + self.0.map_or_else(Vec::new, |ptr| *ptr).into_iter() + } +} + +impl<'a, T> IntoIterator for &'a ThinVec { + type Item = &'a T; + type IntoIter = std::slice::Iter<'a, T>; + + fn into_iter(self) -> Self::IntoIter { + self.as_ref().iter() + } +} + +impl<'a, T> IntoIterator for &'a mut ThinVec { + type Item = &'a mut T; + type IntoIter = std::slice::IterMut<'a, T>; + + fn into_iter(self) -> Self::IntoIter { + self.as_mut().iter_mut() + } +} + impl Extend for ThinVec { fn extend>(&mut self, iter: I) { match *self { @@ -80,3 +126,6 @@ impl Default for ThinVec { Self(None) } } + +#[cfg(test)] +mod tests; diff --git a/compiler/rustc_data_structures/src/thin_vec/tests.rs b/compiler/rustc_data_structures/src/thin_vec/tests.rs new file mode 100644 index 00000000000..5abfd939373 --- /dev/null +++ b/compiler/rustc_data_structures/src/thin_vec/tests.rs @@ -0,0 +1,42 @@ +use super::*; + +impl ThinVec { + fn into_vec(self) -> Vec { + self.into() + } +} + +#[test] +fn test_from_iterator() { + assert_eq!(std::iter::empty().collect::>().into_vec(), Vec::::new()); + assert_eq!(std::iter::once(42).collect::>().into_vec(), vec![42]); + assert_eq!(vec![1, 2].into_iter().collect::>().into_vec(), vec![1, 2]); + assert_eq!(vec![1, 2, 3].into_iter().collect::>().into_vec(), vec![1, 2, 3]); +} + +#[test] +fn test_into_iterator_owned() { + assert_eq!(ThinVec::new().into_iter().collect::>(), Vec::::new()); + assert_eq!(ThinVec::from(vec![1]).into_iter().collect::>(), vec![1]); + assert_eq!(ThinVec::from(vec![1, 2]).into_iter().collect::>(), vec![1, 2]); + assert_eq!(ThinVec::from(vec![1, 2, 3]).into_iter().collect::>(), vec![1, 2, 3]); +} + +#[test] +fn test_into_iterator_ref() { + assert_eq!(ThinVec::new().iter().collect::>(), Vec::<&String>::new()); + assert_eq!(ThinVec::from(vec![1]).iter().collect::>(), vec![&1]); + assert_eq!(ThinVec::from(vec![1, 2]).iter().collect::>(), vec![&1, &2]); + assert_eq!(ThinVec::from(vec![1, 2, 3]).iter().collect::>(), vec![&1, &2, &3]); +} + +#[test] +fn test_into_iterator_ref_mut() { + assert_eq!(ThinVec::new().iter_mut().collect::>(), Vec::<&mut String>::new()); + assert_eq!(ThinVec::from(vec![1]).iter_mut().collect::>(), vec![&mut 1]); + assert_eq!(ThinVec::from(vec![1, 2]).iter_mut().collect::>(), vec![&mut 1, &mut 2]); + assert_eq!( + ThinVec::from(vec![1, 2, 3]).iter_mut().collect::>(), + vec![&mut 1, &mut 2, &mut 3], + ); +} From bf11b12e398ce075e05e825d02c9c4ae48e0b266 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 6 Apr 2021 13:20:48 +0200 Subject: [PATCH 370/370] update Miri --- Cargo.lock | 94 ++++++++++++++++++++++++++------------------------ src/tools/miri | 2 +- 2 files changed, 50 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4bb32f842c2..2b7fbf1b647 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -582,7 +582,7 @@ dependencies = [ "cargo_metadata 0.12.0", "clippy-mini-macro-test", "clippy_lints", - "compiletest_rs 0.6.0", + "compiletest_rs", "derive-new", "quote", "regex", @@ -592,7 +592,7 @@ dependencies = [ "serde", "syn", "tempfile", - "tester 0.9.0", + "tester", ] [[package]] @@ -700,28 +700,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "compiletest_rs" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f737835bfbbe29ed1ff82d5137520338d7ed5bf1a1d4b9c1c7c58bb45b8fa29" -dependencies = [ - "diff", - "filetime", - "getopts", - "libc", - "log", - "miow 0.3.6", - "regex", - "rustfix", - "serde", - "serde_derive", - "serde_json", - "tempfile", - "tester 0.7.0", - "winapi 0.3.9", -] - [[package]] name = "compiletest_rs" version = "0.6.0" @@ -741,7 +719,7 @@ dependencies = [ "serde_derive", "serde_json", "tempfile", - "tester 0.9.0", + "tester", "winapi 0.3.9", ] @@ -1094,6 +1072,26 @@ dependencies = [ "log", ] +[[package]] +name = "enum-iterator" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c79a6321a1197d7730510c7e3f6cb80432dfefecb32426de8cea0aa19b4bb8d7" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e94aa31f7c0dc764f57896dc615ddd76fc13b0d5dca7eb6cc5e018a5a09ec06" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "env_logger" version = "0.6.2" @@ -1439,6 +1437,18 @@ dependencies = [ "wasi", ] +[[package]] +name = "getset" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b328c01a4d71d2d8173daa93562a73ab0fe85616876f02500f53d82948c504" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "gimli" version = "0.23.0" @@ -2304,13 +2314,13 @@ name = "miri" version = "0.1.0" dependencies = [ "colored", - "compiletest_rs 0.5.0", - "env_logger 0.7.1", + "compiletest_rs", + "env_logger 0.8.1", "getrandom 0.2.0", "hex 0.4.2", "libc", "log", - "rand 0.7.3", + "rand 0.8.3", "rustc-workspace-hack", "rustc_version", "shell-escape", @@ -4581,11 +4591,11 @@ dependencies = [ [[package]] name = "rustc_version" -version = "0.2.3" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" dependencies = [ - "semver 0.9.0", + "semver 0.11.0", ] [[package]] @@ -5231,17 +5241,6 @@ dependencies = [ "term 0.0.0", ] -[[package]] -name = "tester" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee72ec31009a42b53de9a6b7d8f462b493ab3b1e4767bda1fcdbb52127f13b6c" -dependencies = [ - "getopts", - "libc", - "term 0.6.1", -] - [[package]] name = "tester" version = "0.9.0" @@ -5676,12 +5675,17 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "vergen" -version = "3.1.0" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ce50d8996df1f85af15f2cd8d33daae6e479575123ef4314a51a70a230739cb" +checksum = "dfbc87f9a7a9d61b15d51d1d3547284f67b6b4f1494ce3fc5814c101f35a5183" dependencies = [ - "bitflags", + "anyhow", "chrono", + "enum-iterator", + "getset", + "git2", + "rustversion", + "thiserror", ] [[package]] diff --git a/src/tools/miri b/src/tools/miri index 2cdd1744b89..685ad70647c 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 2cdd1744b896e8129322229f253f95fd7ad491f1 +Subproject commit 685ad70647c867944128f6c6bacf9483995eff71