diff options
85 files changed, 1261 insertions, 774 deletions
diff --git a/Cargo.lock b/Cargo.lock index dce5357b12d..48518008b7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1502,9 +1502,9 @@ dependencies = [ [[package]] name = "git2" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e7d3b96ec1fcaa8431cf04a4f1ef5caafe58d5cf7bcc31f09c1626adddb0ffe" +checksum = "3826a6e0e2215d7a41c2bfc7c9244123969273f3476b939a226aac0ab56e9e3c" dependencies = [ "bitflags", "libc", @@ -1974,9 +1974,9 @@ dependencies = [ [[package]] name = "libgit2-sys" -version = "0.13.1+1.4.2" +version = "0.13.2+1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43e598aa7a4faedf1ea1b4608f582b06f0f40211eec551b7ef36019ae3f62def" +checksum = "3a42de9a51a5c12e00fc0e4ca6bc2ea43582fc6418488e8f615e905d886f258b" dependencies = [ "cc", "libc", diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 8a134bf7f96..8e748aaa58b 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -758,8 +758,7 @@ where if sess.is_nightly_build() { diag.help("add `#![feature(deprecated_suggestion)]` to the crate root"); } - // FIXME(jhpratt) change this to an actual tracking issue - diag.note("see #XXX for more details").emit(); + diag.note("see #94785 for more details").emit(); } if !get(mi, &mut suggestion) { @@ -772,10 +771,10 @@ where meta.span(), AttrError::UnknownMetaItem( pprust::path_to_string(&mi.path), - if attr.has_name(sym::deprecated) { - &["since", "note"] - } else { + if sess.features_untracked().deprecated_suggestion { &["since", "note", "suggestion"] + } else { + &["since", "note"] }, ), ); diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock index f15e319e3b8..30e9627c48d 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.lock +++ b/compiler/rustc_codegen_cranelift/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "anyhow" -version = "1.0.53" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" +checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" [[package]] name = "ar" @@ -15,9 +15,9 @@ source = "git+https://github.com/bjorn3/rust-ar.git?branch=do_not_remove_cg_clif [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" @@ -33,18 +33,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.81.0" +version = "0.82.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71447555acc6c875c52c407d572fc1327dc5c34cba72b4b2e7ad048aa4e4fd19" +checksum = "d16922317bd7dd104d509a373887822caa0242fc1def00de66abb538db221db4" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.81.0" +version = "0.82.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec9a10261891a7a919b0d4f6aa73582e88441d9a8f6173c88efbe4a5a362ea67" +checksum = "8b80bf40380256307b68a3dcbe1b91cac92a533e212b5b635abc3e4525781a0a" dependencies = [ "cranelift-bforest", "cranelift-codegen-meta", @@ -59,30 +59,30 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.81.0" +version = "0.82.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "815755d76fcbcf6e17ab888545b28ab775f917cb12ce0797e60cd41a2288692c" +checksum = "703d0ed7d3bc6c7a814ca12858175bf4e93167a3584127858c686e4b5dd6e432" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.81.0" +version = "0.82.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ea92f2a67335a2e4d3c9c65624c3b14ae287d595b0650822c41824febab66b" +checksum = "80f52311e1c90de12dcf8c4b9999c6ebfd1ed360373e88c357160936844511f6" [[package]] name = "cranelift-entity" -version = "0.81.0" +version = "0.82.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd25847875e388c500ad3624b4d2e14067955c93185194a7222246a25b91c975" +checksum = "66bc82ef522c1f643baf7d4d40b7c52643ee4549d8960b0e6a047daacb83f897" [[package]] name = "cranelift-frontend" -version = "0.81.0" +version = "0.82.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308bcfb7eb47bdf5ff6e1ace262af4ed39ec19f204c751fffb037e0e82a0c8bf" +checksum = "3cc35e4251864b17515845ba47447bca88fec9ca1a4186b19fe42526e36140e8" dependencies = [ "cranelift-codegen", "log", @@ -92,9 +92,9 @@ dependencies = [ [[package]] name = "cranelift-jit" -version = "0.81.0" +version = "0.82.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f560b3a314b8d15facf411e5d29b917c3e787a2bbc3fcdc5183bc0c5b7d4fe01" +checksum = "93c66d594ad3bfe4e58b1fbd8d17877a7c6564a5f2d6f78cbbf4b0182af1927f" dependencies = [ "anyhow", "cranelift-codegen", @@ -110,9 +110,9 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.81.0" +version = "0.82.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a57aba9e603d694d1430ff38bd914bae23ef9c2e44b25a65e318905807e654c" +checksum = "bf356697c40232aa09e1e3fb8a350ee894e849ccecc4eac56ff0570a4575c325" dependencies = [ "anyhow", "cranelift-codegen", @@ -120,9 +120,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.81.0" +version = "0.82.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cdc799aee673be2317e631d4569a1ba0a7e77a07a7ce45557086d2e02e9514" +checksum = "b882b2251c9845d509d92aebfdb6c8bb3b3b48e207ac951f21fbd20cfe7f90b3" dependencies = [ "cranelift-codegen", "libc", @@ -131,9 +131,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.81.0" +version = "0.82.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502a7333836052fcdf4425d7f7a21264d99f862d32b9c3a0e47cd920487a9b60" +checksum = "2d3f1a88e654e567d2591169239ed157ab290811a729a6468f53999c01001263" dependencies = [ "anyhow", "cranelift-codegen", @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2209c310e29876f7f0b2721e7e26b84aff178aa3da5d091f9bfbf47669e60e3" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", ] @@ -179,9 +179,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.116" +version = "0.2.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "565dbd88872dbe4cc8a46e527f26483c1d1f7afa6b884a3bd6cd893d4f98da74" +checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" [[package]] name = "libloading" @@ -229,6 +229,12 @@ dependencies = [ ] [[package]] +name = "once_cell" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" + +[[package]] name = "regalloc" version = "0.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -272,6 +278,7 @@ dependencies = [ "indexmap", "libloading", "object", + "once_cell", "smallvec", "target-lexicon", ] @@ -284,9 +291,9 @@ checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "target-lexicon" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9bffcddbc2458fa3e6058414599e3c838a022abae82e5c67b4f7f80298d5bff" +checksum = "d7fa7e55043acb85fca6b3c01485a2eeb6b69c5d21002e273c79e465f43b7ac1" [[package]] name = "winapi" diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml index 178404af42d..70c03da3f29 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.toml +++ b/compiler/rustc_codegen_cranelift/Cargo.toml @@ -8,12 +8,12 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.81.0", features = ["unwind", "all-arch"] } -cranelift-frontend = "0.81.0" -cranelift-module = "0.81.0" -cranelift-native = "0.81.0" -cranelift-jit = { version = "0.81.0", optional = true } -cranelift-object = "0.81.0" +cranelift-codegen = { version = "0.82.1", features = ["unwind", "all-arch"] } +cranelift-frontend = "0.82.1" +cranelift-module = "0.82.1" +cranelift-native = "0.82.1" +cranelift-jit = { version = "0.82.1", optional = true } +cranelift-object = "0.82.1" target-lexicon = "0.12.0" gimli = { version = "0.26.0", default-features = false, features = ["write"]} object = { version = "0.27.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } @@ -21,6 +21,7 @@ object = { version = "0.27.0", default-features = false, features = ["std", "rea ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" } indexmap = "1.8.0" libloading = { version = "0.6.0", optional = true } +once_cell = "1.10.0" smallvec = "1.6.1" [patch.crates-io] diff --git a/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock b/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock index b9786395142..f584f54e106 100644 --- a/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock +++ b/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock @@ -56,7 +56,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.70" +version = "0.1.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "163437f05ca8f29d7e9128ea728dedf5eb620e445fbca273641d3a3050305f23" dependencies = [ "rustc-std-workspace-core", ] @@ -132,9 +134,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.119" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" +checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" dependencies = [ "rustc-std-workspace-core", ] diff --git a/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.toml b/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.toml index f25d87e60c0..d0e5fc4a3b9 100644 --- a/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.toml +++ b/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.toml @@ -14,7 +14,6 @@ compiler_builtins = { version = "0.1.39", default-features = false, features = [ rustc-std-workspace-core = { path = "./sysroot_src/library/rustc-std-workspace-core" } rustc-std-workspace-alloc = { path = "./sysroot_src/library/rustc-std-workspace-alloc" } rustc-std-workspace-std = { path = "./sysroot_src/library/rustc-std-workspace-std" } -compiler_builtins = { path = "./compiler-builtins" } [profile.dev] lto = "off" @@ -23,3 +22,14 @@ lto = "off" debug = true incremental = true lto = "off" + +# Mandatory for correctly compiling compiler-builtins +[profile.dev.package.compiler_builtins] +debug-assertions = false +overflow-checks = false +codegen-units = 10000 + +[profile.release.package.compiler_builtins] +debug-assertions = false +overflow-checks = false +codegen-units = 10000 diff --git a/compiler/rustc_codegen_cranelift/build_system/prepare.rs b/compiler/rustc_codegen_cranelift/build_system/prepare.rs index 4a7df2cebbc..8bb00352d3f 100644 --- a/compiler/rustc_codegen_cranelift/build_system/prepare.rs +++ b/compiler/rustc_codegen_cranelift/build_system/prepare.rs @@ -14,29 +14,33 @@ pub(crate) fn prepare() { eprintln!("[INSTALL] hyperfine"); Command::new("cargo").arg("install").arg("hyperfine").spawn().unwrap().wait().unwrap(); - clone_repo( + clone_repo_shallow_github( + "rand", + "rust-random", "rand", - "https://github.com/rust-random/rand.git", "0f933f9c7176e53b2a3c7952ded484e1783f0bf1", ); apply_patches("rand", Path::new("rand")); - clone_repo( + clone_repo_shallow_github( + "regex", + "rust-lang", "regex", - "https://github.com/rust-lang/regex.git", "341f207c1071f7290e3f228c710817c280c8dca1", ); - clone_repo( + clone_repo_shallow_github( + "portable-simd", + "rust-lang", "portable-simd", - "https://github.com/rust-lang/portable-simd", "b8d6b6844602f80af79cd96401339ec594d472d8", ); apply_patches("portable-simd", Path::new("portable-simd")); - clone_repo( + clone_repo_shallow_github( + "simple-raytracer", + "ebobby", "simple-raytracer", - "https://github.com/ebobby/simple-raytracer", "804a7a21b9e673a482797aa289a18ed480e4d813", ); @@ -74,29 +78,12 @@ fn prepare_sysroot() { git_init_cmd.arg("init").arg("-q").current_dir(&sysroot_src); spawn_and_wait(git_init_cmd); - let mut git_add_cmd = Command::new("git"); - git_add_cmd.arg("add").arg(".").current_dir(&sysroot_src); - spawn_and_wait(git_add_cmd); - - let mut git_commit_cmd = Command::new("git"); - git_commit_cmd - .arg("commit") - .arg("-m") - .arg("Initial commit") - .arg("-q") - .current_dir(&sysroot_src); - spawn_and_wait(git_commit_cmd); + init_git_repo(&sysroot_src); apply_patches("sysroot", &sysroot_src); - - clone_repo( - "build_sysroot/compiler-builtins", - "https://github.com/rust-lang/compiler-builtins.git", - "0.1.70", - ); - apply_patches("compiler-builtins", Path::new("build_sysroot/compiler-builtins")); } +#[allow(dead_code)] fn clone_repo(target_dir: &str, repo: &str, rev: &str) { eprintln!("[CLONE] {}", repo); // Ignore exit code as the repo may already have been checked out @@ -111,6 +98,57 @@ fn clone_repo(target_dir: &str, repo: &str, rev: &str) { spawn_and_wait(checkout_cmd); } +fn clone_repo_shallow_github(target_dir: &str, username: &str, repo: &str, rev: &str) { + if cfg!(windows) { + // Older windows doesn't have tar or curl by default. Fall back to using git. + clone_repo(target_dir, &format!("https://github.com/{}/{}.git", username, repo), rev); + return; + } + + let archive_url = format!("https://github.com/{}/{}/archive/{}.tar.gz", username, repo, rev); + let archive_file = format!("{}.tar.gz", rev); + let archive_dir = format!("{}-{}", repo, rev); + + eprintln!("[DOWNLOAD] {}/{} from {}", username, repo, archive_url); + + // Remove previous results if they exists + let _ = std::fs::remove_file(&archive_file); + let _ = std::fs::remove_dir_all(&archive_dir); + let _ = std::fs::remove_dir_all(target_dir); + + // Download zip archive + let mut download_cmd = Command::new("curl"); + download_cmd.arg("--location").arg("--output").arg(&archive_file).arg(archive_url); + spawn_and_wait(download_cmd); + + // Unpack tar archive + let mut unpack_cmd = Command::new("tar"); + unpack_cmd.arg("xf").arg(&archive_file); + spawn_and_wait(unpack_cmd); + + // Rename unpacked dir to the expected name + std::fs::rename(archive_dir, target_dir).unwrap(); + + init_git_repo(Path::new(target_dir)); + + // Cleanup + std::fs::remove_file(archive_file).unwrap(); +} + +fn init_git_repo(repo_dir: &Path) { + let mut git_init_cmd = Command::new("git"); + git_init_cmd.arg("init").arg("-q").current_dir(repo_dir); + spawn_and_wait(git_init_cmd); + + let mut git_add_cmd = Command::new("git"); + git_add_cmd.arg("add").arg(".").current_dir(repo_dir); + spawn_and_wait(git_add_cmd); + + let mut git_commit_cmd = Command::new("git"); + git_commit_cmd.arg("commit").arg("-m").arg("Initial commit").arg("-q").current_dir(repo_dir); + spawn_and_wait(git_commit_cmd); +} + fn get_patches(crate_name: &str) -> Vec<OsString> { let mut patches: Vec<_> = fs::read_dir("patches") .unwrap() diff --git a/compiler/rustc_codegen_cranelift/example/alloc_system.rs b/compiler/rustc_codegen_cranelift/example/alloc_system.rs index 5f66ca67f2d..cf95c89bc31 100644 --- a/compiler/rustc_codegen_cranelift/example/alloc_system.rs +++ b/compiler/rustc_codegen_cranelift/example/alloc_system.rs @@ -8,33 +8,21 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. #![no_std] -#![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")))] -const MIN_ALIGN: usize = 8; -#[cfg(all(any(target_arch = "x86_64", - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "s390x", - target_arch = "sparc64")))] -const MIN_ALIGN: usize = 16; pub struct System; + #[cfg(any(windows, unix, target_os = "redox"))] mod realloc_fallback { use core::alloc::{GlobalAlloc, Layout}; use core::cmp; use core::ptr; impl super::System { - pub(crate) unsafe fn realloc_fallback(&self, ptr: *mut u8, old_layout: Layout, - new_size: usize) -> *mut u8 { + pub(crate) unsafe fn realloc_fallback( + &self, + ptr: *mut u8, + old_layout: Layout, + new_size: usize, + ) -> *mut u8 { // Docs for GlobalAlloc::realloc require this to be valid: let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align()); let new_ptr = GlobalAlloc::alloc(self, new_layout); @@ -49,97 +37,47 @@ mod realloc_fallback { } #[cfg(any(unix, target_os = "redox"))] mod platform { - extern crate libc; + use core::alloc::{GlobalAlloc, Layout}; + use core::ffi::c_void; use core::ptr; - use MIN_ALIGN; use System; - use core::alloc::{GlobalAlloc, Layout}; + extern "C" { + fn posix_memalign(memptr: *mut *mut c_void, align: usize, size: usize) -> i32; + fn free(p: *mut c_void); + } unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - libc::malloc(layout.size()) as *mut u8 - } else { - #[cfg(target_os = "macos")] - { - if layout.align() > (1 << 31) { - return ptr::null_mut() - } - } - aligned_malloc(&layout) - } + aligned_malloc(&layout) } #[inline] unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - libc::calloc(layout.size(), 1) as *mut u8 - } else { - let ptr = self.alloc(layout.clone()); - if !ptr.is_null() { - ptr::write_bytes(ptr, 0, layout.size()); - } - ptr + let ptr = self.alloc(layout.clone()); + if !ptr.is_null() { + ptr::write_bytes(ptr, 0, layout.size()); } + ptr } #[inline] unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { - libc::free(ptr as *mut libc::c_void) + free(ptr as *mut c_void) } #[inline] unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - if layout.align() <= MIN_ALIGN && layout.align() <= new_size { - libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 - } else { - self.realloc_fallback(ptr, layout, new_size) - } + self.realloc_fallback(ptr, layout, new_size) } } - #[cfg(any(target_os = "android", - target_os = "hermit", - target_os = "redox", - target_os = "solaris"))] - #[inline] - unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { - // On android we currently target API level 9 which unfortunately - // doesn't have the `posix_memalign` API used below. Instead we use - // `memalign`, but this unfortunately has the property on some systems - // where the memory returned cannot be deallocated by `free`! - // - // Upon closer inspection, however, this appears to work just fine with - // Android, so for this platform we should be fine to call `memalign` - // (which is present in API level 9). Some helpful references could - // possibly be chromium using memalign [1], attempts at documenting that - // memalign + free is ok [2] [3], or the current source of chromium - // which still uses memalign on android [4]. - // - // [1]: https://codereview.chromium.org/10796020/ - // [2]: https://code.google.com/p/android/issues/detail?id=35391 - // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579 - // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/ - // /memory/aligned_memory.cc - libc::memalign(layout.align(), layout.size()) as *mut u8 - } - #[cfg(not(any(target_os = "android", - target_os = "hermit", - target_os = "redox", - target_os = "solaris")))] - #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); - let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); - if ret != 0 { - ptr::null_mut() - } else { - out as *mut u8 - } + let ret = posix_memalign(&mut out, layout.align(), layout.size()); + if ret != 0 { ptr::null_mut() } else { out as *mut u8 } } } #[cfg(windows)] #[allow(nonstandard_style)] mod platform { - use MIN_ALIGN; - use System; use core::alloc::{GlobalAlloc, Layout}; + use System; type LPVOID = *mut u8; type HANDLE = LPVOID; type SIZE_T = usize; @@ -165,18 +103,9 @@ mod platform { } #[inline] unsafe fn allocate_with_flags(layout: Layout, flags: DWORD) -> *mut u8 { - let ptr = if layout.align() <= MIN_ALIGN { - HeapAlloc(GetProcessHeap(), flags, layout.size()) - } else { - let size = layout.size() + layout.align(); - let ptr = HeapAlloc(GetProcessHeap(), flags, size); - if ptr.is_null() { - ptr - } else { - align_ptr(ptr, layout.align()) - } - }; - ptr as *mut u8 + let size = layout.size() + layout.align(); + let ptr = HeapAlloc(GetProcessHeap(), flags, size); + (if ptr.is_null() { ptr } else { align_ptr(ptr, layout.align()) }) as *mut u8 } unsafe impl GlobalAlloc for System { #[inline] @@ -189,24 +118,13 @@ mod platform { } #[inline] unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - if layout.align() <= MIN_ALIGN { - let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID); - debug_assert!(err != 0, "Failed to free heap memory: {}", - GetLastError()); - } else { - let header = get_header(ptr); - let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID); - debug_assert!(err != 0, "Failed to free heap memory: {}", - GetLastError()); - } + let header = get_header(ptr); + let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID); + debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError()); } #[inline] unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - if layout.align() <= MIN_ALIGN { - HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, new_size) as *mut u8 - } else { - self.realloc_fallback(ptr, layout, new_size) - } + self.realloc_fallback(ptr, layout, new_size) } } } diff --git a/compiler/rustc_codegen_cranelift/example/arbitrary_self_types_pointers_and_wrappers.rs b/compiler/rustc_codegen_cranelift/example/arbitrary_self_types_pointers_and_wrappers.rs index ddeb752f93e..e9876837dd8 100644 --- a/compiler/rustc_codegen_cranelift/example/arbitrary_self_types_pointers_and_wrappers.rs +++ b/compiler/rustc_codegen_cranelift/example/arbitrary_self_types_pointers_and_wrappers.rs @@ -1,7 +1,6 @@ // Adapted from rustc run-pass test suite #![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)] -#![feature(rustc_attrs)] use std::{ ops::{Deref, CoerceUnsized, DispatchFromDyn}, diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index c4834c80408..7efc8dc785a 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -1,7 +1,14 @@ #![feature( - no_core, lang_items, intrinsics, unboxed_closures, type_ascription, extern_types, - untagged_unions, decl_macro, rustc_attrs, transparent_unions, auto_traits, - thread_local, + no_core, + lang_items, + intrinsics, + unboxed_closures, + extern_types, + decl_macro, + rustc_attrs, + transparent_unions, + auto_traits, + thread_local )] #![no_core] #![allow(dead_code)] @@ -55,6 +62,7 @@ unsafe impl Copy for i16 {} unsafe impl Copy for i32 {} unsafe impl Copy for isize {} unsafe impl Copy for f32 {} +unsafe impl Copy for f64 {} unsafe impl Copy for char {} unsafe impl<'a, T: ?Sized> Copy for &'a T {} unsafe impl<T: ?Sized> Copy for *const T {} @@ -483,8 +491,17 @@ pub trait Deref { fn deref(&self) -> &Self::Target; } +pub struct Unique<T: ?Sized> { + pub pointer: *const T, + pub _marker: PhantomData<T>, +} + +impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} + +impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} + #[lang = "owned_box"] -pub struct Box<T: ?Sized>(*mut T); +pub struct Box<T: ?Sized>(Unique<T>, ()); impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {} @@ -508,8 +525,8 @@ unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { } #[lang = "box_free"] -unsafe fn box_free<T: ?Sized>(ptr: *mut T) { - libc::free(ptr as *mut u8); +unsafe fn box_free<T: ?Sized>(ptr: Unique<T>, alloc: ()) { + libc::free(ptr.pointer as *mut u8); } #[lang = "drop"] diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs index ef3b575d393..c4730581335 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs @@ -7,10 +7,6 @@ extern crate mini_core; use mini_core::*; use mini_core::libc::*; -unsafe extern "C" fn my_puts(s: *const i8) { - puts(s); -} - macro_rules! assert { ($e:expr) => { if !$e { @@ -105,12 +101,6 @@ fn start<T: Termination + 'static>( static mut NUM: u8 = 6 * 7; static NUM_REF: &'static u8 = unsafe { &NUM }; -struct Unique<T: ?Sized> { - pointer: *const T, - _marker: PhantomData<T>, -} - -impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} unsafe fn zeroed<T>() -> T { let mut uninit = MaybeUninit { uninit: () }; diff --git a/compiler/rustc_codegen_cranelift/patches/0001-compiler-builtins-Disable-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0001-compiler-builtins-Disable-128bit-atomic-operations.patch deleted file mode 100644 index 460e42d1d8c..00000000000 --- a/compiler/rustc_codegen_cranelift/patches/0001-compiler-builtins-Disable-128bit-atomic-operations.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 1d574bf5e32d51641dcacaf8ef777e95b44f6f2a Mon Sep 17 00:00:00 2001 -From: bjorn3 <bjorn3@users.noreply.github.com> -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 unsafe 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 unsafe 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 unsafe extern "C" fn __llvm_memmove_element_unordered_atomic_1(dest: *mut u8, src: *const u8, bytes: usize) -> () { -@@ -158,10 +154,6 @@ intrinsics! { - pub unsafe 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 unsafe 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 unsafe extern "C" fn __llvm_memset_element_unordered_atomic_1(s: *mut u8, c: u8, bytes: usize) -> () { -@@ -179,8 +171,4 @@ intrinsics! { - pub unsafe 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 unsafe 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/compiler/rustc_codegen_cranelift/patches/0001-rand-Enable-c2-chacha-simd-feature.patch b/compiler/rustc_codegen_cranelift/patches/0001-rand-Enable-c2-chacha-simd-feature.patch deleted file mode 100644 index 01dc0fcc537..00000000000 --- a/compiler/rustc_codegen_cranelift/patches/0001-rand-Enable-c2-chacha-simd-feature.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 9c5663e36391fa20becf84f3af2e82afa5bb720b Mon Sep 17 00:00:00 2001 -From: bjorn3 <bjorn3@users.noreply.github.com> -Date: Sat, 15 Aug 2020 19:56:03 +0200 -Subject: [PATCH] [rand] Enable c2-chacha simd feature - ---- - rand_chacha/Cargo.toml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/rand_chacha/Cargo.toml b/rand_chacha/Cargo.toml -index 9190b7f..872cca2 100644 ---- a/rand_chacha/Cargo.toml -+++ b/rand_chacha/Cargo.toml -@@ -24,5 +24,5 @@ ppv-lite86 = { version = "0.2.8", default-features = false } - - [features] - default = ["std"] --std = ["ppv-lite86/std"] -+std = ["ppv-lite86/std", "ppv-lite86/simd"] - simd = [] # deprecated --- -2.20.1 - diff --git a/compiler/rustc_codegen_cranelift/patches/0002-rand-Disable-failing-test.patch b/compiler/rustc_codegen_cranelift/patches/0002-rand-Disable-failing-test.patch index 19fd20d7269..ae13ab3b0ca 100644 --- a/compiler/rustc_codegen_cranelift/patches/0002-rand-Disable-failing-test.patch +++ b/compiler/rustc_codegen_cranelift/patches/0002-rand-Disable-failing-test.patch @@ -4,27 +4,18 @@ Date: Sat, 15 Aug 2020 20:04:38 +0200 Subject: [PATCH] [rand] Disable failing test --- - src/distributions/uniform.rs | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) + src/distributions/uniform.rs | 1 + + 1 file changed, 1 insertion(+), 0 deletions(-) diff --git a/src/distributions/uniform.rs b/src/distributions/uniform.rs index 480b859..c80bb6f 100644 --- a/src/distributions/uniform.rs +++ b/src/distributions/uniform.rs -@@ -1085,7 +1085,7 @@ mod tests { - _ => panic!("`UniformDurationMode` was not serialized/deserialized correctly") - } - } -- -+ - #[test] - #[cfg(feature = "serde1")] - fn test_uniform_serialization() { @@ -1314,6 +1314,7 @@ mod tests { not(target_arch = "wasm32"), not(target_arch = "asmjs") ))] -+ #[ignore] // FIXME ++ #[ignore] // Requires unwinding fn test_float_assertions() { use super::SampleUniform; use std::panic::catch_unwind; diff --git a/compiler/rustc_codegen_cranelift/patches/0022-sysroot-Disable-not-compiling-tests.patch b/compiler/rustc_codegen_cranelift/patches/0022-sysroot-Disable-not-compiling-tests.patch index 1c45c7573c8..108a97bd7c6 100644 --- a/compiler/rustc_codegen_cranelift/patches/0022-sysroot-Disable-not-compiling-tests.patch +++ b/compiler/rustc_codegen_cranelift/patches/0022-sysroot-Disable-not-compiling-tests.patch @@ -18,7 +18,7 @@ new file mode 100644 index 0000000..46fd999 --- /dev/null +++ b/library/core/tests/Cargo.toml -@@ -0,0 +1,8 @@ +@@ -0,0 +1,11 @@ +[package] +name = "core" +version = "0.0.0" @@ -27,18 +27,9 @@ index 0000000..46fd999 +[lib] +name = "coretests" +path = "lib.rs" -diff --git a/library/core/tests/num/flt2dec/mod.rs b/library/core/tests/num/flt2dec/mod.rs -index a35897e..f0bf645 100644 ---- a/library/core/tests/num/flt2dec/mod.rs -+++ b/library/core/tests/num/flt2dec/mod.rs -@@ -13,7 +13,6 @@ mod strategy { - mod dragon; - mod grisu; - } --mod random; - - pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded { - match decode(v).1 { ++ ++[dependencies] ++rand = "0.7" diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs index 1a6be3a..42dbd59 100644 --- a/library/core/tests/ptr.rs @@ -59,25 +50,5 @@ index 1a6be3a..42dbd59 100644 #[test] fn write_unaligned_drop() { -diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs -index 6609bc3..241b497 100644 ---- a/library/core/tests/slice.rs -+++ b/library/core/tests/slice.rs -@@ -1209,6 +1209,7 @@ fn brute_force_rotate_test_1() { - } - } - -+/* - #[test] - #[cfg(not(target_arch = "wasm32"))] - fn sort_unstable() { -@@ -1394,6 +1395,7 @@ fn partition_at_index() { - v.select_nth_unstable(0); - assert!(v == [0xDEADBEEF]); - } -+*/ - - #[test] - #[should_panic(expected = "index 0 greater than length of slice")] -- 2.21.0 (Apple Git-122) diff --git a/compiler/rustc_codegen_cranelift/patches/0028-sysroot-Disable-long-running-tests.patch b/compiler/rustc_codegen_cranelift/patches/0028-sysroot-Disable-long-running-tests.patch index bf74a74c7c4..d804a78cc10 100644 --- a/compiler/rustc_codegen_cranelift/patches/0028-sysroot-Disable-long-running-tests.patch +++ b/compiler/rustc_codegen_cranelift/patches/0028-sysroot-Disable-long-running-tests.patch @@ -1,30 +1,48 @@ -From 0ffdd8eda8df364391c8ac6e1ce92c73ba9254d4 Mon Sep 17 00:00:00 2001 +From eb703e627e7a84f1cd8d0d87f0f69da1f0acf765 Mon Sep 17 00:00:00 2001 From: bjorn3 <bjorn3@users.noreply.github.com> Date: Fri, 3 Dec 2021 12:16:30 +0100 Subject: [PATCH] Disable long running tests --- - library/core/tests/slice.rs | 3 +++ - 1 file changed, 3 insertions(+) + library/core/tests/slice.rs | 2 ++ + 1 file changed, 2 insertions(+) diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs -index 2c8f00a..44847ee 100644 +index 8402833..84592e0 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs -@@ -2332,7 +2332,8 @@ macro_rules! empty_max_mut { - }; +@@ -1809,6 +1809,7 @@ fn sort_unstable() { + assert!(v == [0xDEADBEEF]); } +/* - #[cfg(not(miri))] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations) - take_tests! { - slice: &[(); usize::MAX], method: take, - (take_in_bounds_max_range_to, (..usize::MAX), Some(EMPTY_MAX), &[(); 0]), -@@ -2345,3 +2347,4 @@ take_tests! { + #[test] + #[cfg(not(target_arch = "wasm32"))] + #[cfg_attr(miri, ignore)] // Miri is too slow +@@ -1914,6 +1915,7 @@ fn select_nth_unstable() { + v.select_nth_unstable(0); + assert!(v == [0xDEADBEEF]); + } ++*/ + + #[test] + #[should_panic(expected = "index 0 greater than length of slice")] +@@ -2462,6 +2462,7 @@ take_tests! { + #[cfg(not(miri))] // unused in Miri + const EMPTY_MAX: &'static [()] = &[(); usize::MAX]; + ++/* + // can't be a constant due to const mutability rules + #[cfg(not(miri))] // unused in Miri + macro_rules! empty_max_mut { +@@ -2485,6 +2486,7 @@ take_tests! { (take_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()), (take_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()), } +*/ + + #[test] + fn test_slice_from_ptr_range() { -- 2.26.2.7.g19db9cfb68 diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain index 1019b1f069e..84d90e5db02 100644 --- a/compiler/rustc_codegen_cranelift/rust-toolchain +++ b/compiler/rustc_codegen_cranelift/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2022-02-23" +channel = "nightly-2022-03-19" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh index 73600faa1e9..85c0109c6f6 100644 --- a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh +++ b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh @@ -12,18 +12,6 @@ git checkout -- . git checkout "$(rustc -V | cut -d' ' -f3 | tr -d '(')" git apply - <<EOF -diff --git a/Cargo.toml b/Cargo.toml -index 5bd1147cad5..10d68a2ff14 100644 ---- a/Cargo.toml -+++ b/Cargo.toml -@@ -111,5 +111,7 @@ rustc-std-workspace-std = { path = 'library/rustc-std-workspace-std' } - rustc-std-workspace-alloc = { path = 'library/rustc-std-workspace-alloc' } - rustc-std-workspace-std = { path = 'library/rustc-std-workspace-std' } - -+compiler_builtins = { path = "../build_sysroot/compiler-builtins" } -+ - [patch."https://github.com/rust-lang/rust-clippy"] - clippy_lints = { path = "src/tools/clippy/clippy_lints" } diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index d95b5b7f17f..00b6f0e3635 100644 --- a/library/alloc/Cargo.toml @@ -38,9 +26,43 @@ index d95b5b7f17f..00b6f0e3635 100644 [dev-dependencies] rand = "0.7" rand_xorshift = "0.2" +diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs +index 887d27fd6dca4..2c2239f2b83d1 100644 +--- a/src/tools/compiletest/src/header.rs ++++ b/src/tools/compiletest/src/header.rs +@@ -806,8 +806,8 @@ pub fn make_test_description<R: Read>( + cfg: Option<&str>, + ) -> test::TestDesc { + let mut ignore = false; + #[cfg(not(bootstrap))] +- let ignore_message: Option<String> = None; ++ let ignore_message: Option<&str> = None; + let mut should_fail = false; + + let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some(); + +diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs +index 8431aa7b818..a3ff7e68ce5 100644 +--- a/src/tools/compiletest/src/runtest.rs ++++ b/src/tools/compiletest/src/runtest.rs +@@ -3489,11 +3489,7 @@ fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> S + .join("library"); + normalize_path(&src_dir, "$(echo '$SRC_DIR')"); + +- if let Some(virtual_rust_source_base_dir) = +- option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from) +- { +- normalize_path(&virtual_rust_source_base_dir.join("library"), "$(echo '$SRC_DIR')"); +- } ++ normalize_path(&Path::new("$(cd ../build_sysroot/sysroot_src/library; pwd)"), "$(echo '$SRC_DIR')"); + + // Paths into the build directory + let test_build_dir = &self.config.build_base; EOF cat > config.toml <<EOF +changelog-seen = 2 + [llvm] ninja = false diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh index b146ea36037..a32e6df2208 100755 --- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh +++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh @@ -10,99 +10,111 @@ pushd rust command -v rg >/dev/null 2>&1 || cargo install ripgrep -rm -r src/test/ui/{extern/,panics/,unsized-locals/,lto/,simd*,linkage*,unwind-*.rs} || true -for test in $(rg --files-with-matches "asm!|catch_unwind|should_panic|lto|// needs-asm-support" src/test/ui); do +rm -r src/test/ui/{extern/,unsized-locals/,lto/,linkage*} || true +for test in $(rg --files-with-matches "asm!|lto|// needs-asm-support|// needs-unwind" src/test/{ui,incremental}); 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 +for test in $(rg -i --files-with-matches "//(\[\w+\])?~[^\|]*\s*ERR|// 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 +# missing features +# ================ + +# requires stack unwinding 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/process/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/drop/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/runtime/rt-explody-panic-payloads.rs rm src/test/incremental/change_crate_dep_kind.rs -rm src/test/ui/threads-sendsync/unwind-resource.rs +rm src/test/incremental/issue-80691-bad-eval-cache.rs # -Cpanic=abort causes abort instead of exit(101) +rm src/test/ui/panic-while-printing.rs +rm src/test/ui/test-attrs/test-panic-while-printing.rs +rm src/test/ui/test-attrs/test-type.rs -rm src/test/ui/issues/issue-28950.rs # depends on stack size optimizations -rm src/test/ui/codegen/init-large-type.rs # same +# requires compiling with -Cpanic=unwind +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/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 + +# vendor intrinsics rm src/test/ui/sse2.rs # cpuid not supported, so sse2 not detected +rm src/test/ui/intrinsics/const-eval-select-x86_64.rs # requires x86_64 vendor intrinsics +rm src/test/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant" +rm src/test/ui/simd/intrinsic/generic-bitmask-pass.rs # simd_bitmask unimplemented +rm src/test/ui/simd/intrinsic/generic-as.rs # simd_as unimplemented +rm src/test/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs # simd_saturating_add unimplemented +rm src/test/ui/simd/intrinsic/float-math-pass.rs # simd_fcos unimplemented +rm src/test/ui/simd/intrinsic/generic-gather-pass.rs # simd_gather unimplemented +rm src/test/ui/simd/intrinsic/generic-select-pass.rs # simd_select_bitmask unimplemented +rm src/test/ui/simd/issue-85915-simd-ptrs.rs # simd_gather unimplemented +rm src/test/ui/simd/issue-89193.rs # simd_gather unimplemented +rm src/test/ui/simd/simd-bitmask.rs # simd_bitmask unimplemented + +# exotic linkages rm src/test/ui/issues/issue-33992.rs # unsupported linkages -rm src/test/ui/issues/issue-51947.rs # same rm src/test/incremental/hashes/function_interfaces.rs # same rm src/test/incremental/hashes/statics.rs # same + +# variadic arguments +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 + +# unsized locals +rm -r src/test/run-pass-valgrind/unsized-locals + +# misc unimplemented things +rm src/test/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and nearbyintf64 intrinsics +rm src/test/ui/target-feature/missing-plusminus.rs # error not implemented +rm src/test/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment +rm -r src/test/run-make/emit-named-files # requires full --emit support + +# optimization tests +# ================== +rm src/test/ui/issues/issue-28950.rs # depends on stack size optimizations +rm src/test/ui/codegen/init-large-type.rs # same +rm -r src/test/run-make/fmt-write-bloat/ # tests an optimization + +# backend specific tests +# ====================== +rm src/test/incremental/thinlto/cgu_invalidated_when_import_{added,removed}.rs # requires LLVM +rm src/test/ui/abi/stack-protector.rs # requires stack protector support + +# giving different but possibly correct results +# ============================================= rm src/test/ui/numbers-arithmetic/saturating-float-casts.rs # intrinsic gives different but valid result +rm src/test/ui/simd/intrinsic/float-minmax-pass.rs # same 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/consts/issue-33537.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/lto.rs # requires lto -rm src/test/incremental/dirty_clean.rs # TODO +# doesn't work due to the way the rustc test suite is invoked. +# should work when using ./x.py test the way it is intended +# ============================================================ rm -r src/test/run-make/emit-shared-files # requires the rustdoc executable in build/bin/ rm -r src/test/run-make/unstable-flag-required # same rm -r src/test/run-make/rustdoc-* # same -rm -r src/test/run-make/emit-named-files # requires full --emit support - -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/intrinsics/const-eval-select-x86_64.rs # same -rm src/test/ui/match/issue-82392.rs # differing error -rm src/test/ui/consts/min_const_fn/address_of_const.rs # same -rm src/test/ui/consts/issue-miri-1910.rs # same -rm src/test/ui/generic-associated-types/bugs/issue-80626.rs # same -rm src/test/ui/generic-associated-types/bugs/issue-89008.rs # same -rm src/test/ui/type-alias-impl-trait/cross_crate_ice*.rs # requires removed aux dep +# genuine bugs +# ============ 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 -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 - -rm src/test/ui/command/command-current-dir.rs # can't find libstd.so - -rm src/test/ui/abi/stack-protector.rs # requires stack protector support - -rm src/test/incremental/issue-80691-bad-eval-cache.rs # wrong exit code rm src/test/incremental/spike-neg1.rs # errors out for some reason rm src/test/incremental/spike-neg2.rs # same rm src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs # gives a stackoverflow before the backend runs +rm src/test/ui/mir/ssa-analysis-regression-50041.rs # produces ICE -rm src/test/incremental/thinlto/cgu_invalidated_when_import_{added,removed}.rs # requires LLVM +rm src/test/ui/simd/intrinsic/generic-reduction-pass.rs # simd_reduce_add_unordered doesn't accept an accumulator for integer vectors + +# bugs in the test suite +# ====================== +rm src/test/ui/unsafe/union.rs # has UB caught by cg_clif. see rust-lang/rust#95075 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,incremental} diff --git a/compiler/rustc_codegen_cranelift/scripts/tests.sh b/compiler/rustc_codegen_cranelift/scripts/tests.sh index bdb3de0936d..fee1012c8f1 100755 --- a/compiler/rustc_codegen_cranelift/scripts/tests.sh +++ b/compiler/rustc_codegen_cranelift/scripts/tests.sh @@ -57,7 +57,6 @@ function base_sysroot_tests() { fi echo "[AOT] dst_field_align" - # FIXME Re-add -Zmir-opt-level=2 once rust-lang/rust#67529 is fixed. $MY_RUSTC example/dst-field-align.rs --crate-name dst_field_align --crate-type bin --target "$TARGET_TRIPLE" $RUN_WRAPPER ./target/out/dst_field_align || (echo $?; false) diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index a249e5fa8ac..ef56fb191bf 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -94,6 +94,9 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv }; let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap(); let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func); + if self.clif_comments.enabled() { + self.add_comment(func_ref, format!("{:?}", name)); + } let call_inst = self.bcx.ins().call(func_ref, args); if self.clif_comments.enabled() { self.add_comment(call_inst, format!("easy_call {}", name)); @@ -367,7 +370,10 @@ pub(crate) fn codegen_terminator_call<'tcx>( .map(|inst| fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD)) .unwrap_or(false); if is_cold { - // FIXME Mark current_block block as cold once Cranelift supports it + fx.bcx.set_cold_block(fx.bcx.current_block().unwrap()); + if let Some((_place, destination_block)) = destination { + fx.bcx.set_cold_block(fx.get_block(destination_block)); + } } // Unpack arguments tuple for closures @@ -501,7 +507,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( let ret_block = fx.get_block(dest); fx.bcx.ins().jump(ret_block, &[]); } else { - trap_unreachable(fx, "[corruption] Diverging function returned"); + fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); } } diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 0a6ef6441fa..a9ff710c91e 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -4,6 +4,7 @@ use rustc_ast::InlineAsmOptions; use rustc_index::vec::IndexVec; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::layout::FnAbiOf; +use rustc_middle::ty::print::with_no_trimmed_paths; use indexmap::IndexSet; @@ -25,7 +26,10 @@ pub(crate) fn codegen_fn<'tcx>( let mir = tcx.instance_mir(instance.def); let _mir_guard = crate::PrintOnPanic(|| { let mut buf = Vec::new(); - rustc_middle::mir::write_mir_pretty(tcx, Some(instance.def_id()), &mut buf).unwrap(); + with_no_trimmed_paths!({ + rustc_middle::mir::pretty::write_mir_fn(tcx, mir, &mut |_, _| Ok(()), &mut buf) + .unwrap(); + }); String::from_utf8_lossy(&buf).into_owned() }); @@ -90,7 +94,7 @@ pub(crate) fn codegen_fn<'tcx>( } 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"); + fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); } else { tcx.sess.time("codegen clif ir", || { tcx.sess @@ -258,7 +262,9 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) { if fx.clif_comments.enabled() { let mut terminator_head = "\n".to_string(); - bb_data.terminator().kind.fmt_head(&mut terminator_head).unwrap(); + with_no_trimmed_paths!({ + 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); } @@ -303,7 +309,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) { let target = fx.get_block(*target); let failure = fx.bcx.create_block(); - // FIXME Mark failure block as cold once Cranelift supports it + fx.bcx.set_cold_block(failure); if *expected { fx.bcx.ins().brz(cond, failure, &[]); @@ -424,18 +430,16 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) { fx.bcx.ins().jump(destination_block, &[]); } None => { - crate::trap::trap_unreachable( - fx, - "[corruption] Returned from noreturn inline asm", - ); + fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); } } } TerminatorKind::Resume | TerminatorKind::Abort => { - trap_unreachable(fx, "[corruption] Unwinding bb reached."); + // FIXME implement unwinding + fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); } TerminatorKind::Unreachable => { - trap_unreachable(fx, "[corruption] Hit unreachable code."); + fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); } TerminatorKind::Yield { .. } | TerminatorKind::FalseEdge { .. } @@ -813,7 +817,14 @@ pub(crate) fn codegen_place<'tcx>( for elem in place.projection { match elem { PlaceElem::Deref => { - cplace = cplace.place_deref(fx); + if cplace.layout().ty.is_box() { + cplace = cplace + .place_field(fx, Field::new(0)) // Box<T> -> Unique<T> + .place_field(fx, Field::new(0)) // Unique<T> -> *const T + .place_deref(fx); + } else { + cplace = cplace.place_deref(fx); + } } PlaceElem::Field(field, _ty) => { cplace = cplace.place_field(fx, field); @@ -918,5 +929,5 @@ pub(crate) fn codegen_panic_inner<'tcx>( args, ); - crate::trap::trap_unreachable(fx, "panic lang item returned"); + fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); } diff --git a/compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs b/compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs index b924f2085a0..5984ec8412a 100644 --- a/compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs +++ b/compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs @@ -1,4 +1,4 @@ -#![feature(rustc_private, once_cell)] +#![feature(rustc_private)] #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] #![warn(unreachable_pub)] @@ -9,19 +9,21 @@ extern crate rustc_interface; extern crate rustc_session; extern crate rustc_target; -use std::lazy::SyncLazy; use std::panic; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; use rustc_interface::interface; -use rustc_session::config::ErrorOutputType; +use rustc_session::config::{ErrorOutputType, TrimmedDefPaths}; use rustc_session::early_error; use rustc_target::spec::PanicStrategy; +// FIXME use std::lazy::SyncLazy once it stabilizes +use once_cell::sync::Lazy; + const BUG_REPORT_URL: &str = "https://github.com/bjorn3/rustc_codegen_cranelift/issues/new"; -static DEFAULT_HOOK: SyncLazy<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> = - SyncLazy::new(|| { +static DEFAULT_HOOK: Lazy<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> = + Lazy::new(|| { let hook = panic::take_hook(); panic::set_hook(Box::new(|info| { // Invoke the default handler, which prints the actual panic message and optionally a backtrace @@ -53,6 +55,8 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks { config.opts.maybe_sysroot = Some(config.opts.maybe_sysroot.clone().unwrap_or_else(|| { std::env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_owned() })); + + config.opts.trimmed_def_paths = TrimmedDefPaths::GoodPath; } } @@ -61,7 +65,7 @@ fn main() { let start_rss = get_resident_set_size(); rustc_driver::init_rustc_env_logger(); let mut callbacks = CraneliftPassesCallbacks::default(); - SyncLazy::force(&DEFAULT_HOOK); // Install ice hook + Lazy::force(&DEFAULT_HOOK); // Install ice hook let exit_code = rustc_driver::catch_with_exit_code(|| { let args = std::env::args_os() .enumerate() diff --git a/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs b/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs index 100c3b43160..c6a247cf59e 100644 --- a/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs +++ b/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs @@ -1,16 +1,18 @@ -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;)* - } +macro_rules! 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); + #[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! { diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs index c7e15f81e03..476d6a54e12 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs @@ -110,7 +110,6 @@ impl<'tcx> DebugContext<'tcx> { 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)); } diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs index e4f28338096..d26392c4913 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs @@ -81,6 +81,8 @@ impl UnwindContext { #[cfg(all(feature = "jit", not(windows)))] pub(crate) unsafe fn register_jit(self, jit_module: &cranelift_jit::JITModule) { + use std::mem::ManuallyDrop; + let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(self.endian)); self.frame_table.write_eh_frame(&mut eh_frame).unwrap(); @@ -95,17 +97,16 @@ impl UnwindContext { // FIXME support unregistering unwind tables once cranelift-jit supports deallocating // individual functions - #[allow(unused_variables)] - let (eh_frame, eh_frame_len, _) = Vec::into_raw_parts(eh_frame); + let eh_frame = ManuallyDrop::new(eh_frame); // ======================================================================= - // Everything after this line up to the end of the file is loosly based on + // Everything after this line up to the end of the file is loosely based on // https://github.com/bytecodealliance/wasmtime/blob/4471a82b0c540ff48960eca6757ccce5b1b5c3e4/crates/jit/src/unwind/systemv.rs #[cfg(target_os = "macos")] { // On macOS, `__register_frame` takes a pointer to a single FDE - let start = eh_frame; - let end = start.add(eh_frame_len); + let start = eh_frame.as_ptr(); + let end = start.add(eh_frame.len()); let mut current = start; // Walk all of the entries in the frame table and register them @@ -124,7 +125,7 @@ impl UnwindContext { #[cfg(not(target_os = "macos"))] { // On other platforms, `__register_frame` will walk the FDEs until an entry of length 0 - __register_frame(eh_frame); + __register_frame(eh_frame.as_ptr()); } } } diff --git a/compiler/rustc_codegen_cranelift/src/discriminant.rs b/compiler/rustc_codegen_cranelift/src/discriminant.rs index 3326f87f000..6b2893fdaeb 100644 --- a/compiler/rustc_codegen_cranelift/src/discriminant.rs +++ b/compiler/rustc_codegen_cranelift/src/discriminant.rs @@ -68,11 +68,10 @@ pub(crate) fn codegen_get_discriminant<'tcx>( let layout = value.layout(); if layout.abi == Abi::Uninhabited { - return trap_unreachable_ret_value( - fx, - dest_layout, - "[panic] Tried to get discriminant for uninhabited type.", - ); + let true_ = fx.bcx.ins().iconst(types::I32, 1); + fx.bcx.ins().trapnz(true_, TrapCode::UnreachableCodeReached); + // Return a dummy value + return CValue::by_ref(Pointer::const_addr(fx, 0), dest_layout); } let (tag_scalar, tag_field, tag_encoding) = match &layout.variants { diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index 9e07528313d..6c22296db71 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs @@ -3,7 +3,6 @@ use std::cell::RefCell; use std::ffi::CString; -use std::lazy::SyncOnceCell; use std::os::raw::{c_char, c_int}; use std::sync::{mpsc, Mutex}; @@ -14,6 +13,9 @@ use rustc_span::Symbol; use cranelift_jit::{JITBuilder, JITModule}; +// FIXME use std::lazy::SyncOnceCell once it stabilizes +use once_cell::sync::OnceCell; + use crate::{prelude::*, BackendConfig}; use crate::{CodegenCx, CodegenMode}; @@ -27,8 +29,7 @@ thread_local! { } /// The Sender owned by the rustc thread -static GLOBAL_MESSAGE_SENDER: SyncOnceCell<Mutex<mpsc::Sender<UnsafeMessage>>> = - SyncOnceCell::new(); +static GLOBAL_MESSAGE_SENDER: OnceCell<Mutex<mpsc::Sender<UnsafeMessage>>> = OnceCell::new(); /// A message that is sent from the jitted runtime to the rustc thread. /// Senders are responsible for upholding `Send` semantics. diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs index 098862b0662..0e4f7ee907a 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs @@ -126,12 +126,9 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( }; } - if let Some((_, dest)) = destination { - let ret_block = fx.get_block(dest); - fx.bcx.ins().jump(ret_block, &[]); - } else { - trap_unreachable(fx, "[corruption] Diverging intrinsic returned."); - } + let dest = destination.expect("all llvm intrinsics used by stdlib should return").1; + let ret_block = fx.get_block(dest); + fx.bcx.ins().jump(ret_block, &[]); } // llvm.x86.avx2.vperm2i128 diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 6489b96be4b..310d27c6dec 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -1,46 +1,32 @@ //! Codegen of intrinsics. This includes `extern "rust-intrinsic"`, `extern "platform-intrinsic"` //! and LLVM intrinsics that have symbol names starting with `llvm.`. -mod cpuid; -mod llvm; -mod simd; - -pub(crate) use cpuid::codegen_cpuid_call; -pub(crate) use llvm::codegen_llvm_intrinsic_call; - -use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::subst::SubstsRef; -use rustc_span::symbol::{kw, sym, Symbol}; - -use crate::prelude::*; -use cranelift_codegen::ir::AtomicRmwOp; - -macro intrinsic_pat { +macro_rules! intrinsic_pat { (_) => { _ - }, + }; ($name:ident) => { sym::$name - }, + }; (kw.$name:ident) => { kw::$name - }, + }; ($name:literal) => { $name - }, + }; } -macro intrinsic_arg { - (o $fx:expr, $arg:ident) => {}, +macro_rules! intrinsic_arg { + (o $fx:expr, $arg:ident) => {}; (c $fx:expr, $arg:ident) => { let $arg = codegen_operand($fx, $arg); - }, + }; (v $fx:expr, $arg:ident) => { let $arg = codegen_operand($fx, $arg).load_scalar($fx); - } + }; } -macro intrinsic_match { +macro_rules! intrinsic_match { ($fx:expr, $intrinsic:expr, $args:expr, _ => $unknown:block; $( @@ -62,6 +48,20 @@ macro intrinsic_match { } } +mod cpuid; +mod llvm; +mod simd; + +pub(crate) use cpuid::codegen_cpuid_call; +pub(crate) use llvm::codegen_llvm_intrinsic_call; + +use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::subst::SubstsRef; +use rustc_span::symbol::{kw, sym, Symbol}; + +use crate::prelude::*; +use cranelift_codegen::ir::AtomicRmwOp; + fn report_atomic_type_validation_error<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, intrinsic: Symbol, @@ -229,7 +229,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( // Insert non returning intrinsics here match intrinsic { sym::abort => { - trap_abort(fx, "Called intrinsic::abort."); + fx.bcx.ins().trap(TrapCode::User(0)); } sym::transmute => { crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", span); @@ -749,6 +749,18 @@ fn codegen_regular_intrinsic_call<'tcx>( _ if intrinsic.as_str().starts_with("atomic_load"), (v ptr) { let ty = substs.type_at(0); match ty.kind() { + ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { + // FIXME implement 128bit atomics + if fx.tcx.is_compiler_builtins(LOCAL_CRATE) { + // special case for compiler-builtins to avoid having to patch it + crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported"); + let ret_block = fx.get_block(destination.unwrap().1); + fx.bcx.ins().jump(ret_block, &[]); + return; + } else { + fx.tcx.sess.span_fatal(span, "128bit atomics not yet supported"); + } + } ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { report_atomic_type_validation_error(fx, intrinsic, span, ty); @@ -765,6 +777,18 @@ fn codegen_regular_intrinsic_call<'tcx>( _ if intrinsic.as_str().starts_with("atomic_store"), (v ptr, c val) { let ty = substs.type_at(0); match ty.kind() { + ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { + // FIXME implement 128bit atomics + if fx.tcx.is_compiler_builtins(LOCAL_CRATE) { + // special case for compiler-builtins to avoid having to patch it + crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported"); + let ret_block = fx.get_block(destination.unwrap().1); + fx.bcx.ins().jump(ret_block, &[]); + return; + } else { + fx.tcx.sess.span_fatal(span, "128bit atomics not yet supported"); + } + } ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} _ => { report_atomic_type_validation_error(fx, intrinsic, span, ty); @@ -1115,10 +1139,6 @@ fn codegen_regular_intrinsic_call<'tcx>( }; } - if let Some((_, dest)) = destination { - let ret_block = fx.get_block(dest); - fx.bcx.ins().jump(ret_block, &[]); - } else { - trap_unreachable(fx, "[corruption] Diverging intrinsic returned."); - } + let ret_block = fx.get_block(destination.unwrap().1); + fx.bcx.ins().jump(ret_block, &[]); } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 49022ebd3e2..bc21d736166 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -409,6 +409,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }; simd_reduce_add_ordered | simd_reduce_add_unordered, (c v, v acc) { + // FIXME there must be no acc param for integer vectors if !v.layout().ty.is_simd() { report_simd_type_validation_error(fx, intrinsic, span, v.layout().ty); return; @@ -424,6 +425,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }; simd_reduce_mul_ordered | simd_reduce_mul_unordered, (c v, v acc) { + // FIXME there must be no acc param for integer vectors if !v.layout().ty.is_simd() { report_simd_type_validation_error(fx, intrinsic, span, v.layout().ty); return; diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 331e3e8f5df..878b9390e13 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -1,5 +1,5 @@ -#![feature(rustc_private, decl_macro)] -#![cfg_attr(feature = "jit", feature(never_type, vec_into_raw_parts, once_cell))] +#![feature(rustc_private)] +// Note: please avoid adding other feature gates where possible #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] #![warn(unreachable_pub)] @@ -105,7 +105,6 @@ mod prelude { pub(crate) use crate::common::*; pub(crate) use crate::debuginfo::{DebugContext, UnwindContext}; pub(crate) use crate::pointer::Pointer; - pub(crate) use crate::trap::*; pub(crate) use crate::value_and_place::{CPlace, CPlaceInner, CValue}; } @@ -196,7 +195,7 @@ impl CodegenBackend for CraneliftCodegenBackend { CodegenMode::Aot => driver::aot::run_aot(tcx, config, metadata, need_metadata_module), CodegenMode::Jit | CodegenMode::JitLazy => { #[cfg(feature = "jit")] - let _: ! = driver::jit::run_jit(tcx, config); + driver::jit::run_jit(tcx, config); #[cfg(not(feature = "jit"))] tcx.sess.fatal("jit support was disabled when compiling rustc_codegen_cranelift"); @@ -301,7 +300,10 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar } }; - isa_builder.finish(flags) + match isa_builder.finish(flags) { + Ok(target_isa) => target_isa, + Err(err) => sess.fatal(&format!("failed to build TargetIsa: {}", err)), + } } /// This is the entrypoint for a hot plugged rustc_codegen_cranelift diff --git a/compiler/rustc_codegen_cranelift/src/trap.rs b/compiler/rustc_codegen_cranelift/src/trap.rs index 99b5366e349..923269c4de9 100644 --- a/compiler/rustc_codegen_cranelift/src/trap.rs +++ b/compiler/rustc_codegen_cranelift/src/trap.rs @@ -25,12 +25,6 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) { fx.bcx.ins().call(puts, &[msg_ptr]); } -/// Trap code: user1 -pub(crate) fn trap_abort(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef<str>) { - codegen_print(fx, msg.as_ref()); - fx.bcx.ins().trap(TrapCode::User(1)); -} - /// Use this for example when a function call should never return. This will fill the current block, /// so you can **not** add instructions to it afterwards. /// @@ -39,21 +33,6 @@ pub(crate) fn trap_unreachable(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef< codegen_print(fx, msg.as_ref()); fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); } - -/// Like `trap_unreachable` but returns a fake value of the specified type. -/// -/// Trap code: user65535 -pub(crate) fn trap_unreachable_ret_value<'tcx>( - fx: &mut FunctionCx<'_, '_, 'tcx>, - dest_layout: TyAndLayout<'tcx>, - msg: impl AsRef<str>, -) -> CValue<'tcx> { - codegen_print(fx, msg.as_ref()); - let true_ = fx.bcx.ins().iconst(types::I32, 1); - fx.bcx.ins().trapnz(true_, TrapCode::UnreachableCodeReached); - CValue::by_ref(Pointer::const_addr(fx, 0), dest_layout) -} - /// Use this when something is unimplemented, but `libcore` or `libstd` requires it to codegen. /// Unlike `trap_unreachable` this will not fill the current block, so you **must** add instructions /// to it afterwards. diff --git a/compiler/rustc_codegen_cranelift/y.rs b/compiler/rustc_codegen_cranelift/y.rs index 18528d54297..f177b91c2c4 100755 --- a/compiler/rustc_codegen_cranelift/y.rs +++ b/compiler/rustc_codegen_cranelift/y.rs @@ -1,9 +1,9 @@ #!/usr/bin/env bash -#![allow()] /*This line is ignored by bash +#![deny(unsafe_code)] /*This line is ignored by bash # This block is ignored by rustc set -e echo "[BUILD] y.rs" 1>&2 -rustc $0 -o ${0/.rs/.bin} -g +rustc $0 -o ${0/.rs/.bin} -Cdebuginfo=1 exec ${0/.rs/.bin} $@ */ diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index d2fbd6a9654..57a93ed4d55 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -476,22 +476,47 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // cannot use the shim here, because that will only result in infinite recursion ty::InstanceDef::Virtual(_, idx) => { let mut args = args.to_vec(); - // We have to implement all "object safe receivers". Currently we - // support built-in pointers `(&, &mut, Box)` as well as unsized-self. We do - // not yet support custom self types. - // Also see `compiler/rustc_codegen_llvm/src/abi.rs` and `compiler/rustc_codegen_ssa/src/mir/block.rs`. - let receiver_place = match args[0].layout.ty.builtin_deref(true) { - Some(_) => { - // Built-in pointer. - self.deref_operand(&args[0])? - } - None => { - // Unsized self. - args[0].assert_mem_place() + // We have to implement all "object safe receivers". So we have to go search for a + // pointer or `dyn Trait` type, but it could be wrapped in newtypes. So recursively + // unwrap those newtypes until we are there. + let mut receiver = args[0]; + let receiver_place = loop { + match receiver.layout.ty.kind() { + ty::Ref(..) | ty::RawPtr(..) => break self.deref_operand(&receiver)?, + ty::Dynamic(..) => break receiver.assert_mem_place(), + _ => { + // Not there yet, search for the only non-ZST field. + let mut non_zst_field = None; + for i in 0..receiver.layout.fields.count() { + let field = self.operand_field(&receiver, i)?; + if !field.layout.is_zst() { + assert!( + non_zst_field.is_none(), + "multiple non-ZST fields in dyn receiver type {}", + receiver.layout.ty + ); + non_zst_field = Some(field); + } + } + receiver = non_zst_field.unwrap_or_else(|| { + panic!( + "no non-ZST fields in dyn receiver type {}", + receiver.layout.ty + ) + }); + } } }; - // Find and consult vtable - let vtable = self.scalar_to_ptr(receiver_place.vtable()); + // Find and consult vtable. The type now could be something like RcBox<dyn Trait>, + // i.e., it is still not necessarily `ty::Dynamic` (so we cannot use + // `place.vtable()`), but it should have a `dyn Trait` tail. + assert!(matches!( + self.tcx + .struct_tail_erasing_lifetimes(receiver_place.layout.ty, self.param_env) + .kind(), + ty::Dynamic(..) + )); + let vtable = self.scalar_to_ptr(receiver_place.meta.unwrap_meta()); let fn_val = self.get_vtable_slot(vtable, u64::try_from(idx).unwrap())?; // `*mut receiver_place.layout.ty` is almost the layout that we @@ -505,7 +530,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Scalar::from_maybe_pointer(receiver_place.ptr, self).into(), this_receiver_ptr, )); - trace!("Patched self operand to {:#?}", args[0]); + trace!("Patched receiver operand to {:#?}", args[0]); // recurse with concrete function self.eval_fn_call( fn_val, diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 29c948fe318..70d9db4a84b 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -86,7 +86,11 @@ impl Display for Target { Target::Statement => "statement", Target::Arm => "match arm", Target::AssocConst => "associated const", - Target::Method(_) => "method", + Target::Method(kind) => match kind { + MethodKind::Inherent => "inherent method", + MethodKind::Trait { body: false } => "required trait method", + MethodKind::Trait { body: true } => "provided trait method", + }, Target::AssocTy => "associated type", Target::ForeignFn => "foreign function", Target::ForeignStatic => "foreign static item", diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index b5bc4893ef3..93ece753728 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -698,7 +698,7 @@ impl<'tcx> GeneratorSubsts<'tcx> { } /// This returns the types of the MIR locals which had to be stored across suspension points. - /// It is calculated in rustc_const_eval::transform::generator::StateTransform. + /// It is calculated in rustc_mir_transform::generator::StateTransform. /// All the types here must be in the tuple in GeneratorInterior. /// /// The locals are grouped by their variant number. Note that some locals may diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index a907f50a11b..148e0a24ec3 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -800,11 +800,17 @@ impl<'a> Parser<'a> { &mut self, cast_expr: P<Expr>, ) -> PResult<'a, P<Expr>> { + let span = cast_expr.span; + let maybe_ascription_span = if let ExprKind::Type(ascripted_expr, _) = &cast_expr.kind { + Some(ascripted_expr.span.shrink_to_hi().with_hi(span.hi())) + } else { + None + }; + // Save the memory location of expr before parsing any following postfix operators. // This will be compared with the memory location of the output expression. // If they different we can assume we parsed another expression because the existing expression is not reallocated. let addr_before = &*cast_expr as *const _ as usize; - let span = cast_expr.span; let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?; let changed = addr_before != &*with_postfix as *const _ as usize; @@ -825,11 +831,8 @@ impl<'a> Parser<'a> { } ); let mut err = self.struct_span_err(span, &msg); - // If type ascription is "likely an error", the user will already be getting a useful - // help message, and doesn't need a second. - if self.last_type_ascription.map_or(false, |last_ascription| last_ascription.1) { - self.maybe_annotate_with_ascription(&mut err, false); - } else { + + let suggest_parens = |err: &mut DiagnosticBuilder<'_, _>| { let suggestions = vec![ (span.shrink_to_lo(), "(".to_string()), (span.shrink_to_hi(), ")".to_string()), @@ -839,6 +842,32 @@ impl<'a> Parser<'a> { suggestions, Applicability::MachineApplicable, ); + }; + + // If type ascription is "likely an error", the user will already be getting a useful + // help message, and doesn't need a second. + if self.last_type_ascription.map_or(false, |last_ascription| last_ascription.1) { + self.maybe_annotate_with_ascription(&mut err, false); + } else if let Some(ascription_span) = maybe_ascription_span { + let is_nightly = self.sess.unstable_features.is_nightly_build(); + if is_nightly { + suggest_parens(&mut err); + } + err.span_suggestion( + ascription_span, + &format!( + "{}remove the type ascription", + if is_nightly { "alternatively, " } else { "" } + ), + String::new(), + if is_nightly { + Applicability::MaybeIncorrect + } else { + Applicability::MachineApplicable + }, + ); + } else { + suggest_parens(&mut err); } err.emit(); }; diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index e949059099c..e55bdb0e553 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1486,7 +1486,7 @@ impl<'a> Parser<'a> { // `check_trailing_angle_brackets` already emitted a nicer error // NOTE(eddyb) this was `.cancel()`, but `err` // gets returned, so we can't fully defuse it. - err.downgrade_to_delayed_bug(); + err.delay_as_bug(); } } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ebf6678d3ad..4f9e1d3fa3b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -196,8 +196,7 @@ impl CheckAttrVisitor<'_> { fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) { self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { lint.build(&format!( - "`#[{}]` is ignored on struct fields, match arms and macro defs", - sym, + "`#[{sym}]` is ignored on struct fields, match arms and macro defs", )) .warn( "this was previously accepted by the compiler but is \ @@ -214,7 +213,7 @@ impl CheckAttrVisitor<'_> { fn inline_attr_str_error_without_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) { self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { - lint.build(&format!("`#[{}]` is ignored on struct fields and match arms", sym)) + lint.build(&format!("`#[{sym}]` is ignored on struct fields and match arms")) .warn( "this was previously accepted by the compiler but is \ being phased out; it will become a hard error in \ @@ -721,7 +720,7 @@ impl CheckAttrVisitor<'_> { .sess .struct_span_err( meta.name_value_literal_span().unwrap_or_else(|| meta.span()), - &format!("`{}` is not a valid identifier", doc_keyword), + &format!("`{doc_keyword}` is not a valid identifier"), ) .emit(); return false; @@ -805,8 +804,7 @@ impl CheckAttrVisitor<'_> { .struct_span_err( meta.span(), &format!( - "`#![doc({} = \"...\")]` isn't allowed as a crate-level attribute", - attr_name, + "`#![doc({attr_name} = \"...\")]` isn't allowed as a crate-level attribute", ), ) .emit(); @@ -1035,8 +1033,7 @@ impl CheckAttrVisitor<'_> { attr.meta().unwrap().span, "use `doc = include_str!` instead", format!( - "#{}[doc = include_str!(\"{}\")]", - inner, value + "#{inner}[doc = include_str!(\"{value}\")]", ), applicability, ); @@ -1230,7 +1227,7 @@ impl CheckAttrVisitor<'_> { if let Some(value) = attr.value_str() { diag.span_help( attr.span, - &format!(r#"try `#[link(name = "{}")]` instead"#, value), + &format!(r#"try `#[link(name = "{value}")]` instead"#), ); } else { diag.span_help(attr.span, r#"try `#[link(name = "...")]` instead"#); @@ -1518,15 +1515,14 @@ impl CheckAttrVisitor<'_> { }; self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { lint.build(&format!( - "`#[no_mangle]` has no effect on a foreign {}", - foreign_item_kind + "`#[no_mangle]` has no effect on a foreign {foreign_item_kind}" )) .warn( "this was previously accepted by the compiler but is \ being phased out; it will become a hard error in \ a future release!", ) - .span_label(span, format!("foreign {}", foreign_item_kind)) + .span_label(span, format!("foreign {foreign_item_kind}")) .note("symbol names in extern blocks are not mangled") .span_suggestion( attr.span, @@ -1692,9 +1688,9 @@ impl CheckAttrVisitor<'_> { hint.span(), E0517, "{}", - &format!("attribute should be applied to {} {}", article, allowed_targets) + &format!("attribute should be applied to {article} {allowed_targets}") ) - .span_label(span, &format!("not {} {}", article, allowed_targets)) + .span_label(span, &format!("not {article} {allowed_targets}")) .emit(); } diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 0fdbdb7b08d..0e04a2cfb11 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -80,8 +80,7 @@ impl<'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for CheckConstTraitVisitor< /// of the trait being implemented; as those provided functions can be non-const. fn visit_item<'hir>(&mut self, item: &'hir hir::Item<'hir>) { let _: Option<_> = try { - if let hir::ItemKind::Impl(ref imp) = item.kind { - if let hir::Constness::Const = imp.constness { + if let hir::ItemKind::Impl(ref imp) = item.kind && let hir::Constness::Const = imp.constness { let trait_def_id = imp.of_trait.as_ref()?.trait_def_id()?; let ancestors = self .tcx @@ -132,7 +131,6 @@ impl<'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for CheckConstTraitVisitor< .note(&format!("`{}` not implemented", to_implement.join("`, `"))) .emit(); } - } } }; } diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index 30a0071f0f2..9cbb7917e9a 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -61,10 +61,9 @@ fn collect_item(tcx: TyCtxt<'_>, items: &mut DiagnosticItems, name: Symbol, item if let Some(original_def_id) = items.name_to_id.insert(name, item_def_id) { if original_def_id != item_def_id { let mut err = match tcx.hir().span_if_local(item_def_id) { - Some(span) => tcx.sess.struct_span_err( - span, - &format!("duplicate diagnostic item found: `{}`.", name), - ), + Some(span) => tcx + .sess + .struct_span_err(span, &format!("duplicate diagnostic item found: `{name}`.")), None => tcx.sess.struct_err(&format!( "duplicate diagnostic item in crate `{}`: `{}`.", tcx.crate_name(item_def_id.krate), diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index f5040a373c2..5a1373ad1a2 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -148,33 +148,29 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(De } else if let Some((def_id, _)) = visitor.attr_main_fn { Some((def_id.to_def_id(), EntryFnType::Main)) } else { - if let Some(main_def) = tcx.resolutions(()).main_def { - if let Some(def_id) = main_def.opt_fn_def_id() { - // non-local main imports are handled below - if let Some(def_id) = def_id.as_local() { - if matches!(tcx.hir().find_by_def_id(def_id), Some(Node::ForeignItem(_))) { - tcx.sess - .struct_span_err( - tcx.def_span(def_id), - "the `main` function cannot be declared in an `extern` block", - ) - .emit(); - return None; - } - } - - if main_def.is_import && !tcx.features().imported_main { - let span = main_def.span; - feature_err( - &tcx.sess.parse_sess, - sym::imported_main, - span, - "using an imported function as entry point `main` is experimental", + if let Some(main_def) = tcx.resolutions(()).main_def && let Some(def_id) = main_def.opt_fn_def_id() { + // non-local main imports are handled below + if let Some(def_id) = def_id.as_local() && matches!(tcx.hir().find_by_def_id(def_id), Some(Node::ForeignItem(_))) { + tcx.sess + .struct_span_err( + tcx.def_span(def_id), + "the `main` function cannot be declared in an `extern` block", ) .emit(); - } - return Some((def_id, EntryFnType::Main)); + return None; } + + if main_def.is_import && !tcx.features().imported_main { + let span = main_def.span; + feature_err( + &tcx.sess.parse_sess, + sym::imported_main, + span, + "using an imported function as entry point `main` is experimental", + ) + .emit(); + } + return Some((def_id, EntryFnType::Main)); } no_main_err(tcx, visitor); None @@ -225,11 +221,9 @@ fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) { err.note(¬e); } - if let Some(main_def) = tcx.resolutions(()).main_def { - if main_def.opt_fn_def_id().is_none() { - // There is something at `crate::main`, but it is not a function definition. - err.span_label(main_def.span, "non-function item at `crate::main` is found"); - } + if let Some(main_def) = tcx.resolutions(()).main_def && main_def.opt_fn_def_id().is_none(){ + // There is something at `crate::main`, but it is not a function definition. + err.span_label(main_def.span, "non-function item at `crate::main` is found"); } if tcx.sess.teach(&err.get_code().unwrap()) { diff --git a/compiler/rustc_passes/src/intrinsicck.rs b/compiler/rustc_passes/src/intrinsicck.rs index 6316f3b8459..027eac16bad 100644 --- a/compiler/rustc_passes/src/intrinsicck.rs +++ b/compiler/rustc_passes/src/intrinsicck.rs @@ -79,27 +79,25 @@ impl<'tcx> ExprVisitor<'tcx> { // Special-case transmuting from `typeof(function)` and // `Option<typeof(function)>` to present a clearer error. let from = unpack_option_like(self.tcx, from); - if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) { - if size_to == Pointer.size(&self.tcx) { - struct_span_err!(self.tcx.sess, span, E0591, "can't transmute zero-sized type") - .note(&format!("source type: {}", from)) - .note(&format!("target type: {}", to)) - .help("cast with `as` to a pointer instead") - .emit(); - return; - } + if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer.size(&self.tcx) { + struct_span_err!(self.tcx.sess, span, E0591, "can't transmute zero-sized type") + .note(&format!("source type: {from}")) + .note(&format!("target type: {to}")) + .help("cast with `as` to a pointer instead") + .emit(); + return; } } // Try to display a sensible error with as much information as possible. let skeleton_string = |ty: Ty<'tcx>, sk| match sk { Ok(SizeSkeleton::Known(size)) => format!("{} bits", size.bits()), - Ok(SizeSkeleton::Pointer { tail, .. }) => format!("pointer to `{}`", tail), + Ok(SizeSkeleton::Pointer { tail, .. }) => format!("pointer to `{tail}`"), Err(LayoutError::Unknown(bad)) => { if bad == ty { "this type does not have a fixed size".to_owned() } else { - format!("size can vary because of {}", bad) + format!("size can vary because of {bad}") } } Err(err) => err.to_string(), @@ -113,7 +111,7 @@ impl<'tcx> ExprVisitor<'tcx> { or dependently-sized types" ); if from == to { - err.note(&format!("`{}` does not have a fixed size", from)); + err.note(&format!("`{from}` does not have a fixed size")); } else { err.note(&format!("source type: `{}` ({})", from, skeleton_string(from, sk_from))) .note(&format!("target type: `{}` ({})", to, skeleton_string(to, sk_to))); @@ -201,7 +199,7 @@ impl<'tcx> ExprVisitor<'tcx> { _ => None, }; let Some(asm_ty) = asm_ty else { - let msg = &format!("cannot use value of type `{}` for inline assembly", ty); + let msg = &format!("cannot use value of type `{ty}` for inline assembly"); let mut err = self.tcx.sess.struct_span_err(expr.span, msg); err.note( "only integers, floats, SIMD vectors, pointers and function pointers \ @@ -216,7 +214,7 @@ impl<'tcx> ExprVisitor<'tcx> { if !ty.is_copy_modulo_regions(self.tcx.at(DUMMY_SP), self.param_env) { let msg = "arguments for inline assembly must be copyable"; let mut err = self.tcx.sess.struct_span_err(expr.span, msg); - err.note(&format!("`{}` does not implement the Copy trait", ty)); + err.note(&format!("`{ty}` does not implement the Copy trait")); err.emit(); } @@ -237,7 +235,7 @@ impl<'tcx> ExprVisitor<'tcx> { in_expr.span, &format!("type `{}`", self.typeck_results.expr_ty_adjusted(in_expr)), ); - err.span_label(expr.span, &format!("type `{}`", ty)); + err.span_label(expr.span, &format!("type `{ty}`")); err.note( "asm inout arguments must have the same type, \ unless they are both pointers or integers of the same size", @@ -256,7 +254,7 @@ impl<'tcx> ExprVisitor<'tcx> { let reg_class = reg.reg_class(); let supported_tys = reg_class.supported_types(asm_arch); let Some((_, feature)) = supported_tys.iter().find(|&&(t, _)| t == asm_ty) else { - let msg = &format!("type `{}` cannot be used with this register class", ty); + let msg = &format!("type `{ty}` cannot be used with this register class"); let mut err = self.tcx.sess.struct_span_err(expr.span, msg); let supported_tys: Vec<_> = supported_tys.iter().map(|(t, _)| t.to_string()).collect(); @@ -326,12 +324,10 @@ impl<'tcx> ExprVisitor<'tcx> { let mut err = lint.build(msg); err.span_label(expr.span, "for this argument"); err.help(&format!( - "use the `{}` modifier to have the register formatted as `{}`", - suggested_modifier, suggested_result, + "use the `{suggested_modifier}` modifier to have the register formatted as `{suggested_result}`", )); err.help(&format!( - "or use the `{}` modifier to keep the default formatting of `{}`", - default_modifier, default_result, + "or use the `{default_modifier}` modifier to keep the default formatting of `{default_result}`", )); err.emit(); }, @@ -509,14 +505,14 @@ impl<'tcx> Visitor<'tcx> for ExprVisitor<'tcx> { match expr.kind { hir::ExprKind::Path(ref qpath) => { let res = self.typeck_results.qpath_res(qpath, expr.hir_id); - if let Res::Def(DefKind::Fn, did) = res { - if self.def_id_is_transmute(did) { - let typ = self.typeck_results.node_type(expr.hir_id); - let sig = typ.fn_sig(self.tcx); - let from = sig.inputs().skip_binder()[0]; - let to = sig.output().skip_binder(); - self.check_transmute(expr.span, from, to); - } + if let Res::Def(DefKind::Fn, did) = res + && self.def_id_is_transmute(did) + { + let typ = self.typeck_results.node_type(expr.hir_id); + let sig = typ.fn_sig(self.tcx); + let from = sig.inputs().skip_binder()[0]; + let to = sig.output().skip_binder(); + self.check_transmute(expr.span, from, to); } } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index ecdbe12c9ab..bcae735bb7e 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1,3 +1,4 @@ +// ignore-tidy-filelength //! Name resolution for lifetimes. //! //! Name resolution for lifetimes follows *much* simpler rules than the @@ -230,6 +231,10 @@ enum Scope<'a> { hir_id: hir::HirId, s: ScopeRef<'a>, + + /// In some cases not allowing late bounds allows us to avoid ICEs. + /// This is almost ways set to true. + allow_late_bound: bool, }, /// Lifetimes introduced by a fn are scoped to the call-site for that fn, @@ -302,6 +307,7 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { scope_type, hir_id, s: _, + allow_late_bound, } => f .debug_struct("Binder") .field("lifetimes", lifetimes) @@ -311,6 +317,7 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { .field("scope_type", scope_type) .field("hir_id", hir_id) .field("s", &"..") + .field("allow_late_bound", allow_late_bound) .finish(), Scope::Body { id, s: _ } => { f.debug_struct("Body").field("id", id).field("s", &"..").finish() @@ -703,6 +710,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { track_lifetime_uses: true, opaque_type_parent: false, scope_type: BinderScopeType::Normal, + allow_late_bound: true, }; self.with(scope, move |_old_scope, this| { intravisit::walk_fn(this, fk, fd, b, s, hir_id) @@ -828,6 +836,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { track_lifetime_uses, scope_type: BinderScopeType::Normal, s: ROOT_SCOPE, + allow_late_bound: false, }; self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &generics.params); @@ -896,6 +905,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { track_lifetime_uses: true, opaque_type_parent: false, scope_type: BinderScopeType::Normal, + allow_late_bound: true, }; self.with(scope, |old_scope, this| { // a bare fn has no bounds, so everything @@ -1077,6 +1087,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { track_lifetime_uses: true, opaque_type_parent: false, scope_type: BinderScopeType::Normal, + allow_late_bound: false, }; this.with(scope, |_old_scope, this| { this.visit_generics(generics); @@ -1097,6 +1108,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { track_lifetime_uses: true, opaque_type_parent: false, scope_type: BinderScopeType::Normal, + allow_late_bound: false, }; self.with(scope, |_old_scope, this| { let scope = Scope::TraitRefBoundary { s: this.scope }; @@ -1156,6 +1168,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { track_lifetime_uses: true, opaque_type_parent: true, scope_type: BinderScopeType::Normal, + allow_late_bound: false, }; self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &generics.params); @@ -1225,6 +1238,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { track_lifetime_uses: true, opaque_type_parent: true, scope_type: BinderScopeType::Normal, + allow_late_bound: true, }; self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &generics.params); @@ -1378,6 +1392,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { track_lifetime_uses: true, opaque_type_parent: false, scope_type: BinderScopeType::Normal, + allow_late_bound: true, }; this.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &bound_generic_params); @@ -1425,6 +1440,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { track_lifetime_uses: true, opaque_type_parent: false, scope_type, + allow_late_bound: true, }; self.with(scope, |_, this| { intravisit::walk_param_bound(this, bound); @@ -1477,6 +1493,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { track_lifetime_uses: true, opaque_type_parent: false, scope_type, + allow_late_bound: true, }; self.with(scope, |old_scope, this| { this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params); @@ -2180,6 +2197,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { opaque_type_parent: true, track_lifetime_uses: false, scope_type: BinderScopeType::Normal, + allow_late_bound: true, }; self.with(scope, move |old_scope, this| { this.check_lifetime_params(old_scope, &generics.params); @@ -2602,7 +2620,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let mut scope = &*self.scope; let hir_id = loop { match scope { - Scope::Binder { hir_id, .. } => { + Scope::Binder { hir_id, allow_late_bound: true, .. } => { break *hir_id; } Scope::ObjectLifetimeDefault { ref s, .. } @@ -2611,8 +2629,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { | Scope::TraitRefBoundary { ref s, .. } => { scope = *s; } - Scope::Root | Scope::Body { .. } => { + Scope::Root + | Scope::Body { .. } + | Scope::Binder { allow_late_bound: false, .. } => { // See issues #83907 and #83693. Just bail out from looking inside. + // See the issue #95023 for not allowing late bound self.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, "In fn_like_elision without appropriate scope above", diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index e9537af25a0..e584c9ad201 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -1,6 +1,6 @@ //! This calculates the types which has storage which lives across a suspension point in a //! generator from the perspective of typeck. The actual types used at runtime -//! is calculated in `rustc_const_eval::transform::generator` and may be a subset of the +//! is calculated in `rustc_mir_transform::generator` and may be a subset of the //! types computed here. use self::drop_ranges::DropRanges; diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 010405cfd52..bf7db8221a2 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -599,7 +599,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Make sure that, if any traits other than the found ones were involved, // we don't don't report an unimplemented trait. - // We don't want to say that `iter::Cloned` is not an interator, just + // We don't want to say that `iter::Cloned` is not an iterator, just // because of some non-Clone item being iterated over. for (predicate, _parent_pred, _cause) in &unsatisfied_predicates { match predicate.kind().skip_binder() { diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index d0ff3eb7475..c178d3e3b03 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -212,7 +212,7 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> { let mut out_tree = clone_subtree(internal.first_edge().descend()); { - let out_root = BTreeMap::ensure_is_owned(&mut out_tree.root); + let out_root = out_tree.root.as_mut().unwrap(); let mut out_node = out_root.push_internal_level(); let mut in_edge = internal.first_edge(); while let Ok(kv) = in_edge.right_kv() { @@ -278,11 +278,12 @@ where fn replace(&mut self, key: K) -> Option<K> { let (map, dormant_map) = DormantMutRef::new(self); - let root_node = Self::ensure_is_owned(&mut map.root).borrow_mut(); + let root_node = map.root.get_or_insert_with(Root::new).borrow_mut(); match root_node.search_tree::<K>(&key) { Found(mut kv) => Some(mem::replace(kv.key_mut(), key)), GoDown(handle) => { - VacantEntry { key, handle, dormant_map, _marker: PhantomData }.insert(()); + VacantEntry { key, handle: Some(handle), dormant_map, _marker: PhantomData } + .insert(()); None } } @@ -1032,7 +1033,7 @@ impl<K, V> BTreeMap<K, V> { let self_iter = mem::take(self).into_iter(); let other_iter = mem::take(other).into_iter(); - let root = BTreeMap::ensure_is_owned(&mut self.root); + let root = self.root.get_or_insert_with(Root::new); root.append_from_sorted_iters(self_iter, other_iter, &mut self.length) } @@ -1144,14 +1145,20 @@ impl<K, V> BTreeMap<K, V> { where K: Ord, { - // FIXME(@porglezomp) Avoid allocating if we don't insert let (map, dormant_map) = DormantMutRef::new(self); - let root_node = Self::ensure_is_owned(&mut map.root).borrow_mut(); - match root_node.search_tree(&key) { - Found(handle) => Occupied(OccupiedEntry { handle, dormant_map, _marker: PhantomData }), - GoDown(handle) => { - Vacant(VacantEntry { key, handle, dormant_map, _marker: PhantomData }) - } + match map.root { + None => Vacant(VacantEntry { key, handle: None, dormant_map, _marker: PhantomData }), + Some(ref mut root) => match root.borrow_mut().search_tree(&key) { + Found(handle) => { + Occupied(OccupiedEntry { handle, dormant_map, _marker: PhantomData }) + } + GoDown(handle) => Vacant(VacantEntry { + key, + handle: Some(handle), + dormant_map, + _marker: PhantomData, + }), + }, } } @@ -2247,12 +2254,6 @@ impl<K, V> BTreeMap<K, V> { pub const fn is_empty(&self) -> bool { self.len() == 0 } - - /// If the root node is the empty (non-allocated) root node, allocate our - /// own node. Is an associated function to avoid borrowing the entire BTreeMap. - fn ensure_is_owned(root: &mut Option<Root<K, V>>) -> &mut Root<K, V> { - root.get_or_insert_with(Root::new) - } } #[cfg(test)] diff --git a/library/alloc/src/collections/btree/map/entry.rs b/library/alloc/src/collections/btree/map/entry.rs index 66608d09082..cacd06b5df1 100644 --- a/library/alloc/src/collections/btree/map/entry.rs +++ b/library/alloc/src/collections/btree/map/entry.rs @@ -40,7 +40,8 @@ impl<K: Debug + Ord, V: Debug> Debug for Entry<'_, K, V> { #[stable(feature = "rust1", since = "1.0.0")] pub struct VacantEntry<'a, K: 'a, V: 'a> { pub(super) key: K, - pub(super) handle: Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>, + /// `None` for a (empty) map without root + pub(super) handle: Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>>, pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V>>, // Be invariant in `K` and `V` @@ -312,22 +313,33 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn insert(self, value: V) -> &'a mut V { - let out_ptr = match self.handle.insert_recursing(self.key, value) { - (None, val_ptr) => { - // SAFETY: We have consumed self.handle and the handle returned. - let map = unsafe { self.dormant_map.awaken() }; - map.length += 1; - val_ptr - } - (Some(ins), val_ptr) => { - drop(ins.left); + let out_ptr = match self.handle { + None => { // SAFETY: We have consumed self.handle and the reference returned. let map = unsafe { self.dormant_map.awaken() }; - let root = map.root.as_mut().unwrap(); - root.push_internal_level().push(ins.kv.0, ins.kv.1, ins.right); - map.length += 1; + let mut root = NodeRef::new_leaf(); + let val_ptr = root.borrow_mut().push(self.key, value) as *mut V; + map.root = Some(root.forget_type()); + map.length = 1; val_ptr } + Some(handle) => match handle.insert_recursing(self.key, value) { + (None, val_ptr) => { + // SAFETY: We have consumed self.handle and the handle returned. + let map = unsafe { self.dormant_map.awaken() }; + map.length += 1; + val_ptr + } + (Some(ins), val_ptr) => { + drop(ins.left); + // SAFETY: We have consumed self.handle and the reference returned. + let map = unsafe { self.dormant_map.awaken() }; + let root = map.root.as_mut().unwrap(); + root.push_internal_level().push(ins.kv.0, ins.kv.1, ins.right); + map.length += 1; + val_ptr + } + }, }; // Now that we have finished growing the tree using borrowed references, // dereference the pointer to a part of it, that we picked up along the way. diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 4d21df32417..cc986e93698 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -115,8 +115,9 @@ impl<K, V> BTreeMap<K, V> { K: Ord, { let iter = mem::take(self).into_iter(); - let root = BTreeMap::ensure_is_owned(&mut self.root); - root.bulk_push(iter, &mut self.length); + if !iter.is_empty() { + self.root.insert(Root::new()).bulk_push(iter, &mut self.length); + } } } @@ -914,7 +915,7 @@ mod test_drain_filter { fn empty() { let mut map: BTreeMap<i32, i32> = BTreeMap::new(); map.drain_filter(|_, _| unreachable!("there's nothing to decide on")); - assert!(map.is_empty()); + assert_eq!(map.height(), None); map.check(); } @@ -1410,7 +1411,7 @@ fn test_clear() { assert_eq!(map.len(), len); map.clear(); map.check(); - assert!(map.is_empty()); + assert_eq!(map.height(), None); } } @@ -1789,7 +1790,7 @@ fn test_occupied_entry_key() { let mut a = BTreeMap::new(); let key = "hello there"; let value = "value goes here"; - assert!(a.is_empty()); + assert_eq!(a.height(), None); a.insert(key, value); assert_eq!(a.len(), 1); assert_eq!(a[key], value); @@ -1809,9 +1810,9 @@ fn test_vacant_entry_key() { let key = "hello there"; let value = "value goes here"; - assert!(a.is_empty()); + assert_eq!(a.height(), None); match a.entry(key) { - Occupied(_) => panic!(), + Occupied(_) => unreachable!(), Vacant(e) => { assert_eq!(key, *e.key()); e.insert(value); @@ -1823,6 +1824,36 @@ fn test_vacant_entry_key() { } #[test] +fn test_vacant_entry_no_insert() { + let mut a = BTreeMap::<&str, ()>::new(); + let key = "hello there"; + + // Non-allocated + assert_eq!(a.height(), None); + match a.entry(key) { + Occupied(_) => unreachable!(), + Vacant(e) => assert_eq!(key, *e.key()), + } + // Ensures the tree has no root. + assert_eq!(a.height(), None); + a.check(); + + // Allocated but still empty + a.insert(key, ()); + a.remove(&key); + assert_eq!(a.height(), Some(0)); + assert!(a.is_empty()); + match a.entry(key) { + Occupied(_) => unreachable!(), + Vacant(e) => assert_eq!(key, *e.key()), + } + // Ensures the allocated root is not changed. + assert_eq!(a.height(), Some(0)); + assert!(a.is_empty()); + a.check(); +} + +#[test] fn test_first_last_entry() { let mut a = BTreeMap::new(); assert!(a.first_entry().is_none()); diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index 44f5bc850b8..b5f0edf6b33 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -213,7 +213,7 @@ unsafe impl<K: Send, V: Send, Type> Send for NodeRef<marker::Owned, K, V, Type> unsafe impl<K: Send, V: Send, Type> Send for NodeRef<marker::Dying, K, V, Type> {} impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> { - fn new_leaf() -> Self { + pub fn new_leaf() -> Self { Self::from_new_leaf(LeafNode::new()) } @@ -619,15 +619,16 @@ impl<K, V, Type> NodeRef<marker::Owned, K, V, Type> { } impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> { - /// Adds a key-value pair to the end of the node. - pub fn push(&mut self, key: K, val: V) { + /// Adds a key-value pair to the end of the node, and returns + /// the mutable reference of the inserted value. + pub fn push(&mut self, key: K, val: V) -> &mut V { let len = self.len_mut(); let idx = usize::from(*len); assert!(idx < CAPACITY); *len += 1; unsafe { self.key_area_mut(idx).write(key); - self.val_area_mut(idx).write(val); + self.val_area_mut(idx).write(val) } } } diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 3065169e5e2..ea651c075d9 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2112,9 +2112,10 @@ impl<T> Weak<T> { /// assert!(empty.upgrade().is_none()); /// ``` #[stable(feature = "downgraded_weak", since = "1.10.0")] + #[rustc_const_unstable(feature = "const_weak_new", issue = "95091", reason = "recently added")] #[must_use] - pub fn new() -> Weak<T> { - Weak { ptr: NonNull::new(usize::MAX as *mut RcBox<T>).expect("MAX is not 0") } + pub const fn new() -> Weak<T> { + Weak { ptr: unsafe { NonNull::new_unchecked(usize::MAX as *mut RcBox<T>) } } } } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 2140c3f168d..ba3187294e6 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1742,9 +1742,10 @@ impl<T> Weak<T> { /// assert!(empty.upgrade().is_none()); /// ``` #[stable(feature = "downgraded_weak", since = "1.10.0")] + #[rustc_const_unstable(feature = "const_weak_new", issue = "95091", reason = "recently added")] #[must_use] - pub fn new() -> Weak<T> { - Weak { ptr: NonNull::new(usize::MAX as *mut ArcInner<T>).expect("MAX is not 0") } + pub const fn new() -> Weak<T> { + Weak { ptr: unsafe { NonNull::new_unchecked(usize::MAX as *mut ArcInner<T>) } } } } diff --git a/library/core/src/async_iter/async_iter.rs b/library/core/src/async_iter/async_iter.rs index f29de31171a..016a3685e85 100644 --- a/library/core/src/async_iter/async_iter.rs +++ b/library/core/src/async_iter/async_iter.rs @@ -12,6 +12,7 @@ use crate::task::{Context, Poll}; /// [impl]: index.html#implementing-async-iterator #[unstable(feature = "async_iterator", issue = "79024")] #[must_use = "async iterators do nothing unless polled"] +#[doc(alias = "Stream")] pub trait AsyncIterator { /// The type of items yielded by the async iterator. type Item; diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index f5ea5f5ba50..c7a9a818378 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -154,7 +154,7 @@ pub const fn identity<T>(x: T) -> T { #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "AsRef")] pub trait AsRef<T: ?Sized> { - /// Performs the conversion. + /// Converts this type into a shared reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] fn as_ref(&self) -> &T; } @@ -196,7 +196,7 @@ pub trait AsRef<T: ?Sized> { #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "AsMut")] pub trait AsMut<T: ?Sized> { - /// Performs the conversion. + /// Converts this type into a mutable reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] fn as_mut(&mut self) -> &mut T; } @@ -272,7 +272,7 @@ pub trait AsMut<T: ?Sized> { #[rustc_diagnostic_item = "Into"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Into<T>: Sized { - /// Performs the conversion. + /// Converts this type into the (usually inferred) input type. #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn into(self) -> T; @@ -367,7 +367,7 @@ pub trait Into<T>: Sized { note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix", ))] pub trait From<T>: Sized { - /// Performs the conversion. + /// Converts to this type from the input type. #[lang = "from"] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] @@ -487,6 +487,7 @@ impl<T: ?Sized, U: ?Sized> const AsRef<U> for &T where T: ~const AsRef<U>, { + #[inline] fn as_ref(&self) -> &U { <T as AsRef<U>>::as_ref(*self) } @@ -499,6 +500,7 @@ impl<T: ?Sized, U: ?Sized> const AsRef<U> for &mut T where T: ~const AsRef<U>, { + #[inline] fn as_ref(&self) -> &U { <T as AsRef<U>>::as_ref(*self) } @@ -519,6 +521,7 @@ impl<T: ?Sized, U: ?Sized> const AsMut<U> for &mut T where T: ~const AsMut<U>, { + #[inline] fn as_mut(&mut self) -> &mut U { (*self).as_mut() } diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index c99d9b279a9..d4e103ab525 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2049,9 +2049,10 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> { /// /// [changes]: io#platform-specific-behavior /// -/// On macOS before version 10.10 and REDOX this function is not protected against time-of-check to -/// time-of-use (TOCTOU) race conditions, and should not be used in security-sensitive code on -/// those platforms. All other platforms are protected. +/// On macOS before version 10.10 and REDOX, as well as when running in Miri for any target, this +/// function is not protected against time-of-check to time-of-use (TOCTOU) race conditions, and +/// should not be used in security-sensitive code on those platforms. All other platforms are +/// protected. /// /// # Errors /// diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 855f900430c..d95bc9b15c9 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -149,6 +149,11 @@ pub trait CommandExt: Sealed { fn arg0<S>(&mut self, arg: S) -> &mut process::Command where S: AsRef<OsStr>; + + /// Sets the process group ID of the child process. Translates to a `setpgid` call in the child + /// process. + #[unstable(feature = "process_set_process_group", issue = "93857")] + fn process_group(&mut self, pgroup: i32) -> &mut process::Command; } #[stable(feature = "rust1", since = "1.0.0")] @@ -201,6 +206,11 @@ impl CommandExt for process::Command { self.as_inner_mut().set_arg_0(arg.as_ref()); self } + + fn process_group(&mut self, pgroup: i32) -> &mut process::Command { + self.as_inner_mut().pgroup(pgroup); + self + } } /// Unix-specific extensions to [`process::ExitStatus`] and diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index c8dc768d3fc..d1f59d2786e 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -1739,11 +1739,11 @@ fn test_windows_absolute() { let relative = r"a\b"; let mut expected = crate::env::current_dir().unwrap(); expected.push(relative); - assert_eq!(absolute(relative).unwrap(), expected); + assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str()); macro_rules! unchanged( ($path:expr) => { - assert_eq!(absolute($path).unwrap(), Path::new($path)); + assert_eq!(absolute($path).unwrap().as_os_str(), Path::new($path).as_os_str()); } ); @@ -1759,11 +1759,11 @@ fn test_windows_absolute() { // Verbatim paths are always unchanged, no matter what. unchanged!(r"\\?\path.\to/file.."); - assert_eq!(absolute(r"C:\path..\to.\file.").unwrap(), Path::new(r"C:\path..\to\file")); - assert_eq!(absolute(r"C:\path\to\COM1").unwrap(), Path::new(r"\\.\COM1")); - assert_eq!(absolute(r"C:\path\to\COM1.txt").unwrap(), Path::new(r"\\.\COM1")); - assert_eq!(absolute(r"C:\path\to\COM1 .txt").unwrap(), Path::new(r"\\.\COM1")); - assert_eq!(absolute(r"C:\path\to\cOnOuT$").unwrap(), Path::new(r"\\.\cOnOuT$")); + assert_eq!( + absolute(r"C:\path..\to.\file.").unwrap().as_os_str(), + Path::new(r"C:\path..\to\file").as_os_str() + ); + assert_eq!(absolute(r"COM1").unwrap().as_os_str(), Path::new(r"\\.\COM1").as_os_str()); } #[bench] diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index a3e6b081936..b93a3d67771 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -1517,14 +1517,14 @@ pub fn chroot(dir: &Path) -> io::Result<()> { pub use remove_dir_impl::remove_dir_all; -// Fallback for REDOX and ESP-IDF -#[cfg(any(target_os = "redox", target_os = "espidf"))] +// Fallback for REDOX and ESP-IDF (and Miri) +#[cfg(any(target_os = "redox", target_os = "espidf", miri))] mod remove_dir_impl { pub use crate::sys_common::fs::remove_dir_all; } // Modern implementation using openat(), unlinkat() and fdopendir() -#[cfg(not(any(target_os = "redox", target_os = "espidf")))] +#[cfg(not(any(target_os = "redox", target_os = "espidf", miri)))] mod remove_dir_impl { use super::{cstr, lstat, Dir, DirEntry, InnerReadDir, ReadDir}; use crate::ffi::CStr; diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs index 97985ddd331..27bee714f5b 100644 --- a/library/std/src/sys/unix/process/process_common.rs +++ b/library/std/src/sys/unix/process/process_common.rs @@ -18,7 +18,7 @@ use crate::sys_common::IntoInner; #[cfg(not(target_os = "fuchsia"))] use crate::sys::fs::OpenOptions; -use libc::{c_char, c_int, gid_t, uid_t, EXIT_FAILURE, EXIT_SUCCESS}; +use libc::{c_char, c_int, gid_t, pid_t, uid_t, EXIT_FAILURE, EXIT_SUCCESS}; cfg_if::cfg_if! { if #[cfg(target_os = "fuchsia")] { @@ -82,6 +82,7 @@ pub struct Command { stderr: Option<Stdio>, #[cfg(target_os = "linux")] create_pidfd: bool, + pgroup: Option<pid_t>, } // Create a new type for argv, so that we can make it `Send` and `Sync` @@ -145,6 +146,7 @@ impl Command { stdin: None, stdout: None, stderr: None, + pgroup: None, } } @@ -167,6 +169,7 @@ impl Command { stdout: None, stderr: None, create_pidfd: false, + pgroup: None, } } @@ -202,6 +205,9 @@ impl Command { pub fn groups(&mut self, groups: &[gid_t]) { self.groups = Some(Box::from(groups)); } + pub fn pgroup(&mut self, pgroup: pid_t) { + self.pgroup = Some(pgroup); + } #[cfg(target_os = "linux")] pub fn create_pidfd(&mut self, val: bool) { @@ -265,6 +271,10 @@ impl Command { pub fn get_groups(&self) -> Option<&[gid_t]> { self.groups.as_deref() } + #[allow(dead_code)] + pub fn get_pgroup(&self) -> Option<pid_t> { + self.pgroup + } pub fn get_closures(&mut self) -> &mut Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>> { &mut self.closures diff --git a/library/std/src/sys/unix/process/process_common/tests.rs b/library/std/src/sys/unix/process/process_common/tests.rs index 10aa34e9443..9f1a645372f 100644 --- a/library/std/src/sys/unix/process/process_common/tests.rs +++ b/library/std/src/sys/unix/process/process_common/tests.rs @@ -67,3 +67,58 @@ fn test_process_mask() { t!(cat.wait()); } } + +#[test] +#[cfg_attr( + any( + // See test_process_mask + target_os = "macos", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + ), + ignore +)] +fn test_process_group_posix_spawn() { + unsafe { + // Spawn a cat subprocess that's just going to hang since there is no I/O. + let mut cmd = Command::new(OsStr::new("cat")); + cmd.pgroup(0); + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + // Check that we can kill its process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} + +#[test] +#[cfg_attr( + any( + // See test_process_mask + target_os = "macos", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + ), + ignore +)] +fn test_process_group_no_posix_spawn() { + unsafe { + // Same as above, create hang-y cat. This time, force using the non-posix_spawnp path. + let mut cmd = Command::new(OsStr::new("cat")); + cmd.pgroup(0); + cmd.pre_exec(Box::new(|| Ok(()))); // pre_exec forces fork + exec + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + // Check that we can kill its process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 2a97a802a20..3d305cd7310 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -320,6 +320,10 @@ impl Command { cvt(libc::chdir(cwd.as_ptr()))?; } + if let Some(pgroup) = self.get_pgroup() { + cvt(libc::setpgid(0, pgroup))?; + } + // emscripten has no signal support. #[cfg(not(target_os = "emscripten"))] { @@ -459,6 +463,8 @@ impl Command { None => None, }; + let pgroup = self.get_pgroup(); + // Safety: -1 indicates we don't have a pidfd. let mut p = unsafe { Process::new(0, -1) }; @@ -487,6 +493,8 @@ impl Command { cvt_nz(libc::posix_spawnattr_init(attrs.as_mut_ptr()))?; let attrs = PosixSpawnattr(&mut attrs); + let mut flags = 0; + let mut file_actions = MaybeUninit::uninit(); cvt_nz(libc::posix_spawn_file_actions_init(file_actions.as_mut_ptr()))?; let file_actions = PosixSpawnFileActions(&mut file_actions); @@ -516,13 +524,18 @@ impl Command { cvt_nz(f(file_actions.0.as_mut_ptr(), cwd.as_ptr()))?; } + if let Some(pgroup) = pgroup { + flags |= libc::POSIX_SPAWN_SETPGROUP; + cvt_nz(libc::posix_spawnattr_setpgroup(attrs.0.as_mut_ptr(), pgroup))?; + } + let mut set = MaybeUninit::<libc::sigset_t>::uninit(); cvt(sigemptyset(set.as_mut_ptr()))?; cvt_nz(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(), set.as_ptr()))?; cvt(sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?; cvt_nz(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(), set.as_ptr()))?; - let flags = libc::POSIX_SPAWN_SETSIGDEF | libc::POSIX_SPAWN_SETSIGMASK; + flags |= libc::POSIX_SPAWN_SETSIGDEF | libc::POSIX_SPAWN_SETSIGMASK; cvt_nz(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?; // Make sure we synchronize access to the global `environ` resource diff --git a/library/std/src/sys/windows/process/tests.rs b/library/std/src/sys/windows/process/tests.rs index 96477fb19da..cd535afb4a3 100644 --- a/library/std/src/sys/windows/process/tests.rs +++ b/library/std/src/sys/windows/process/tests.rs @@ -186,8 +186,15 @@ fn windows_exe_resolver() { let temp = tmpdir(); let mut exe_path = temp.path().to_owned(); exe_path.push("exists.exe"); - symlink("<DOES NOT EXIST>".as_ref(), &exe_path).unwrap(); // A broken symlink should still be resolved. - assert!(resolve_exe(OsStr::new("exists.exe"), empty_paths, Some(temp.path().as_ref())).is_ok()); + // Skip this check if not in CI and creating symlinks isn't possible. + let is_ci = env::var("CI").is_ok(); + let result = symlink("<DOES NOT EXIST>".as_ref(), &exe_path); + if is_ci || result.is_ok() { + result.unwrap(); + assert!( + resolve_exe(OsStr::new("exists.exe"), empty_paths, Some(temp.path().as_ref())).is_ok() + ); + } } diff --git a/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh b/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh index 4cbc2ccfe38..cf784a66ae4 100755 --- a/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh +++ b/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh @@ -33,14 +33,18 @@ cd solaris dpkg --add-architecture $APT_ARCH apt-get update apt-get download $(apt-cache depends --recurse --no-replaces \ - libc:$APT_ARCH \ - libm-dev:$APT_ARCH \ - libpthread:$APT_ARCH \ - libresolv:$APT_ARCH \ - librt:$APT_ARCH \ - libsocket:$APT_ARCH \ - system-crt:$APT_ARCH \ - system-header:$APT_ARCH \ + libc:$APT_ARCH \ + liblgrp-dev:$APT_ARCH \ + liblgrp:$APT_ARCH \ + libm-dev:$APT_ARCH \ + libpthread:$APT_ARCH \ + libresolv:$APT_ARCH \ + librt:$APT_ARCH \ + libsendfile-dev:$APT_ARCH \ + libsendfile:$APT_ARCH \ + libsocket:$APT_ARCH \ + system-crt:$APT_ARCH \ + system-header:$APT_ARCH \ | grep "^\w") for deb in *$APT_ARCH.deb; do diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 11925ab9785..3759cb632bb 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -118,7 +118,7 @@ The valid emit kinds are: - `llvm-ir` — Generates a file containing [LLVM IR]. The default output filename is `CRATE_NAME.ll`. - `metadata` — Generates a file containing metadata about the crate. The - default output filename is `CRATE_NAME.rmeta`. + default output filename is `libCRATE_NAME.rmeta`. - `mir` — Generates a file containing rustc's mid-level intermediate representation. The default output filename is `CRATE_NAME.mir`. - `obj` — Generates a native object file. The default output filename is diff --git a/src/test/debuginfo/borrowed-basic.rs b/src/test/debuginfo/borrowed-basic.rs index b4bb7c146d9..45f5df228e3 100644 --- a/src/test/debuginfo/borrowed-basic.rs +++ b/src/test/debuginfo/borrowed-basic.rs @@ -1,6 +1,3 @@ -// Gdb doesn't know about UTF-32 character encoding and will print a rust char as only -// its numerical value. - // compile-flags:-g // min-lldb-version: 310 @@ -13,7 +10,7 @@ // gdb-command:print *int_ref // gdb-check:$2 = -1 -// gdb-command:print *char_ref +// gdb-command:print/d *char_ref // gdb-check:$3 = 97 // gdb-command:print *i8_ref diff --git a/src/test/debuginfo/borrowed-unique-basic.rs b/src/test/debuginfo/borrowed-unique-basic.rs index f38cbc10dd3..94229bf27f3 100644 --- a/src/test/debuginfo/borrowed-unique-basic.rs +++ b/src/test/debuginfo/borrowed-unique-basic.rs @@ -1,8 +1,5 @@ // min-lldb-version: 310 -// Gdb doesn't know about UTF-32 character encoding and will print a rust char as only -// its numerical value. - // compile-flags:-g // === GDB TESTS =================================================================================== @@ -15,7 +12,7 @@ // gdb-command:print *int_ref // gdb-check:$2 = -1 -// gdb-command:print *char_ref +// gdb-command:print/d *char_ref // gdb-check:$3 = 97 // gdb-command:print/d *i8_ref diff --git a/src/test/debuginfo/gdb-char.rs b/src/test/debuginfo/gdb-char.rs new file mode 100644 index 00000000000..1863405bf1e --- /dev/null +++ b/src/test/debuginfo/gdb-char.rs @@ -0,0 +1,23 @@ +// GDB got support for DW_ATE_UTF in 11.2, see +// https://sourceware.org/bugzilla/show_bug.cgi?id=28637. + +// min-gdb-version: 11.2 +// compile-flags: -g + +// === GDB TESTS =================================================================================== + +// gdb-command:run +// gdb-command:print ch +// gdb-check:$1 = 97 'a' + +#![allow(unused_variables)] +#![feature(omit_gdb_pretty_printer_section)] +#![omit_gdb_pretty_printer_section] + +fn main() { + let ch: char = 'a'; + + zzz(); // #break +} + +fn zzz() {()} diff --git a/src/test/ui/check-cfg/mix.rs b/src/test/ui/check-cfg/mix.rs index 26c735c4a10..b51d356f61f 100644 --- a/src/test/ui/check-cfg/mix.rs +++ b/src/test/ui/check-cfg/mix.rs @@ -45,6 +45,28 @@ fn test_cfg_macro() { //~^ WARNING unexpected `cfg` condition name cfg!(any(feature = "bad", windows)); //~^ WARNING unexpected `cfg` condition value + cfg!(any(windows, xxx)); + //~^ WARNING unexpected `cfg` condition name + cfg!(all(unix, xxx)); + //~^ WARNING unexpected `cfg` condition name + cfg!(all(aa, bb)); + //~^ WARNING unexpected `cfg` condition name + //~| WARNING unexpected `cfg` condition name + cfg!(any(aa, bb)); + //~^ WARNING unexpected `cfg` condition name + //~| WARNING unexpected `cfg` condition name + cfg!(any(unix, feature = "zebra")); + //~^ WARNING unexpected `cfg` condition value + cfg!(any(xxx, feature = "zebra")); + //~^ WARNING unexpected `cfg` condition name + //~| WARNING unexpected `cfg` condition value + cfg!(any(xxx, unix, xxx)); + //~^ WARNING unexpected `cfg` condition name + //~| WARNING unexpected `cfg` condition name + cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); + //~^ WARNING unexpected `cfg` condition value + //~| WARNING unexpected `cfg` condition value + //~| WARNING unexpected `cfg` condition value } fn main() {} diff --git a/src/test/ui/check-cfg/mix.stderr b/src/test/ui/check-cfg/mix.stderr index b273be77422..08a338da104 100644 --- a/src/test/ui/check-cfg/mix.stderr +++ b/src/test/ui/check-cfg/mix.stderr @@ -62,5 +62,99 @@ LL | cfg!(any(feature = "bad", windows)); | = note: expected values for `feature` are: bar, foo -warning: 9 warnings emitted +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:48:23 + | +LL | cfg!(any(windows, xxx)); + | ^^^ + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:50:20 + | +LL | cfg!(all(unix, xxx)); + | ^^^ + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:52:14 + | +LL | cfg!(all(aa, bb)); + | ^^ + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:52:18 + | +LL | cfg!(all(aa, bb)); + | ^^ + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:55:14 + | +LL | cfg!(any(aa, bb)); + | ^^ + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:55:18 + | +LL | cfg!(any(aa, bb)); + | ^^ + +warning: unexpected `cfg` condition value + --> $DIR/mix.rs:58:20 + | +LL | cfg!(any(unix, feature = "zebra")); + | ^^^^^^^^^^^^^^^^^ + | + = note: expected values for `feature` are: bar, foo + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:60:14 + | +LL | cfg!(any(xxx, feature = "zebra")); + | ^^^ + +warning: unexpected `cfg` condition value + --> $DIR/mix.rs:60:19 + | +LL | cfg!(any(xxx, feature = "zebra")); + | ^^^^^^^^^^^^^^^^^ + | + = note: expected values for `feature` are: bar, foo + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:63:14 + | +LL | cfg!(any(xxx, unix, xxx)); + | ^^^ + +warning: unexpected `cfg` condition name + --> $DIR/mix.rs:63:25 + | +LL | cfg!(any(xxx, unix, xxx)); + | ^^^ + +warning: unexpected `cfg` condition value + --> $DIR/mix.rs:66:14 + | +LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); + | ^^^^^^^^^^^^^^^^^ + | + = note: expected values for `feature` are: bar, foo + +warning: unexpected `cfg` condition value + --> $DIR/mix.rs:66:33 + | +LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); + | ^^^^^^^^^^^^^^^^^ + | + = note: expected values for `feature` are: bar, foo + +warning: unexpected `cfg` condition value + --> $DIR/mix.rs:66:52 + | +LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); + | ^^^^^^^^^^^^^^^^^ + | + = note: expected values for `feature` are: bar, foo + +warning: 23 warnings emitted diff --git a/src/test/ui/deprecation/feature-gate-deprecated_suggestion.stderr b/src/test/ui/deprecation/feature-gate-deprecated_suggestion.stderr index 3b995fed75c..438ce3349d2 100644 --- a/src/test/ui/deprecation/feature-gate-deprecated_suggestion.stderr +++ b/src/test/ui/deprecation/feature-gate-deprecated_suggestion.stderr @@ -5,7 +5,7 @@ LL | #[deprecated(suggestion = "foo")] | ^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(deprecated_suggestion)]` to the crate root - = note: see #XXX for more details + = note: see #94785 for more details error: aborting due to previous error diff --git a/src/test/ui/lifetimes/issue-95023.rs b/src/test/ui/lifetimes/issue-95023.rs new file mode 100644 index 00000000000..3fba8c00c57 --- /dev/null +++ b/src/test/ui/lifetimes/issue-95023.rs @@ -0,0 +1,11 @@ +struct ErrorKind; +struct Error(ErrorKind); +impl Fn(&isize) for Error { + //~^ ERROR manual implementations of `Fn` are experimental [E0183] + //~^^ ERROR associated type bindings are not allowed here [E0229] + fn foo<const N: usize>(&self) -> Self::B<{N}>; + //~^ ERROR associated function in `impl` without body + //~^^ ERROR method `foo` is not a member of trait `Fn` [E0407] + //~^^^ ERROR associated type `B` not found for `Self` [E0220] +} +fn main() {} diff --git a/src/test/ui/lifetimes/issue-95023.stderr b/src/test/ui/lifetimes/issue-95023.stderr new file mode 100644 index 00000000000..35c3797c77a --- /dev/null +++ b/src/test/ui/lifetimes/issue-95023.stderr @@ -0,0 +1,38 @@ +error: associated function in `impl` without body + --> $DIR/issue-95023.rs:6:5 + | +LL | fn foo<const N: usize>(&self) -> Self::B<{N}>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the function: `{ <body> }` + +error[E0407]: method `foo` is not a member of trait `Fn` + --> $DIR/issue-95023.rs:6:5 + | +LL | fn foo<const N: usize>(&self) -> Self::B<{N}>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `Fn` + +error[E0183]: manual implementations of `Fn` are experimental + --> $DIR/issue-95023.rs:3:6 + | +LL | impl Fn(&isize) for Error { + | ^^^^^^^^^^ manual implementations of `Fn` are experimental + | + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable + +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-95023.rs:3:6 + | +LL | impl Fn(&isize) for Error { + | ^^^^^^^^^^ associated type not allowed here + +error[E0220]: associated type `B` not found for `Self` + --> $DIR/issue-95023.rs:6:44 + | +LL | fn foo<const N: usize>(&self) -> Self::B<{N}>; + | ^ associated type `B` not found + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0183, E0220, E0229, E0407. +For more information about an error, try `rustc --explain E0183`. diff --git a/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr b/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr index e96b67da336..6823a426823 100644 --- a/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr +++ b/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr @@ -19,6 +19,11 @@ help: try surrounding the expression in parentheses | LL | (vec![1, 2, 3]: Vec<i32>)[0]; | + + +help: alternatively, remove the type ascription + | +LL - vec![1, 2, 3]: Vec<i32>[0]; +LL + vec![1, 2, 3][0]; + | error: casts cannot be followed by indexing --> $DIR/issue-35813-postfix-after-cast.rs:17:5 @@ -41,6 +46,11 @@ help: try surrounding the expression in parentheses | LL | ((&[0i32]): &[i32; 1])[0]; | + + +help: alternatively, remove the type ascription + | +LL - (&[0i32]): &[i32; 1][0]; +LL + (&[0i32])[0]; + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:39:13 @@ -52,6 +62,11 @@ help: try surrounding the expression in parentheses | LL | let _ = (0i32: i32: i32).count_ones(); | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0i32: i32: i32.count_ones(); +LL + let _ = 0i32: i32.count_ones(); + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:41:13 @@ -63,6 +78,11 @@ help: try surrounding the expression in parentheses | LL | let _ = (0 as i32: i32).count_ones(); | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0 as i32: i32.count_ones(); +LL + let _ = 0 as i32.count_ones(); + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:43:13 @@ -107,6 +127,11 @@ help: try surrounding the expression in parentheses | LL | let _ = (0i32: i32).count_ones(): u32; | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0i32: i32.count_ones(): u32; +LL + let _ = 0i32.count_ones(): u32; + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:51:13 @@ -129,6 +154,11 @@ help: try surrounding the expression in parentheses | LL | let _ = (0i32: i32).count_ones() as u32; | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0i32: i32.count_ones() as u32; +LL + let _ = 0i32.count_ones() as u32; + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:55:13 @@ -151,6 +181,11 @@ help: try surrounding the expression in parentheses | LL | let _ = (0i32: i32: i32).count_ones() as u32 as i32; | + + +help: alternatively, remove the type ascription + | +LL - let _ = 0i32: i32: i32.count_ones() as u32 as i32; +LL + let _ = 0i32: i32.count_ones() as u32 as i32; + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:62:13 @@ -198,6 +233,11 @@ help: try surrounding the expression in parentheses | LL | (0: i32).max(0); | + + +help: alternatively, remove the type ascription + | +LL - 0: i32.max(0); +LL + 0.max(0); + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:92:8 @@ -220,6 +260,11 @@ help: try surrounding the expression in parentheses | LL | if (5u64: u64).max(0) == 0 { | + + +help: alternatively, remove the type ascription + | +LL - if 5u64: u64.max(0) == 0 { +LL + if 5u64.max(0) == 0 { + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:102:9 @@ -242,6 +287,11 @@ help: try surrounding the expression in parentheses | LL | (5u64: u64).max(0) == 0 | + + +help: alternatively, remove the type ascription + | +LL - 5u64: u64.max(0) == 0 +LL + 5u64.max(0) == 0 + | error: casts cannot be followed by indexing --> $DIR/issue-35813-postfix-after-cast.rs:111:24 @@ -264,6 +314,11 @@ help: try surrounding the expression in parentheses | LL | static bar2: &[i32] = &((&[1i32,2,3]: &[i32; 3])[0..1]); | + + +help: alternatively, remove the type ascription + | +LL - static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]); +LL + static bar2: &[i32] = &(&[1i32,2,3][0..1]); + | error: casts cannot be followed by `?` --> $DIR/issue-35813-postfix-after-cast.rs:119:5 @@ -286,6 +341,11 @@ help: try surrounding the expression in parentheses | LL | (Err(0u64): Result<u64,u64>)?; | + + +help: alternatively, remove the type ascription + | +LL - Err(0u64): Result<u64,u64>?; +LL + Err(0u64)?; + | error: casts cannot be followed by a function call --> $DIR/issue-35813-postfix-after-cast.rs:145:5 @@ -308,6 +368,11 @@ help: try surrounding the expression in parentheses | LL | (drop_ptr: fn(u8))(0); | + + +help: alternatively, remove the type ascription + | +LL - drop_ptr: fn(u8)(0); +LL + drop_ptr(0); + | error: casts cannot be followed by `.await` --> $DIR/issue-35813-postfix-after-cast.rs:152:5 @@ -330,6 +395,11 @@ help: try surrounding the expression in parentheses | LL | (Box::pin(noop()): Pin<Box<_>>).await; | + + +help: alternatively, remove the type ascription + | +LL - Box::pin(noop()): Pin<Box<_>>.await; +LL + Box::pin(noop()).await; + | error: casts cannot be followed by a field access --> $DIR/issue-35813-postfix-after-cast.rs:167:5 @@ -352,6 +422,11 @@ help: try surrounding the expression in parentheses | LL | (Foo::default(): Foo).bar; | + + +help: alternatively, remove the type ascription + | +LL - Foo::default(): Foo.bar; +LL + Foo::default().bar; + | error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:84:9 @@ -374,6 +449,11 @@ help: try surrounding the expression in parentheses | LL | (if true { 33 } else { 44 }: i32).max(0) | + + +help: alternatively, remove the type ascription + | +LL - if true { 33 } else { 44 }: i32.max(0) +LL + if true { 33 } else { 44 }.max(0) + | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-35813-postfix-after-cast.rs:131:13 diff --git a/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.rs b/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.rs new file mode 100644 index 00000000000..e815c7611c0 --- /dev/null +++ b/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.rs @@ -0,0 +1,6 @@ +struct TypedArenaChunk { + next: Option<String>> + //~^ ERROR unmatched angle bracket +} + +fn main() {} diff --git a/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.stderr b/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.stderr new file mode 100644 index 00000000000..17237c93097 --- /dev/null +++ b/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.stderr @@ -0,0 +1,11 @@ +error: unmatched angle bracket + --> $DIR/recover-field-extra-angle-brackets-in-struct-with-a-field.rs:2:25 + | +LL | next: Option<String>> + | _________________________^ +LL | | +LL | | } + | |_ help: remove extra angle bracket + +error: aborting due to previous error + diff --git a/src/test/ui/unsafe/union-modification.rs b/src/test/ui/unsafe/union-modification.rs new file mode 100644 index 00000000000..5c70b78df7c --- /dev/null +++ b/src/test/ui/unsafe/union-modification.rs @@ -0,0 +1,39 @@ +// run-pass +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +#![feature(untagged_unions)] + +union Foo { + bar: i8, + _blah: isize, + _zst: (), +} + +struct FooHolder { + inner_foo: Foo +} + +fn do_nothing(_x: &mut Foo) {} + +pub fn main() { + let mut foo = Foo { bar: 5 }; + do_nothing(&mut foo); + foo.bar = 6; + unsafe { foo.bar += 1; } + assert_eq!(unsafe { foo.bar }, 7); + unsafe { + let Foo { bar: inner } = foo; + assert_eq!(inner, 7); + } + + let foo = Foo { bar: 5 }; + let foo = if let 3 = if let true = true { 3 } else { 4 } { foo } else { foo }; + + let (_foo2, _random) = (foo, 42); + + let mut foo_holder = FooHolder { inner_foo: Foo { bar: 5 } }; + foo_holder.inner_foo.bar = 4; + assert_eq!(unsafe { foo_holder.inner_foo.bar }, 4); + drop(foo_holder); +} diff --git a/src/test/ui/unsafe/union.mir.stderr b/src/test/ui/unsafe/union.mir.stderr index f7bd411a744..787714cdd2d 100644 --- a/src/test/ui/unsafe/union.mir.stderr +++ b/src/test/ui/unsafe/union.mir.stderr @@ -1,16 +1,19 @@ -warning: unnecessary `unsafe` block - --> $DIR/union.rs:61:5 +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:30:20 | -LL | unsafe { - | ^^^^^^ unnecessary `unsafe` block +LL | Foo { bar: _a } => {}, + | ^^ access to union field | - = note: `#[warn(unused_unsafe)]` on by default + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -warning: unnecessary `unsafe` block - --> $DIR/union.rs:66:5 +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:32:11 | -LL | unsafe { - | ^^^^^^ unnecessary `unsafe` block +LL | match foo { + | ^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -warning: 2 warnings emitted +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/union.rs b/src/test/ui/unsafe/union.rs index 0130fa67f23..5fe09933cfc 100644 --- a/src/test/ui/unsafe/union.rs +++ b/src/test/ui/unsafe/union.rs @@ -1,4 +1,3 @@ -// run-pass // revisions: mir thir // [thir]compile-flags: -Z thir-unsafeck @@ -20,61 +19,35 @@ enum PizzaTopping { Pineapple, } -struct FooHolder { - inner_foo: Foo -} - fn do_nothing(_x: &mut Foo) {} pub fn main() { let mut foo = Foo { bar: 5 }; do_nothing(&mut foo); - foo.bar = 6; - unsafe { foo.bar += 1; } - assert_eq!(unsafe { foo.bar }, 7); - unsafe { - let Foo { bar: inner } = foo; - assert_eq!(inner, 7); + + // This is UB, so this test isn't run + match foo { + Foo { bar: _a } => {}, //~ ERROR access to union field is unsafe + } + match foo { //[mir]~ ERROR access to union field is unsafe + Foo { + pizza: Pizza { //[thir]~ ERROR access to union field is unsafe + topping: Some(PizzaTopping::Cheese) | Some(PizzaTopping::Pineapple) | None + } + } => {}, } - let foo = if let true = true { foo } else { foo }; - unsafe { - match foo { - Foo { bar: _a } => {}, - } + // MIR unsafeck incorrectly thinks that no unsafe block is needed to do these + match foo { + Foo { zst: () } => {}, //[thir]~ ERROR access to union field is unsafe } - unsafe { - match foo { - Foo { - pizza: Pizza { - topping: Some(PizzaTopping::Cheese) | Some(PizzaTopping::Pineapple) | None - } - } => {}, - } + match foo { + Foo { pizza: Pizza { .. } } => {}, //[thir]~ ERROR access to union field is unsafe } + // binding to wildcard is okay match foo { Foo { bar: _ } => {}, } let Foo { bar: _ } = foo; - // MIR unsafeck incorrectly thinks that it is safe to do these - unsafe { //[mir]~ WARNING - match foo { - Foo { zst: () } => {}, - } - } - unsafe { //[mir]~ WARNING - match foo { - Foo { pizza: Pizza { .. } } => {}, - } - } - let foo = Foo { bar: 5 }; - let foo = if let 3 = if let true = true { 3 } else { 4 } { foo } else { foo }; - - let (_foo2, _random) = (foo, 42); - - let mut foo_holder = FooHolder { inner_foo: Foo { bar: 5 } }; - foo_holder.inner_foo.bar = 4; - assert_eq!(unsafe { foo_holder.inner_foo.bar }, 4); - drop(foo_holder); } diff --git a/src/test/ui/unsafe/union.thir.stderr b/src/test/ui/unsafe/union.thir.stderr new file mode 100644 index 00000000000..e1a1bd634de --- /dev/null +++ b/src/test/ui/unsafe/union.thir.stderr @@ -0,0 +1,38 @@ +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:30:20 + | +LL | Foo { bar: _a } => {}, + | ^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:34:20 + | +LL | pizza: Pizza { + | ____________________^ +LL | | topping: Some(PizzaTopping::Cheese) | Some(PizzaTopping::Pineapple) | None +LL | | } + | |_____________^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:42:20 + | +LL | Foo { zst: () } => {}, + | ^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:45:22 + | +LL | Foo { pizza: Pizza { .. } } => {}, + | ^^^^^^^^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 65c82664263feddc5fe2d424be0993c28d46377 +Subproject 109bfbd055325ef87a6e7f63d67da7e838f8300 diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 3f2cd3ae232..503b624114a 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -487,11 +487,6 @@ fn configure_lldb(config: &Config) -> Option<Config> { return None; } - // Some older versions of LLDB seem to have problems with multiple - // instances running in parallel, so only run one test thread at a - // time. - env::set_var("RUST_TEST_THREADS", "1"); - Some(Config { debugger: Some(Debugger::Lldb), ..config.clone() }) } diff --git a/src/tools/miri b/src/tools/miri -Subproject 8e818ffa1b85f4e740c4096fd38c62b2b73f4d8 +Subproject 16c69fd2901b49148bff6f24292e7fc98967d7f diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index d6e36c2e7db..ab4be43e495 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -258,6 +258,7 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ "mach", "memchr", "object", + "once_cell", "regalloc", "region", "rustc-hash", diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 7b932b867f2..0e5e0c2616e 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -7,7 +7,7 @@ use std::path::Path; const ENTRY_LIMIT: usize = 1000; // FIXME: The following limits should be reduced eventually. -const ROOT_ENTRY_LIMIT: usize = 984; +const ROOT_ENTRY_LIMIT: usize = 985; const ISSUES_ENTRY_LIMIT: usize = 2310; fn check_entries(path: &Path, bad: &mut bool) { |
