From a20866254c6864e49814d6abd47a37fd01bcff0a Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Thu, 12 Oct 2023 15:35:03 -0700 Subject: [PATCH 01/20] References refer to allocated objects --- library/core/src/primitive_docs.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 380a21b376bde..e73d5f990cbac 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1389,6 +1389,18 @@ mod prim_usize {} /// work on references as well as they do on owned values! The implementations described here are /// meant for generic contexts, where the final type `T` is a type parameter or otherwise not /// locally known. +/// +/// # Safety +/// +/// For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`, unsafe code may assume that +/// the following properties hold. It is undefined behavior to produce a `t: &T` or `t: &mut T` +/// which violates any of these properties. +/// +/// * `t` is aligned to `align_of_val(t)` +/// * `t` refers to a valid instance of `T` +/// * `t` refers to a single [allocated object] +/// +/// [allocated object]: ptr#allocated-object #[stable(feature = "rust1", since = "1.0.0")] mod prim_ref {} From 4f0192a756f756db6bd1c25a8dbe6e89f0086661 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Thu, 12 Oct 2023 18:55:45 -0700 Subject: [PATCH 02/20] Update primitive_docs.rs --- library/core/src/primitive_docs.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index e73d5f990cbac..04ae8c223f2cb 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1397,7 +1397,6 @@ mod prim_usize {} /// which violates any of these properties. /// /// * `t` is aligned to `align_of_val(t)` -/// * `t` refers to a valid instance of `T` /// * `t` refers to a single [allocated object] /// /// [allocated object]: ptr#allocated-object From 39660c4a77d3dda7f5d57a8d91faa946fff5192b Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Fri, 13 Oct 2023 09:47:39 -0700 Subject: [PATCH 03/20] Update library/core/src/primitive_docs.rs Co-authored-by: Ralf Jung --- library/core/src/primitive_docs.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 04ae8c223f2cb..cde49aeb687f0 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1397,7 +1397,11 @@ mod prim_usize {} /// which violates any of these properties. /// /// * `t` is aligned to `align_of_val(t)` -/// * `t` refers to a single [allocated object] +/// * `t` is dereferenceable for `size_of_val(t)` many bytes +/// +/// Being "dereferenceable" for N bytes means that the memory range beginning +/// at the address `t` points to and ending N bytes later is all contained within a +/// single [allocated object]. /// /// [allocated object]: ptr#allocated-object #[stable(feature = "rust1", since = "1.0.0")] From 55487e235b106088ced4e5b4710fa8f9674baaf9 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Fri, 13 Oct 2023 09:49:23 -0700 Subject: [PATCH 04/20] Update primitive_docs.rs --- library/core/src/primitive_docs.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index cde49aeb687f0..19ff41697d9fc 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1399,9 +1399,8 @@ mod prim_usize {} /// * `t` is aligned to `align_of_val(t)` /// * `t` is dereferenceable for `size_of_val(t)` many bytes /// -/// Being "dereferenceable" for N bytes means that the memory range beginning -/// at the address `t` points to and ending N bytes later is all contained within a -/// single [allocated object]. +/// If `t` points at address `a`, being "dereferenceable" for N bytes means that the memory range +/// `[a, a + N)` is all contained within a single [allocated object]. /// /// [allocated object]: ptr#allocated-object #[stable(feature = "rust1", since = "1.0.0")] From 1a0309afb62b01002c1ac2466a6af0dc69594596 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Fri, 3 Nov 2023 06:41:23 -0700 Subject: [PATCH 05/20] Update primitive_docs.rs --- library/core/src/primitive_docs.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 19ff41697d9fc..939342c4d9760 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1393,8 +1393,9 @@ mod prim_usize {} /// # Safety /// /// For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`, unsafe code may assume that -/// the following properties hold. It is undefined behavior to produce a `t: &T` or `t: &mut T` -/// which violates any of these properties. +/// the following properties hold. Rust programmers must assume that, unless explicitly stated +/// otherwise, any Rust code they did not author themselves may rely on these properties, and that +/// violating them may cause that code to exhibit undefined behavior. /// /// * `t` is aligned to `align_of_val(t)` /// * `t` is dereferenceable for `size_of_val(t)` many bytes From ab938b9acbf1d5849198cba19e14959d8ad2871f Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Tue, 23 Jan 2024 11:29:11 +0100 Subject: [PATCH 06/20] Improve documentation for [A]Rc::into_inner General improvements, and also aims to better encourage the reader to actually check out Arc::try_unwrap. --- library/alloc/src/rc.rs | 7 +++++-- library/alloc/src/sync.rs | 10 +++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index f986df058467b..197d3a6e55ef6 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -938,8 +938,11 @@ impl Rc { /// it is guaranteed that exactly one of the calls returns the inner value. /// This means in particular that the inner value is not dropped. /// - /// This is equivalent to `Rc::try_unwrap(this).ok()`. (Note that these are not equivalent for - /// [`Arc`](crate::sync::Arc), due to race conditions that do not apply to `Rc`.) + /// [`Rc::try_unwrap`] is conceptually similar to `Rc::into_inner`. + /// And while they are meant for different use-cases, `Rc::into_inner(this)` + /// is in fact equivalent to [Rc::try_unwrap]\(this).[ok][Result::ok](). + /// (Note that the same kind of equivalence does **not** hold true for + /// [`Arc`](crate::sync::Arc), due to race conditions that do not apply to `Rc`!) #[inline] #[stable(feature = "rc_into_inner", since = "1.70.0")] pub fn into_inner(this: Self) -> Option { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index dc82c9c411110..4784a5db17ab5 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -983,9 +983,13 @@ impl Arc { /// it is guaranteed that exactly one of the calls returns the inner value. /// This means in particular that the inner value is not dropped. /// - /// The similar expression `Arc::try_unwrap(this).ok()` does not - /// offer such a guarantee. See the last example below - /// and the documentation of [`Arc::try_unwrap`]. + /// [`Arc::try_unwrap`] is conceptually similar to `Arc::into_inner`, but it + /// is meant for different use-cases. If used as a direct replacement + /// for `Arc::into_inner` anyway, such as with the expression + /// [Arc::try_unwrap]\(this).[ok][Result::ok](), then it does + /// **not** give the same guarantee as described in the previous paragraph. + /// For more information, see the examples below and read the documentation + /// of [`Arc::try_unwrap`]. /// /// # Examples /// From 797cf5927872459a00ca3a2758216c8aa89cef2b Mon Sep 17 00:00:00 2001 From: Lawrence Tang Date: Mon, 22 Jan 2024 11:33:02 +0000 Subject: [PATCH 07/20] Add support for custom JSON targets when using build-std. Currently, when building with `build-std`, some library build scripts check properties of the target by inspecting the target triple at `env::TARGET`, which is simply set to the filename of the JSON file when using JSON target files. This patch alters these build scripts to use `env::CARGO_CFG_*` to fetch target information instead, allowing JSON target files describing platforms without `restricted_std` to build correctly when using `-Z build-std`. Fixes wg-cargo-std-aware/#60. --- library/profiler_builtins/build.rs | 7 +-- library/std/build.rs | 77 ++++++++++++++++-------------- 2 files changed, 45 insertions(+), 39 deletions(-) diff --git a/library/profiler_builtins/build.rs b/library/profiler_builtins/build.rs index d14d0b82229a1..8e7b72f837220 100644 --- a/library/profiler_builtins/build.rs +++ b/library/profiler_builtins/build.rs @@ -12,7 +12,8 @@ fn main() { return; } - let target = env::var("TARGET").expect("TARGET was not set"); + let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS was not set"); + let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set"); let cfg = &mut cc::Build::new(); // FIXME: `rerun-if-changed` directives are not currently emitted and the build script @@ -40,7 +41,7 @@ fn main() { "InstrProfilingBiasVar.c", ]; - if target.contains("msvc") { + if target_env == "msvc" { // Don't pull in extra libraries on MSVC cfg.flag("/Zl"); profile_sources.push("WindowsMMap.c"); @@ -55,7 +56,7 @@ fn main() { cfg.flag("-fno-builtin"); cfg.flag("-fomit-frame-pointer"); cfg.define("VISIBILITY_HIDDEN", None); - if !target.contains("windows") { + if target_os != "windows" { cfg.flag("-fvisibility=hidden"); cfg.define("COMPILER_RT_HAS_UNAME", Some("1")); } else { diff --git a/library/std/build.rs b/library/std/build.rs index 60c097db2f4bf..b3da198881676 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -2,41 +2,46 @@ use std::env; fn main() { println!("cargo:rerun-if-changed=build.rs"); - let target = env::var("TARGET").expect("TARGET was not set"); - if target.contains("linux") - || target.contains("netbsd") - || target.contains("dragonfly") - || target.contains("openbsd") - || target.contains("freebsd") - || target.contains("solaris") - || target.contains("illumos") - || target.contains("apple-darwin") - || target.contains("apple-ios") - || target.contains("apple-tvos") - || target.contains("apple-watchos") - || target.contains("uwp") - || target.contains("windows") - || target.contains("fuchsia") - || (target.contains("sgx") && target.contains("fortanix")) - || target.contains("hermit") - || target.contains("l4re") - || target.contains("redox") - || target.contains("haiku") - || target.contains("vxworks") - || target.contains("wasm32") - || target.contains("wasm64") - || target.contains("espidf") - || target.contains("solid") - || target.contains("nintendo-3ds") - || target.contains("vita") - || target.contains("aix") - || target.contains("nto") - || target.contains("xous") - || target.contains("hurd") - || target.contains("uefi") - || target.contains("teeos") - || target.contains("zkvm") - // See src/bootstrap/synthetic_targets.rs + let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH was not set"); + let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS was not set"); + let target_vendor = + env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set"); + let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set"); + + if target_os == "linux" + || target_os == "netbsd" + || target_os == "dragonfly" + || target_os == "openbsd" + || target_os == "freebsd" + || target_os == "solaris" + || target_os == "illumos" + || target_os == "macos" + || target_os == "ios" + || target_os == "tvos" + || target_os == "watchos" + || target_os == "windows" + || target_os == "fuchsia" + || (target_vendor == "fortranix" && target_env == "sgx") + || target_os == "hermit" + || target_os == "l4re" + || target_os == "redox" + || target_os == "haiku" + || target_os == "vxworks" + || target_arch == "wasm32" + || target_arch == "wasm64" + || target_os == "espidf" + || target_os.starts_with("solid") + || (target_vendor == "nintendo" && target_env == "newlib") + || target_os == "vita" + || target_os == "aix" + || target_os == "nto" + || target_os == "xous" + || target_os == "hurd" + || target_os == "uefi" + || target_os == "teeos" + || target_os == "zkvm" + + // See src/bootstrap/src/core/build_steps/synthetic_targets.rs || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok() { // These platforms don't have any special requirements. @@ -48,7 +53,7 @@ fn main() { // - mipsel-sony-psp // - nvptx64-nvidia-cuda // - arch=avr - // - JSON targets + // - JSON targets not describing an excluded target above. // - Any new targets that have not been explicitly added above. println!("cargo:rustc-cfg=feature=\"restricted-std\""); } From c2c6e333356f53338e6eecd710faf663217a0074 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Thu, 25 Jan 2024 06:59:51 -0800 Subject: [PATCH 08/20] Update primitive_docs.rs --- library/core/src/primitive_docs.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 939342c4d9760..fca2d3979ab47 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1403,6 +1403,10 @@ mod prim_usize {} /// If `t` points at address `a`, being "dereferenceable" for N bytes means that the memory range /// `[a, a + N)` is all contained within a single [allocated object]. /// +/// Note that the precise validity invariants for reference types are a work in progress. In the +/// future, new guarantees may be added. However, the guarantees documented in this section will +/// never be removed. +/// /// [allocated object]: ptr#allocated-object #[stable(feature = "rust1", since = "1.0.0")] mod prim_ref {} From 3269513eb0189946c40a67d98724b40321e6e9f3 Mon Sep 17 00:00:00 2001 From: "HTGAzureX1212." <39023054+HTGAzureX1212@users.noreply.github.com> Date: Fri, 26 Jan 2024 20:15:30 +0800 Subject: [PATCH 09/20] fix issue 120040 --- library/std/src/sys/pal/windows/fs.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index 4248454368644..06a08ea22ebee 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -1068,6 +1068,27 @@ pub fn readdir(p: &Path) -> io::Result { unsafe { let mut wfd = mem::zeroed(); let find_handle = c::FindFirstFileW(path.as_ptr(), &mut wfd); + + // The status `ERROR_FILE_NOT_FOUND` is returned by the `FindFirstFileW` function + // if no matching files can be found, but not necessarily that the path to find the + // files in does not exist. + // + // Hence, a check for whether the path to search in exists is added when the last + // os error returned by Windows is `ERROR_FILE_NOT_FOUND` to handle this scenario. + // If that is the case, an empty `ReadDir` iterator is returned as it returns `None` + // in the initial `.next()` invocation because `ERROR_NO_MORE_FILES` would have been + // returned by the `FindNextFileW` function. + // + // See issue #120040: https://github.com/rust-lang/rust/issues/120040. + let last_error = Error::last_os_error(); + if last_error.raw_os_error().unwrap() == c::ERROR_FILE_NOT_FOUND && p.exists() { + return Ok(ReadDir { + handle: FindNextFileHandle(file_handle), + root: Arc::new(root), + first: None, + }); + } + if find_handle != c::INVALID_HANDLE_VALUE { Ok(ReadDir { handle: FindNextFileHandle(find_handle), From 8f89e57e9f7fe4a2fccf57161aea39a4e48b6a75 Mon Sep 17 00:00:00 2001 From: "HTGAzureX1212." <39023054+HTGAzureX1212@users.noreply.github.com> Date: Fri, 26 Jan 2024 20:27:20 +0800 Subject: [PATCH 10/20] remove redundant call to Error::last_os_error --- library/std/src/sys/pal/windows/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index 06a08ea22ebee..b5976b87be210 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -1096,7 +1096,7 @@ pub fn readdir(p: &Path) -> io::Result { first: Some(wfd), }) } else { - Err(Error::last_os_error()) + Err(last_error) } } } From 2241d1618960a2d192b2874e925fa51afeb8a83b Mon Sep 17 00:00:00 2001 From: "HTGAzureX1212." <39023054+HTGAzureX1212@users.noreply.github.com> Date: Fri, 26 Jan 2024 20:34:13 +0800 Subject: [PATCH 11/20] fix --- library/std/src/sys/pal/windows/fs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index b5976b87be210..38835db7649de 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -1081,9 +1081,9 @@ pub fn readdir(p: &Path) -> io::Result { // // See issue #120040: https://github.com/rust-lang/rust/issues/120040. let last_error = Error::last_os_error(); - if last_error.raw_os_error().unwrap() == c::ERROR_FILE_NOT_FOUND && p.exists() { + if last_error.raw_os_error().unwrap() == c::ERROR_FILE_NOT_FOUND as i32 && p.exists() { return Ok(ReadDir { - handle: FindNextFileHandle(file_handle), + handle: FindNextFileHandle(find_handle), root: Arc::new(root), first: None, }); From 40f5e6899d00484f05a3f1b227180a69a43bea0f Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Thu, 28 Dec 2023 16:20:02 -0800 Subject: [PATCH 12/20] Build Fuchsia on 8 cores instead of 16 --- .github/workflows/ci.yml | 2 +- src/ci/github-actions/ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index caf97abf78d9e..e8e103df68b3b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -291,7 +291,7 @@ jobs: - name: x86_64-gnu-integration env: CI_ONLY_WHEN_CHANNEL: nightly - os: ubuntu-20.04-16core-64gb + os: ubuntu-20.04-8core-32gb - name: x86_64-gnu-debug os: ubuntu-20.04-8core-32gb env: {} diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 68a3afc910f22..659d048cc1d9a 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -476,7 +476,7 @@ jobs: # nightly features to compile, and this job would fail if # executed on beta and stable. CI_ONLY_WHEN_CHANNEL: nightly - <<: *job-linux-16c + <<: *job-linux-8c - name: x86_64-gnu-debug <<: *job-linux-8c From 53bf511af2b9b54702943eb4fe6e4f17d9fc96c6 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Thu, 28 Dec 2023 16:44:49 -0800 Subject: [PATCH 13/20] Skip building cranelift for Fuchsia This refactors run.sh to never override an explicit $CODEGEN_BACKENDS if set in the build. --- .../docker/host-x86_64/x86_64-gnu-integration/Dockerfile | 3 +++ src/ci/run.sh | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile index ba65ba9bed460..3132f9e0098b3 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile @@ -51,6 +51,9 @@ RUN sh /scripts/sccache.sh ENV RUST_INSTALL_DIR /checkout/obj/install RUN mkdir -p $RUST_INSTALL_DIR/etc +# Fuchsia only supports LLVM. +ENV CODEGEN_BACKENDS llvm + ENV RUST_CONFIGURE_ARGS \ --prefix=$RUST_INSTALL_DIR \ --sysconfdir=etc \ diff --git a/src/ci/run.sh b/src/ci/run.sh index 420545172e6d5..1cdcffc1a7544 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -119,7 +119,8 @@ if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir" fi - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.codegen-backends=${CODEGEN_BACKENDS:-llvm}" + CODEGEN_BACKENDS="${CODEGEN_BACKENDS:-llvm}" + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.codegen-backends=$CODEGEN_BACKENDS" else # We almost always want debug assertions enabled, but sometimes this takes too # long for too little benefit, so we just turn them off. @@ -144,11 +145,12 @@ else # tests as it will fail them. if [[ "${ENABLE_GCC_CODEGEN}" == "1" ]]; then # Test the Cranelift and GCC backends in CI. Bootstrap knows which targets to run tests on. - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.codegen-backends=llvm,cranelift,gcc" + CODEGEN_BACKENDS="${CODEGEN_BACKENDS:-llvm,cranelift,gcc}" else # Test the Cranelift backend in CI. Bootstrap knows which targets to run tests on. - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.codegen-backends=llvm,cranelift" + CODEGEN_BACKENDS="${CODEGEN_BACKENDS:-llvm,cranelift}" fi + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.codegen-backends=$CODEGEN_BACKENDS" # We enable this for non-dist builders, since those aren't trying to produce # fresh binaries. We currently don't entirely support distributing a fresh From afd5edc8c995662760ed9cccce687637af86967f Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Thu, 25 Jan 2024 16:40:15 -0800 Subject: [PATCH 14/20] Bump Fuchsia (includes building tests) This includes a change to the upstream build_fuchsia_from_rust_ci script that builds a minimal set of tests, to improve coverage on this builder. --- src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile | 1 + .../docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile index 3132f9e0098b3..bec1c89733775 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile @@ -44,6 +44,7 @@ ENV CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS \ ENV TARGETS=x86_64-fuchsia ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnu +ENV TARGETS=$TARGETS,wasm32-unknown-unknown COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh b/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh index 4a246f591d717..d6de992913bf5 100755 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh +++ b/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh @@ -5,7 +5,7 @@ set -euf -o pipefail -INTEGRATION_SHA=66793c4894bf6204579bbee3b79956335f31c768 +INTEGRATION_SHA=56310bca298872ffb5ea02e665956d9b6dc41171 PICK_REFS=() checkout=fuchsia From e26f213050f451ec3e9c6a3132bc0d5be5123737 Mon Sep 17 00:00:00 2001 From: "HTGAzureX1212." <39023054+HTGAzureX1212@users.noreply.github.com> Date: Sat, 27 Jan 2024 12:28:28 +0800 Subject: [PATCH 15/20] make modifications as per reviews --- library/std/src/sys/pal/windows/fs.rs | 46 +++++++++++++++------------ 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index 38835db7649de..1a8151479f390 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -1069,26 +1069,6 @@ pub fn readdir(p: &Path) -> io::Result { let mut wfd = mem::zeroed(); let find_handle = c::FindFirstFileW(path.as_ptr(), &mut wfd); - // The status `ERROR_FILE_NOT_FOUND` is returned by the `FindFirstFileW` function - // if no matching files can be found, but not necessarily that the path to find the - // files in does not exist. - // - // Hence, a check for whether the path to search in exists is added when the last - // os error returned by Windows is `ERROR_FILE_NOT_FOUND` to handle this scenario. - // If that is the case, an empty `ReadDir` iterator is returned as it returns `None` - // in the initial `.next()` invocation because `ERROR_NO_MORE_FILES` would have been - // returned by the `FindNextFileW` function. - // - // See issue #120040: https://github.com/rust-lang/rust/issues/120040. - let last_error = Error::last_os_error(); - if last_error.raw_os_error().unwrap() == c::ERROR_FILE_NOT_FOUND as i32 && p.exists() { - return Ok(ReadDir { - handle: FindNextFileHandle(find_handle), - root: Arc::new(root), - first: None, - }); - } - if find_handle != c::INVALID_HANDLE_VALUE { Ok(ReadDir { handle: FindNextFileHandle(find_handle), @@ -1096,7 +1076,31 @@ pub fn readdir(p: &Path) -> io::Result { first: Some(wfd), }) } else { - Err(last_error) + // The status `ERROR_FILE_NOT_FOUND` is returned by the `FindFirstFileW` function + // if no matching files can be found, but not necessarily that the path to find the + // files in does not exist. + // + // Hence, a check for whether the path to search in exists is added when the last + // os error returned by Windows is `ERROR_FILE_NOT_FOUND` to handle this scenario. + // If that is the case, an empty `ReadDir` iterator is returned as it returns `None` + // in the initial `.next()` invocation because `ERROR_NO_MORE_FILES` would have been + // returned by the `FindNextFileW` function. + // + // See issue #120040: https://github.com/rust-lang/rust/issues/120040. + let last_error = api::get_last_error(); + if last_error.code == c::ERROR_FILE_NOT_FOUND { + return Ok(ReadDir { + handle: FindNextFileHandle(find_handle), + root: Arc::new(root), + first: None, + }); + } + + // Just return the error constructed from the raw OS error if the above is not the case. + // + // Note: `ERROR_PATH_NOT_FOUND` would have been returned by the `FindFirstFileW` function + // when the path to search in does not exist in the first place. + Err(Error::from_raw_os_error(last_error.code as i32)); } } } From 018bf305cdcc2d478998642bc2d9a5613ec902f3 Mon Sep 17 00:00:00 2001 From: "HTGAzureX1212." <39023054+HTGAzureX1212@users.noreply.github.com> Date: Sat, 27 Jan 2024 12:43:38 +0800 Subject: [PATCH 16/20] add extra check for invalid handle in ReadDir::next --- library/std/src/sys/pal/windows/fs.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index 1a8151479f390..2bdd3d96fa48c 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -112,6 +112,13 @@ impl fmt::Debug for ReadDir { impl Iterator for ReadDir { type Item = io::Result; fn next(&mut self) -> Option> { + if self.handle.0 == c::INVALID_HANDLE_VALUE { + // This iterator was initialized with an `INVALID_HANDLE_VALUE` as its handle. + // Simply return `None` because this is only the case when `FindFirstFileW` in + // the construction of this iterator returns `ERROR_FILE_NOT_FOUND` which means + // no matchhing files can be found. + return None; + } if let Some(first) = self.first.take() { if let Some(e) = DirEntry::new(&self.root, &first) { return Some(Ok(e)); @@ -1100,7 +1107,7 @@ pub fn readdir(p: &Path) -> io::Result { // // Note: `ERROR_PATH_NOT_FOUND` would have been returned by the `FindFirstFileW` function // when the path to search in does not exist in the first place. - Err(Error::from_raw_os_error(last_error.code as i32)); + Err(Error::from_raw_os_error(last_error.code as i32)) } } } From f5c78955c88ac37b7422bef6ee9ec993c0a5dad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Sat, 27 Jan 2024 14:18:33 +0200 Subject: [PATCH 17/20] Stop using derivative in rustc_pattern_analysis --- Cargo.lock | 1 - compiler/rustc_pattern_analysis/Cargo.toml | 1 - .../rustc_pattern_analysis/src/constructor.rs | 98 ++++++++++++++++++- compiler/rustc_pattern_analysis/src/lib.rs | 20 +++- compiler/rustc_pattern_analysis/src/pat.rs | 31 +++++- compiler/rustc_pattern_analysis/src/rustc.rs | 8 +- .../rustc_pattern_analysis/src/usefulness.rs | 58 ++++++++--- 7 files changed, 191 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 28068684362e4..587489a94b20e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4342,7 +4342,6 @@ dependencies = [ name = "rustc_pattern_analysis" version = "0.0.0" dependencies = [ - "derivative", "rustc-hash", "rustc_apfloat", "rustc_arena", diff --git a/compiler/rustc_pattern_analysis/Cargo.toml b/compiler/rustc_pattern_analysis/Cargo.toml index 1d0e1cb7e6a57..b9bdcb41929dc 100644 --- a/compiler/rustc_pattern_analysis/Cargo.toml +++ b/compiler/rustc_pattern_analysis/Cargo.toml @@ -5,7 +5,6 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -derivative = "2.2.0" rustc-hash = "1.1.0" rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena", optional = true } diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs index e94a0373c79ff..4996015f86345 100644 --- a/compiler/rustc_pattern_analysis/src/constructor.rs +++ b/compiler/rustc_pattern_analysis/src/constructor.rs @@ -151,6 +151,7 @@ use std::cmp::{self, max, min, Ordering}; use std::fmt; use std::iter::once; +use std::mem; use smallvec::SmallVec; @@ -648,8 +649,6 @@ impl OpaqueId { /// `specialize_constructor` returns the list of fields corresponding to a pattern, given a /// constructor. `Constructor::apply` reconstructs the pattern from a pair of `Constructor` and /// `Fields`. -#[derive(derivative::Derivative)] -#[derivative(Debug(bound = ""), Clone(bound = ""), PartialEq(bound = ""))] pub enum Constructor { /// Tuples and structs. Struct, @@ -692,6 +691,101 @@ pub enum Constructor { Missing, } +impl Clone for Constructor { + fn clone(&self) -> Self { + match self { + Constructor::Struct => Constructor::Struct, + Constructor::Variant(idx) => Constructor::Variant(idx.clone()), + Constructor::Ref => Constructor::Ref, + Constructor::Slice(slice) => Constructor::Slice(slice.clone()), + Constructor::UnionField => Constructor::UnionField, + Constructor::Bool(b) => Constructor::Bool(b.clone()), + Constructor::IntRange(range) => Constructor::IntRange(range.clone()), + Constructor::F32Range(lo, hi, end) => { + Constructor::F32Range(lo.clone(), hi.clone(), end.clone()) + } + Constructor::F64Range(lo, hi, end) => { + Constructor::F64Range(lo.clone(), hi.clone(), end.clone()) + } + Constructor::Str(value) => Constructor::Str(value.clone()), + Constructor::Opaque(inner) => Constructor::Opaque(inner.clone()), + Constructor::Or => Constructor::Or, + Constructor::Wildcard => Constructor::Wildcard, + Constructor::NonExhaustive => Constructor::NonExhaustive, + Constructor::Hidden => Constructor::Hidden, + Constructor::Missing => Constructor::Missing, + } + } +} + +impl fmt::Debug for Constructor { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Constructor::Struct => f.debug_tuple("Struct").finish(), + Constructor::Variant(idx) => f.debug_tuple("Variant").field(idx).finish(), + Constructor::Ref => f.debug_tuple("Ref").finish(), + Constructor::Slice(slice) => f.debug_tuple("Slice").field(slice).finish(), + Constructor::UnionField => f.debug_tuple("UnionField").finish(), + Constructor::Bool(b) => f.debug_tuple("Bool").field(b).finish(), + Constructor::IntRange(range) => f.debug_tuple("IntRange").field(range).finish(), + Constructor::F32Range(lo, hi, end) => { + f.debug_tuple("F32Range").field(lo).field(hi).field(end).finish() + } + Constructor::F64Range(lo, hi, end) => { + f.debug_tuple("F64Range").field(lo).field(hi).field(end).finish() + } + Constructor::Str(value) => f.debug_tuple("Str").field(value).finish(), + Constructor::Opaque(inner) => f.debug_tuple("Opaque").field(inner).finish(), + Constructor::Or => f.debug_tuple("Or").finish(), + Constructor::Wildcard => f.debug_tuple("Wildcard").finish(), + Constructor::NonExhaustive => f.debug_tuple("NonExhaustive").finish(), + Constructor::Hidden => f.debug_tuple("Hidden").finish(), + Constructor::Missing => f.debug_tuple("Missing").finish(), + } + } +} + +impl PartialEq for Constructor { + fn eq(&self, other: &Self) -> bool { + (mem::discriminant(self) == mem::discriminant(other)) + && match (self, other) { + (Constructor::Struct, Constructor::Struct) => true, + (Constructor::Variant(self_variant), Constructor::Variant(other_variant)) => { + self_variant == other_variant + } + (Constructor::Ref, Constructor::Ref) => true, + (Constructor::Slice(self_slice), Constructor::Slice(other_slice)) => { + self_slice == other_slice + } + (Constructor::UnionField, Constructor::UnionField) => true, + (Constructor::Bool(self_b), Constructor::Bool(other_b)) => self_b == other_b, + (Constructor::IntRange(self_range), Constructor::IntRange(other_range)) => { + self_range == other_range + } + ( + Constructor::F32Range(self_lo, self_hi, self_end), + Constructor::F32Range(other_lo, other_hi, other_end), + ) => self_lo == other_lo && self_hi == other_hi && self_end == other_end, + ( + Constructor::F64Range(self_lo, self_hi, self_end), + Constructor::F64Range(other_lo, other_hi, other_end), + ) => self_lo == other_lo && self_hi == other_hi && self_end == other_end, + (Constructor::Str(self_value), Constructor::Str(other_value)) => { + self_value == other_value + } + (Constructor::Opaque(self_inner), Constructor::Opaque(other_inner)) => { + self_inner == other_inner + } + (Constructor::Or, Constructor::Or) => true, + (Constructor::Wildcard, Constructor::Wildcard) => true, + (Constructor::NonExhaustive, Constructor::NonExhaustive) => true, + (Constructor::Hidden, Constructor::Hidden) => true, + (Constructor::Missing, Constructor::Missing) => true, + _ => unreachable!(), + } + } +} + impl Constructor { pub(crate) fn is_non_exhaustive(&self) -> bool { matches!(self, NonExhaustive) diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index 6374874165fc1..a53d7a0d8096a 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -136,23 +136,35 @@ pub trait TypeCx: Sized + fmt::Debug { } /// Context that provides information global to a match. -#[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""), Copy(bound = ""))] pub struct MatchCtxt<'a, Cx: TypeCx> { /// The context for type information. pub tycx: &'a Cx, } +impl<'a, Cx: TypeCx> Clone for MatchCtxt<'a, Cx> { + fn clone(&self) -> Self { + Self { tycx: self.tycx } + } +} + +impl<'a, Cx: TypeCx> Copy for MatchCtxt<'a, Cx> {} + /// The arm of a match expression. #[derive(Debug)] -#[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""), Copy(bound = ""))] pub struct MatchArm<'p, Cx: TypeCx> { pub pat: &'p DeconstructedPat<'p, Cx>, pub has_guard: bool, pub arm_data: Cx::ArmData, } +impl<'p, Cx: TypeCx> Clone for MatchArm<'p, Cx> { + fn clone(&self) -> Self { + Self { pat: self.pat, has_guard: self.has_guard, arm_data: self.arm_data } + } +} + +impl<'p, Cx: TypeCx> Copy for MatchArm<'p, Cx> {} + /// The entrypoint for this crate. Computes whether a match is exhaustive and which of its arms are /// useful, and runs some lints. #[cfg(feature = "rustc")] diff --git a/compiler/rustc_pattern_analysis/src/pat.rs b/compiler/rustc_pattern_analysis/src/pat.rs index 1cc3107455645..d476766d466f2 100644 --- a/compiler/rustc_pattern_analysis/src/pat.rs +++ b/compiler/rustc_pattern_analysis/src/pat.rs @@ -218,8 +218,6 @@ impl<'p, Cx: TypeCx> fmt::Debug for DeconstructedPat<'p, Cx> { /// algorithm. Do not use `Wild` to represent a wildcard pattern comping from user input. /// /// This is morally `Option<&'p DeconstructedPat>` where `None` is interpreted as a wildcard. -#[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""), Copy(bound = ""))] pub(crate) enum PatOrWild<'p, Cx: TypeCx> { /// A non-user-provided wildcard, created during specialization. Wild, @@ -227,6 +225,17 @@ pub(crate) enum PatOrWild<'p, Cx: TypeCx> { Pat(&'p DeconstructedPat<'p, Cx>), } +impl<'p, Cx: TypeCx> Clone for PatOrWild<'p, Cx> { + fn clone(&self) -> Self { + match self { + PatOrWild::Wild => PatOrWild::Wild, + PatOrWild::Pat(pat) => PatOrWild::Pat(pat), + } + } +} + +impl<'p, Cx: TypeCx> Copy for PatOrWild<'p, Cx> {} + impl<'p, Cx: TypeCx> PatOrWild<'p, Cx> { pub(crate) fn as_pat(&self) -> Option<&'p DeconstructedPat<'p, Cx>> { match self { @@ -289,14 +298,28 @@ impl<'p, Cx: TypeCx> fmt::Debug for PatOrWild<'p, Cx> { /// Same idea as `DeconstructedPat`, except this is a fictitious pattern built up for diagnostics /// purposes. As such they don't use interning and can be cloned. -#[derive(derivative::Derivative)] -#[derivative(Debug(bound = ""), Clone(bound = ""))] pub struct WitnessPat { ctor: Constructor, pub(crate) fields: Vec>, ty: Cx::Ty, } +impl Clone for WitnessPat { + fn clone(&self) -> Self { + Self { ctor: self.ctor.clone(), fields: self.fields.clone(), ty: self.ty.clone() } + } +} + +impl fmt::Debug for WitnessPat { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("WitnessPat") + .field("ctor", &self.ctor) + .field("fields", &self.fields) + .field("ty", &self.ty) + .finish() + } +} + impl WitnessPat { pub(crate) fn new(ctor: Constructor, fields: Vec, ty: Cx::Ty) -> Self { Self { ctor, fields, ty } diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index ef90d24b0bf1e..223d6cefc83fe 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -46,11 +46,15 @@ pub type WitnessPat<'p, 'tcx> = crate::pat::WitnessPat`. #[repr(transparent)] -#[derive(derivative::Derivative)] #[derive(Clone, Copy)] -#[derivative(Debug = "transparent")] pub struct RevealedTy<'tcx>(Ty<'tcx>); +impl<'tcx> fmt::Debug for RevealedTy<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(fmt) + } +} + impl<'tcx> std::ops::Deref for RevealedTy<'tcx> { type Target = Ty<'tcx>; fn deref(&self) -> &Self::Target { diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index a627bdeef81e3..b15de1c0ca9d7 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -731,16 +731,26 @@ pub fn ensure_sufficient_stack(f: impl FnOnce() -> R) -> R { } /// Context that provides information local to a place under investigation. -#[derive(derivative::Derivative)] -#[derivative(Debug(bound = ""), Clone(bound = ""), Copy(bound = ""))] pub(crate) struct PlaceCtxt<'a, Cx: TypeCx> { - #[derivative(Debug = "ignore")] pub(crate) mcx: MatchCtxt<'a, Cx>, /// Type of the place under investigation. - #[derivative(Clone(clone_with = "Clone::clone"))] // See rust-derivative#90 pub(crate) ty: &'a Cx::Ty, } +impl<'a, Cx: TypeCx> Clone for PlaceCtxt<'a, Cx> { + fn clone(&self) -> Self { + Self { mcx: self.mcx, ty: self.ty } + } +} + +impl<'a, Cx: TypeCx> Copy for PlaceCtxt<'a, Cx> {} + +impl<'a, Cx: TypeCx> fmt::Debug for PlaceCtxt<'a, Cx> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("PlaceCtxt").field("ty", self.ty).finish() + } +} + impl<'a, Cx: TypeCx> PlaceCtxt<'a, Cx> { /// A `PlaceCtxt` when code other than `is_useful` needs one. #[cfg_attr(not(feature = "rustc"), allow(dead_code))] @@ -813,8 +823,6 @@ impl fmt::Display for ValidityConstraint { // The three lifetimes are: // - 'p coming from the input // - Cx global compilation context -#[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""))] struct PatStack<'p, Cx: TypeCx> { // Rows of len 1 are very common, which is why `SmallVec[_; 2]` works well. pats: SmallVec<[PatOrWild<'p, Cx>; 2]>, @@ -824,6 +832,12 @@ struct PatStack<'p, Cx: TypeCx> { relevant: bool, } +impl<'p, Cx: TypeCx> Clone for PatStack<'p, Cx> { + fn clone(&self) -> Self { + Self { pats: self.pats.clone(), relevant: self.relevant } + } +} + impl<'p, Cx: TypeCx> PatStack<'p, Cx> { fn from_pattern(pat: &'p DeconstructedPat<'p, Cx>) -> Self { PatStack { pats: smallvec![PatOrWild::Pat(pat)], relevant: true } @@ -1184,10 +1198,20 @@ impl<'p, Cx: TypeCx> fmt::Debug for Matrix<'p, Cx> { /// The final `Pair(Some(_), true)` is then the resulting witness. /// /// See the top of the file for more detailed explanations and examples. -#[derive(derivative::Derivative)] -#[derivative(Debug(bound = ""), Clone(bound = ""))] struct WitnessStack(Vec>); +impl Clone for WitnessStack { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl fmt::Debug for WitnessStack { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_tuple("WitnessStack").field(&self.0).finish() + } +} + impl WitnessStack { /// Asserts that the witness contains a single pattern, and returns it. fn single_pattern(self) -> WitnessPat { @@ -1232,18 +1256,28 @@ impl WitnessStack { /// /// Just as the `Matrix` starts with a single column, by the end of the algorithm, this has a single /// column, which contains the patterns that are missing for the match to be exhaustive. -#[derive(derivative::Derivative)] -#[derivative(Debug(bound = ""), Clone(bound = ""))] struct WitnessMatrix(Vec>); +impl Clone for WitnessMatrix { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl fmt::Debug for WitnessMatrix { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_tuple("WitnessMatrix").field(&self.0).finish() + } +} + impl WitnessMatrix { /// New matrix with no witnesses. fn empty() -> Self { - WitnessMatrix(vec![]) + WitnessMatrix(Vec::new()) } /// New matrix with one `()` witness, i.e. with no columns. fn unit_witness() -> Self { - WitnessMatrix(vec![WitnessStack(vec![])]) + WitnessMatrix(vec![WitnessStack(Vec::new())]) } /// Whether this has any witnesses. From cda898b0d9a34e4a3615e879fcd4fb2da3fcead5 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:55:15 +0100 Subject: [PATCH 18/20] Remove unnecessary unit returns in query declarations For consistency with normal functions. --- compiler/rustc_middle/src/query/mod.rs | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 1122f571fff8a..b383a6f5e52c8 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -109,7 +109,7 @@ pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue // as they will raise an fatal error on query cycles instead. rustc_queries! { /// This exists purely for testing the interactions between span_delayed_bug and incremental. - query trigger_span_delayed_bug(key: DefId) -> () { + query trigger_span_delayed_bug(key: DefId) { desc { "triggering a span delayed bug for testing incremental" } } @@ -119,7 +119,7 @@ rustc_queries! { desc { "compute registered tools for crate" } } - query early_lint_checks(_: ()) -> () { + query early_lint_checks(_: ()) { desc { "perform lints prior to macro expansion" } } @@ -299,7 +299,7 @@ rustc_queries! { /// name. This is useful for cases were not all linting code from rustc /// was called. With the default `None` all registered lints will also /// be checked for expectation fulfillment. - query check_expectations(key: Option) -> () { + query check_expectations(key: Option) { eval_always desc { "checking lint expectations (RFC 2383)" } } @@ -906,39 +906,39 @@ rustc_queries! { } /// Performs lint checking for the module. - query lint_mod(key: LocalModDefId) -> () { + query lint_mod(key: LocalModDefId) { desc { |tcx| "linting {}", describe_as_module(key, tcx) } } - query check_unused_traits(_: ()) -> () { + query check_unused_traits(_: ()) { desc { "checking unused trait imports in crate" } } /// Checks the attributes in the module. - query check_mod_attrs(key: LocalModDefId) -> () { + query check_mod_attrs(key: LocalModDefId) { desc { |tcx| "checking attributes in {}", describe_as_module(key, tcx) } } /// Checks for uses of unstable APIs in the module. - query check_mod_unstable_api_usage(key: LocalModDefId) -> () { + query check_mod_unstable_api_usage(key: LocalModDefId) { desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) } } /// Checks the const bodies in the module for illegal operations (e.g. `if` or `loop`). - query check_mod_const_bodies(key: LocalModDefId) -> () { + query check_mod_const_bodies(key: LocalModDefId) { desc { |tcx| "checking consts in {}", describe_as_module(key, tcx) } } /// Checks the loops in the module. - query check_mod_loops(key: LocalModDefId) -> () { + query check_mod_loops(key: LocalModDefId) { desc { |tcx| "checking loops in {}", describe_as_module(key, tcx) } } - query check_mod_naked_functions(key: LocalModDefId) -> () { + query check_mod_naked_functions(key: LocalModDefId) { desc { |tcx| "checking naked functions in {}", describe_as_module(key, tcx) } } - query check_mod_privacy(key: LocalModDefId) -> () { + query check_mod_privacy(key: LocalModDefId) { desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) } } @@ -958,7 +958,7 @@ rustc_queries! { desc { "finding live symbols in crate" } } - query check_mod_deathness(key: LocalModDefId) -> () { + query check_mod_deathness(key: LocalModDefId) { desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) } } @@ -972,7 +972,7 @@ rustc_queries! { ensure_forwards_result_if_red } - query collect_mod_item_types(key: LocalModDefId) -> () { + query collect_mod_item_types(key: LocalModDefId) { desc { |tcx| "collecting item types in {}", describe_as_module(key, tcx) } } @@ -1121,7 +1121,7 @@ rustc_queries! { eval_always desc { "checking effective visibilities" } } - query check_private_in_public(_: ()) -> () { + query check_private_in_public(_: ()) { eval_always desc { "checking for private elements in public interfaces" } } From b867c7c707be0070beac663a03eb6a797f076f68 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Sat, 27 Jan 2024 08:47:14 -0800 Subject: [PATCH 19/20] Update primitive_docs.rs --- library/core/src/primitive_docs.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index fca2d3979ab47..e9c30ce9a23f5 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1392,10 +1392,8 @@ mod prim_usize {} /// /// # Safety /// -/// For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`, unsafe code may assume that -/// the following properties hold. Rust programmers must assume that, unless explicitly stated -/// otherwise, any Rust code they did not author themselves may rely on these properties, and that -/// violating them may cause that code to exhibit undefined behavior. +/// For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`, when such values cross an API +/// boundary, the following invariants must generally be upheld: /// /// * `t` is aligned to `align_of_val(t)` /// * `t` is dereferenceable for `size_of_val(t)` many bytes @@ -1403,9 +1401,16 @@ mod prim_usize {} /// If `t` points at address `a`, being "dereferenceable" for N bytes means that the memory range /// `[a, a + N)` is all contained within a single [allocated object]. /// -/// Note that the precise validity invariants for reference types are a work in progress. In the -/// future, new guarantees may be added. However, the guarantees documented in this section will -/// never be removed. +/// For instance, this means that unsafe code in a safe function may assume these invariants are +/// ensured of arguments passed by the caller, and it may assume that these invariants are ensured +/// of return values from any safe functions it calls. In most cases, the inverse is also true: +/// unsafe code must not violate these invariants when passing arguments to safe functions or +/// returning values from safe functions; such violations may result in undefined behavior. Where +/// exceptions to this latter requirement exist, they will be called out explicitly in documentation. +/// +/// It is not decided yet whether unsafe code may violate these invariants temporarily on internal +/// data. As a consequence, unsafe code which violates these invariants temporarily on internal data +/// may become unsound in future versions of Rust depending on how this question is decided. /// /// [allocated object]: ptr#allocated-object #[stable(feature = "rust1", since = "1.0.0")] From 5d8c1780fae725ce02a1c4619809347e55af67eb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 27 Jan 2024 00:50:31 +0000 Subject: [PATCH 20/20] Make the coroutine def id of an async closure the child of the closure def id --- compiler/rustc_resolve/src/def_collector.rs | 18 ++++++++++++------ .../ui/async-await/async-closures/def-path.rs | 14 ++++++++++++++ .../async-await/async-closures/def-path.stderr | 17 +++++++++++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 tests/ui/async-await/async-closures/def-path.rs create mode 100644 tests/ui/async-await/async-closures/def-path.stderr diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index b77102c085c59..42ace9bb22fa9 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -289,12 +289,18 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { // we must create two defs. let closure_def = self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span); match closure.coroutine_kind { - Some(coroutine_kind) => self.create_def( - coroutine_kind.closure_id(), - kw::Empty, - DefKind::Closure, - expr.span, - ), + Some(coroutine_kind) => { + self.with_parent(closure_def, |this| { + let coroutine_def = this.create_def( + coroutine_kind.closure_id(), + kw::Empty, + DefKind::Closure, + expr.span, + ); + this.with_parent(coroutine_def, |this| visit::walk_expr(this, expr)); + }); + return; + } None => closure_def, } } diff --git a/tests/ui/async-await/async-closures/def-path.rs b/tests/ui/async-await/async-closures/def-path.rs new file mode 100644 index 0000000000000..2883a1715b0ac --- /dev/null +++ b/tests/ui/async-await/async-closures/def-path.rs @@ -0,0 +1,14 @@ +// compile-flags: -Zverbose-internals +// edition:2021 + +#![feature(async_closure)] + +fn main() { + let x = async || {}; + //~^ NOTE the expected `async` closure body + let () = x(); + //~^ ERROR mismatched types + //~| NOTE this expression has type `{static main::{closure#0}::{closure#0} upvar_tys= + //~| NOTE expected `async` closure body, found `()` + //~| NOTE expected `async` closure body `{static main::{closure#0}::{closure#0} +} diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr new file mode 100644 index 0000000000000..4b37e50aac459 --- /dev/null +++ b/tests/ui/async-await/async-closures/def-path.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/def-path.rs:9:9 + | +LL | let x = async || {}; + | -- the expected `async` closure body +LL | +LL | let () = x(); + | ^^ --- this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=?7t witness=?8t}` + | | + | expected `async` closure body, found `()` + | + = note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?7t witness=?8t}` + found unit type `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`.