From fb619ec208b898bad1505c97ee79408b2c60926b Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Sat, 11 May 2024 08:24:26 +0530 Subject: [PATCH 1/5] FIx ICE while casting a type with error --- compiler/rustc_hir_typeck/src/cast.rs | 5 +- .../cast/ice-cast-type-with-error-124848.rs | 18 ++++++ .../ice-cast-type-with-error-124848.stderr | 63 +++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 tests/ui/cast/ice-cast-type-with-error-124848.rs create mode 100644 tests/ui/cast/ice-cast-type-with-error-124848.stderr diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 92f74281ab982..cecb9a61098a8 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -140,7 +140,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Never | ty::Dynamic(_, _, ty::DynStar) | ty::Error(_) => { - self.dcx().span_bug(span, format!("`{t:?}` should be sized but is not?")); + let guar = self + .dcx() + .span_delayed_bug(span, format!("`{t:?}` should be sized but is not?")); + return Err(guar); } }) } diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.rs b/tests/ui/cast/ice-cast-type-with-error-124848.rs new file mode 100644 index 0000000000000..9b3732b02db43 --- /dev/null +++ b/tests/ui/cast/ice-cast-type-with-error-124848.rs @@ -0,0 +1,18 @@ +// Regression test for ICE #124848 +// Tests that there is no ICE when a cast +// involves a type with error + +use std::cell::Cell; + +struct MyType<'a>(Cell>>, Pin); +//~^ ERROR use of undeclared lifetime name `'unpinned` +//~| ERROR cannot find type `Pin` in this scope + +fn main() { + let mut unpinned = MyType(Cell::new(None)); + //~^ ERROR his struct takes 2 arguments but 1 argument was supplied + let bad_addr = &unpinned as *const Cell>> as usize; + //~^ ERROR use of undeclared lifetime name `'a` + //~| ERROR use of undeclared lifetime name `'a` + //~| ERROR casting `&MyType<'_>` as `*const Cell>>` is invalid +} diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.stderr b/tests/ui/cast/ice-cast-type-with-error-124848.stderr new file mode 100644 index 0000000000000..2d86bf76d1102 --- /dev/null +++ b/tests/ui/cast/ice-cast-type-with-error-124848.stderr @@ -0,0 +1,63 @@ +error[E0261]: use of undeclared lifetime name `'unpinned` + --> $DIR/ice-cast-type-with-error-124848.rs:7:32 + | +LL | struct MyType<'a>(Cell>>, Pin); + | - ^^^^^^^^^ undeclared lifetime + | | + | help: consider introducing lifetime `'unpinned` here: `'unpinned,` + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/ice-cast-type-with-error-124848.rs:14:53 + | +LL | fn main() { + | - help: consider introducing lifetime `'a` here: `<'a>` +... +LL | let bad_addr = &unpinned as *const Cell>> as usize; + | ^^ undeclared lifetime + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/ice-cast-type-with-error-124848.rs:14:67 + | +LL | fn main() { + | - help: consider introducing lifetime `'a` here: `<'a>` +... +LL | let bad_addr = &unpinned as *const Cell>> as usize; + | ^^ undeclared lifetime + +error[E0412]: cannot find type `Pin` in this scope + --> $DIR/ice-cast-type-with-error-124848.rs:7:60 + | +LL | struct MyType<'a>(Cell>>, Pin); + | ^^^ not found in this scope + | +help: consider importing this struct + | +LL + use std::pin::Pin; + | + +error[E0061]: this struct takes 2 arguments but 1 argument was supplied + --> $DIR/ice-cast-type-with-error-124848.rs:12:24 + | +LL | let mut unpinned = MyType(Cell::new(None)); + | ^^^^^^----------------- an argument is missing + | +note: tuple struct defined here + --> $DIR/ice-cast-type-with-error-124848.rs:7:8 + | +LL | struct MyType<'a>(Cell>>, Pin); + | ^^^^^^ +help: provide the argument + | +LL | let mut unpinned = MyType(Cell::new(None), /* value */); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0606]: casting `&MyType<'_>` as `*const Cell>>` is invalid + --> $DIR/ice-cast-type-with-error-124848.rs:14:20 + | +LL | let bad_addr = &unpinned as *const Cell>> as usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0061, E0261, E0412, E0606. +For more information about an error, try `rustc --explain E0061`. From b3a78c1d094eb978ec876643c3c4d0e5349b1073 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Mon, 13 May 2024 13:34:33 +0200 Subject: [PATCH 2/5] Add test for dynamic dispatch + Pin::new soundness --- tests/ui/coercion/pin-dyn-dispatch-sound.rs | 19 +++++++++++++++++++ .../ui/coercion/pin-dyn-dispatch-sound.stderr | 9 +++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/ui/coercion/pin-dyn-dispatch-sound.rs create mode 100644 tests/ui/coercion/pin-dyn-dispatch-sound.stderr diff --git a/tests/ui/coercion/pin-dyn-dispatch-sound.rs b/tests/ui/coercion/pin-dyn-dispatch-sound.rs new file mode 100644 index 0000000000000..b9d43ebac8bf4 --- /dev/null +++ b/tests/ui/coercion/pin-dyn-dispatch-sound.rs @@ -0,0 +1,19 @@ +use std::marker::PhantomPinned; +use std::pin::Pin; + +trait MyUnpinTrait { + fn into_pinned_type(self: Pin<&mut Self>) -> Pin<&mut PhantomPinned>; +} +impl MyUnpinTrait for PhantomPinned { + fn into_pinned_type(self: Pin<&mut Self>) -> Pin<&mut PhantomPinned> { + self + } +} +impl Unpin for dyn MyUnpinTrait {} //~ ERROR E0321 + +// It would be unsound for this function to compile. +fn pin_it(not_yet_pinned: &mut PhantomPinned) -> Pin<&mut PhantomPinned> { + Pin::new(not_yet_pinned as &mut dyn MyUnpinTrait).into_pinned_type() +} + +fn main() {} diff --git a/tests/ui/coercion/pin-dyn-dispatch-sound.stderr b/tests/ui/coercion/pin-dyn-dispatch-sound.stderr new file mode 100644 index 0000000000000..45860bfcfc760 --- /dev/null +++ b/tests/ui/coercion/pin-dyn-dispatch-sound.stderr @@ -0,0 +1,9 @@ +error[E0321]: cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `(dyn MyUnpinTrait + 'static)` + --> $DIR/pin-dyn-dispatch-sound.rs:12:1 + | +LL | impl Unpin for dyn MyUnpinTrait {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0321`. From bce3598f55294342da7181cb4fdb3aa33121613e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 6 May 2024 11:10:42 +0200 Subject: [PATCH 3/5] Migrate `run-make/rustdoc-io-error` to `rmake.rs` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/rustdoc-io-error/Makefile | 20 ------------ tests/run-make/rustdoc-io-error/rmake.rs | 32 +++++++++++++++++++ 3 files changed, 32 insertions(+), 21 deletions(-) delete mode 100644 tests/run-make/rustdoc-io-error/Makefile create mode 100644 tests/run-make/rustdoc-io-error/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index e87950b36d9df..121bec92407c5 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -244,7 +244,6 @@ run-make/rlib-format-packed-bundled-libs-3/Makefile run-make/rlib-format-packed-bundled-libs/Makefile run-make/rmeta-preferred/Makefile run-make/rustc-macro-dep-files/Makefile -run-make/rustdoc-io-error/Makefile run-make/rustdoc-scrape-examples-invalid-expr/Makefile run-make/rustdoc-scrape-examples-macros/Makefile run-make/rustdoc-scrape-examples-multiple/Makefile diff --git a/tests/run-make/rustdoc-io-error/Makefile b/tests/run-make/rustdoc-io-error/Makefile deleted file mode 100644 index 27f5ecf94aba3..0000000000000 --- a/tests/run-make/rustdoc-io-error/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -include ../tools.mk - -# This test verifies that rustdoc doesn't ICE when it encounters an IO error -# while generating files. Ideally this would be a rustdoc-ui test, so we could -# verify the error message as well. - -# ignore-windows -# The test uses `chmod`. - -OUTPUT_DIR := "$(TMPDIR)/rustdoc-io-error" - -# This test operates by creating a temporary directory and modifying its -# permissions so that it is not writable. We have to take special care to set -# the permissions back to normal so that it's able to be deleted later. -all: - mkdir -p $(OUTPUT_DIR) - chmod u-w $(OUTPUT_DIR) - -$(shell $(RUSTDOC) -o $(OUTPUT_DIR) foo.rs) - chmod u+w $(OUTPUT_DIR) - exit $($(.SHELLSTATUS) -eq 1) diff --git a/tests/run-make/rustdoc-io-error/rmake.rs b/tests/run-make/rustdoc-io-error/rmake.rs new file mode 100644 index 0000000000000..b1d31395e3de8 --- /dev/null +++ b/tests/run-make/rustdoc-io-error/rmake.rs @@ -0,0 +1,32 @@ +// This test verifies that rustdoc doesn't ICE when it encounters an IO error +// while generating files. Ideally this would be a rustdoc-ui test, so we could +// verify the error message as well. +// +// It operates by creating a temporary directory and modifying its +// permissions so that it is not writable. We have to take special care to set +// the permissions back to normal so that it's able to be deleted later. + +use run_make_support::{rustdoc, tmp_dir}; +use std::fs; + +fn main() { + let out_dir = tmp_dir().join("rustdoc-io-error"); + let output = fs::create_dir(&out_dir).unwrap(); + let mut permissions = fs::metadata(&out_dir).unwrap().permissions(); + let original_permissions = permissions.clone(); + permissions.set_readonly(true); + fs::set_permissions(&out_dir, permissions.clone()).unwrap(); + + let output = rustdoc().input("foo.rs").output(&out_dir).command_output(); + + // Changing back permissions. + fs::set_permissions(&out_dir, original_permissions).unwrap(); + + // Checks that rustdoc failed with the error code 1. + #[cfg(unix)] + assert_eq!(output.status.code().unwrap(), 1); + assert!(!output.status.success()); + let stderr = String::from_utf8(output.stderr).unwrap(); + + assert!(stderr.contains("error: couldn't generate documentation: Permission denied")); +} From 293b5cb1caa32487d986c052c4d72cd1fde9f250 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Thu, 12 Oct 2023 15:17:18 -0700 Subject: [PATCH 4/5] [ptr] Document maximum allocation size --- library/core/src/ptr/mod.rs | 38 ++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 5039ff53d0313..0ff44478d3563 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -59,11 +59,39 @@ //! //! ## Allocated object //! -//! For several operations, such as [`offset`] or field projections (`expr.field`), the notion of an -//! "allocated object" becomes relevant. An allocated object is a contiguous region of memory. -//! Common examples of allocated objects include stack-allocated variables (each variable is a -//! separate allocated object), heap allocations (each allocation created by the global allocator is -//! a separate allocated object), and `static` variables. +//! An *allocated object* is a subset of program memory which is addressable +//! from Rust, and within which pointer arithmetic is possible. Examples of +//! allocated objects include heap allocations, stack-allocated variables, +//! statics, and consts. The safety preconditions of some Rust operations - +//! such as `offset` and field projections (`expr.field`) - are defined in +//! terms of the allocated objects on which they operate. +//! +//! An allocated object has a base address, a size, and a set of memory +//! addresses. It is possible for an allocated object to have zero size, but +//! such an allocated object will still have a base address. The base address +//! of an allocated object is not necessarily unique. While it is currently the +//! case that an allocated object always has a set of memory addresses which is +//! fully contiguous (i.e., has no "holes"), there is no guarantee that this +//! will not change in the future. +//! +//! For any allocated object with `base` address, `size`, and a set of +//! `addresses`, the following are guaranteed: +//! - For all addresses `a` in `addresses`, `a` is in the range `base .. (base + +//! size)` (note that this requires `a < base + size`, not `a <= base + size`) +//! - `base` is not equal to [`null()`] (i.e., the address with the numerical +//! value 0) +//! - `base + size <= usize::MAX` +//! - `size <= isize::MAX` +//! +//! As a consequence of these guarantees, given any address `a` within the set +//! of addresses of an allocated object: +//! - It is guaranteed that `a - base` does not overflow `isize` +//! - It is guaranteed that `a - base` is non-negative +//! - It is guaranteed that, given `o = a - base` (i.e., the offset of `a` within +//! the allocated object), `base + o` will not wrap around the address space (in +//! other words, will not overflow `usize`) +//! +//! [`null()`]: null //! //! # Strict Provenance //! From 58ee9192e08e8394da6a3bfa3c26eb315213b77a Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Mon, 13 May 2024 20:13:48 +0000 Subject: [PATCH 5/5] Migrate fuchsia docs from `pm` to `ffx` The `pm` tool has been deprecated, so this migrates the fuchsia documentation to the new `ffx` based tooling. --- src/doc/rustc/src/platform-support/fuchsia.md | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md index 9c2e05b57f5e8..3e1db692f50be 100644 --- a/src/doc/rustc/src/platform-support/fuchsia.md +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -387,7 +387,7 @@ meta/hello_fuchsia.cm=pkg/meta/hello_fuchsia.cm ``` *Note: Relative manifest paths are resolved starting from the working directory -of `pm`. Make sure to fill out `` with the path to the downloaded +of `ffx`. Make sure to fill out `` with the path to the downloaded SDK.* The `.manifest` file will be used to describe the contents of the package by @@ -459,12 +459,10 @@ hello_fuchsia/ Next, we'll build a package manifest as defined by our manifest: ```sh -${SDK_PATH}/tools/${ARCH}/pm \ - -api-level $(${SDK_PATH}/tools/${ARCH}/ffx version -v | grep "api-level" | head -1 | awk -F ' ' '{print $2}') \ - -o pkg/hello_fuchsia_manifest \ - -m pkg/hello_fuchsia.manifest \ - build \ - -output-package-manifest pkg/hello_fuchsia_package_manifest +${SDK_PATH}/tools/${ARCH}/ffx package build \ + --api-level $(${SDK_PATH}/tools/${ARCH}/ffx --machine json version | jq .tool_version.api_level) \ + --out pkg/hello_fuchsia_manifest \ + pkg/hello_fuchsia.manifest ``` This will produce `pkg/hello_fuchsia_manifest/` which is a package manifest we can @@ -498,8 +496,7 @@ to. We can set up our repository with: ```sh -${SDK_PATH}/tools/${ARCH}/pm newrepo \ - -repo pkg/repo +${SDK_PATH}/tools/${ARCH}/ffx repository create pkg/repo ``` **Current directory structure** @@ -523,17 +520,17 @@ hello_fuchsia/ We can publish our new package to that repository with: ```sh -${SDK_PATH}/tools/${ARCH}/pm publish \ - -repo pkg/repo \ - -lp -f <(echo "pkg/hello_fuchsia_package_manifest") +${SDK_PATH}/tools/${ARCH}/ffx repository publish \ + --package pkg/hello_fuchsia_package_manifest \ + pkg/repo ``` Then we can add the repository to `ffx`'s package server as `hello-fuchsia` using: ```sh ${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm \ - pkg/repo \ - -r hello-fuchsia + --repository hello-fuchsia \ + pkg/repo ``` ## Running a Fuchsia component on an emulator