From c4c8bda689b3cb4474ef0aaad4bbcfaeeef434c1 Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 29 May 2024 14:47:01 +0200 Subject: [PATCH 1/9] non_local_defs: indicate that the macro needs to change aaa --- compiler/rustc_lint/messages.ftl | 1 + compiler/rustc_lint/src/lints.rs | 8 ++++++++ compiler/rustc_lint/src/non_local_def.rs | 8 ++++++++ tests/ui/lint/non-local-defs/cargo-update.stderr | 1 + tests/ui/lint/non-local-defs/inside-macro_rules.stderr | 1 + 5 files changed, 19 insertions(+) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index d2b1f50d79cbc..28f75a8193b98 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -550,6 +550,7 @@ lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks sho .bounds = `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type .exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration .const_anon = use a const-anon item to suppress this lint + .macro_to_change = the {$macro_kind} `{$macro_to_change}` defines the non-local `impl`, and may need to be changed lint_non_local_definitions_impl_move_help = move the `impl` block outside of this {$body_kind_descr} {$depth -> diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index c365e68ba44dc..91a600e754f9d 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1355,6 +1355,7 @@ pub enum NonLocalDefinitionsDiag { has_trait: bool, self_ty_str: String, of_trait_str: Option, + macro_to_change: Option<(String, &'static str)>, }, MacroRules { depth: u32, @@ -1380,6 +1381,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { has_trait, self_ty_str, of_trait_str, + macro_to_change, } => { diag.primary_message(fluent::lint_non_local_definitions_impl); diag.arg("depth", depth); @@ -1390,6 +1392,12 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { diag.arg("of_trait_str", of_trait_str); } + if let Some((macro_to_change, macro_kind)) = macro_to_change { + diag.arg("macro_to_change", macro_to_change); + diag.arg("macro_kind", macro_kind); + diag.note(fluent::lint_macro_to_change); + } + if has_trait { diag.note(fluent::lint_bounds); diag.note(fluent::lint_with_trait); diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 42b03f47a5bc5..ac5ed9d21906f 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -258,6 +258,13 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { Some((cx.tcx.def_span(parent), may_move)) }; + let macro_to_change = + if let ExpnKind::Macro(kind, name) = item.span.ctxt().outer_expn_data().kind { + Some((name.to_string(), kind.descr())) + } else { + None + }; + cx.emit_span_lint( NON_LOCAL_DEFINITIONS, ms, @@ -274,6 +281,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { move_to, may_remove, has_trait: impl_.of_trait.is_some(), + macro_to_change, }, ) } diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr index 888fd2e61837f..c1f224edeba5e 100644 --- a/tests/ui/lint/non-local-defs/cargo-update.stderr +++ b/tests/ui/lint/non-local-defs/cargo-update.stderr @@ -8,6 +8,7 @@ LL | non_local_macro::non_local_impl!(LocalStruct); | `Debug` is not local | move the `impl` block outside of this constant `_IMPL_DEBUG` | + = note: the macro `non_local_macro::non_local_impl` defines the non-local `impl`, and may need to be changed = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: the macro `non_local_macro::non_local_impl` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro` diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr index b52301d1aa086..fa9ba2cb785d9 100644 --- a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr +++ b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr @@ -12,6 +12,7 @@ LL | impl MacroTrait for OutsideStruct {} LL | m!(); | ---- in this macro invocation | + = note: the macro `m` defines the non-local `impl`, and may need to be changed = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue From b5d486793647ef4df01259639cae2ee908bde659 Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 29 May 2024 17:01:43 +0200 Subject: [PATCH 2/9] non_local_defs: move cargo update suggestion upper --- compiler/rustc_lint/src/lints.rs | 6 +++--- tests/ui/lint/non-local-defs/cargo-update.stderr | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 91a600e754f9d..d45d71ff8fe6e 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1397,6 +1397,9 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { diag.arg("macro_kind", macro_kind); diag.note(fluent::lint_macro_to_change); } + if let Some(cargo_update) = cargo_update { + diag.subdiagnostic(&diag.dcx, cargo_update); + } if has_trait { diag.note(fluent::lint_bounds); @@ -1423,9 +1426,6 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { ); } - if let Some(cargo_update) = cargo_update { - diag.subdiagnostic(&diag.dcx, cargo_update); - } if let Some(const_anon) = const_anon { diag.note(fluent::lint_exception); if let Some(const_anon) = const_anon { diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr index c1f224edeba5e..afd37d03a231c 100644 --- a/tests/ui/lint/non-local-defs/cargo-update.stderr +++ b/tests/ui/lint/non-local-defs/cargo-update.stderr @@ -9,9 +9,9 @@ LL | non_local_macro::non_local_impl!(LocalStruct); | move the `impl` block outside of this constant `_IMPL_DEBUG` | = note: the macro `non_local_macro::non_local_impl` defines the non-local `impl`, and may need to be changed + = note: the macro `non_local_macro::non_local_impl` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro` = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: the macro `non_local_macro::non_local_impl` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro` = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue = note: `#[warn(non_local_definitions)]` on by default From de12eb94d5b8cc2ef150f105103a29bed8f04a10 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 9 Jun 2024 12:35:27 +0000 Subject: [PATCH 3/9] Several fixes to the redox target specs * Allow crt-static for dylibs * Pass -lgcc to the linker --- compiler/rustc_target/src/spec/base/redox.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/base/redox.rs b/compiler/rustc_target/src/spec/base/redox.rs index 468fe478549b2..9070791e9dfc4 100644 --- a/compiler/rustc_target/src/spec/base/redox.rs +++ b/compiler/rustc_target/src/spec/base/redox.rs @@ -1,4 +1,4 @@ -use crate::spec::{cvs, RelroLevel, TargetOptions}; +use crate::spec::{cvs, Cc, LinkerFlavor, Lld, RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { TargetOptions { @@ -12,6 +12,8 @@ pub fn opts() -> TargetOptions { has_thread_local: true, crt_static_default: true, crt_static_respected: true, + crt_static_allows_dylibs: true, + late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-lgcc"]), ..Default::default() } } From f6669e8a095a9701879fd57f859bfef04338dfb1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 9 Jun 2024 12:38:06 +0000 Subject: [PATCH 4/9] Add i686-unknown-redox target Co-Authored-By: Jeremy Soller --- compiler/rustc_target/src/spec/mod.rs | 1 + .../src/spec/targets/i686_unknown_redox.rs | 27 +++++++++++++++++++ src/bootstrap/src/core/sanity.rs | 1 + src/doc/rustc/src/platform-support.md | 1 + src/tools/build-manifest/src/main.rs | 1 + tests/assembly/targets/targets-elf.rs | 3 +++ 6 files changed, 34 insertions(+) create mode 100644 compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index fe07d116726b6..cbd8dbfd30fdd 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1647,6 +1647,7 @@ supported_targets! { ("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc), ("aarch64-unknown-redox", aarch64_unknown_redox), + ("i686-unknown-redox", i686_unknown_redox), ("x86_64-unknown-redox", x86_64_unknown_redox), ("i386-apple-ios", i386_apple_ios), diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs new file mode 100644 index 0000000000000..83252fadb78ea --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs @@ -0,0 +1,27 @@ +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; + +pub fn target() -> Target { + let mut base = base::redox::opts(); + base.cpu = "pentiumpro".into(); + base.plt_by_default = false; + base.max_atomic_width = Some(64); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; + + Target { + llvm_target: "i686-unknown-redox".into(), + metadata: crate::spec::TargetMetadata { + description: None, + tier: None, + host_tools: None, + std: None, + }, + pointer_width: 32, + data_layout: + "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128" + .into(), + arch: "x86".into(), + options: base, + } +} diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index e3556cb16b053..6370406b17fdd 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -40,6 +40,7 @@ pub struct Finder { #[cfg(not(feature = "bootstrap-self-test"))] const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined + "i686-unknown-redox", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 633c26a4f56cd..bdb094d765f62 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -300,6 +300,7 @@ target | std | host | notes [`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd [^x86_32-floats-return-ABI] [`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 with SSE2 [^x86_32-floats-return-ABI] [`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD [^x86_32-floats-return-ABI] +`i686-unknown-redox` | ? | | i686 Redox OS `i686-uwp-windows-gnu` | ? | | [^x86_32-floats-return-ABI] `i686-uwp-windows-msvc` | ? | | [^x86_32-floats-return-ABI] [`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index bed76263b4516..65ff30b4c2efb 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -102,6 +102,7 @@ static TARGETS: &[&str] = &[ "i686-unknown-freebsd", "i686-unknown-linux-gnu", "i686-unknown-linux-musl", + "i686-unknown-redox", "i686-unknown-uefi", "loongarch64-unknown-linux-gnu", "loongarch64-unknown-none", diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index 0db2a35800269..0b2055b5f45b8 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -228,6 +228,9 @@ //@ revisions: i686_unknown_openbsd //@ [i686_unknown_openbsd] compile-flags: --target i686-unknown-openbsd //@ [i686_unknown_openbsd] needs-llvm-components: x86 +//@ revisions: i686_unknown_redox +//@ [i686_unknown_redox] compile-flags: --target i686-unknown-redox +//@ [i686_unknown_redox] needs-llvm-components: x86 //@ revisions: i686_wrs_vxworks //@ [i686_wrs_vxworks] compile-flags: --target i686-wrs-vxworks //@ [i686_wrs_vxworks] needs-llvm-components: x86 From db45105694cc5a63d1c1b39ebb725a024cea2d13 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 11 Feb 2023 18:34:41 -0700 Subject: [PATCH 5/9] Use Linux file locking on Redox --- compiler/rustc_data_structures/src/flock.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_data_structures/src/flock.rs b/compiler/rustc_data_structures/src/flock.rs index 008565e4c7b97..e03962a54ecab 100644 --- a/compiler/rustc_data_structures/src/flock.rs +++ b/compiler/rustc_data_structures/src/flock.rs @@ -9,6 +9,10 @@ cfg_match! { mod linux; use linux as imp; } + cfg(target_os = "redox") => { + mod linux; + use linux as imp; + } cfg(unix) => { mod unix; use unix as imp; From f636d3f1f7c82d8b537b7f7534bdb3397a0aeb7d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 9 Jun 2024 15:50:58 +0000 Subject: [PATCH 6/9] Add dedicated platform support page for Redox OS --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 6 +-- src/doc/rustc/src/platform-support/redox.md | 53 +++++++++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 src/doc/rustc/src/platform-support/redox.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 201ace5ce3a7b..e76ebb8f8aa8c 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -71,6 +71,7 @@ - [*-unknown-hermit](platform-support/hermit.md) - [\*-unknown-netbsd\*](platform-support/netbsd.md) - [*-unknown-openbsd](platform-support/openbsd.md) + - [*-unknown-redox](platform-support/redox.md) - [\*-unknown-uefi](platform-support/unknown-uefi.md) - [wasm32-wasip1](platform-support/wasm32-wasip1.md) - [wasm32-wasip1-threads](platform-support/wasm32-wasip1-threads.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index bdb094d765f62..ca20d01c6cb96 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -202,7 +202,7 @@ target | std | notes `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27) [`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | x86_64 OpenHarmony [`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat -`x86_64-unknown-redox` | ✓ | Redox OS +[`x86_64-unknown-redox`](platform-support/redox.md) | ✓ | Redox OS [`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 64-bit UEFI [^x86_32-floats-x87]: Floating-point support on `i586` targets is non-compliant: the `x87` registers and instructions used for these targets do not provide IEEE-754-compliant behavior, in particular when it comes to rounding and NaN payload bits. See [issue #114479][x86-32-float-issue]. @@ -258,7 +258,7 @@ target | std | host | notes `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) [`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD -`aarch64-unknown-redox` | ? | | ARM64 Redox OS +[`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS `aarch64-uwp-windows-msvc` | ? | | `aarch64-wrs-vxworks` | ? | | `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) @@ -300,7 +300,7 @@ target | std | host | notes [`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd [^x86_32-floats-return-ABI] [`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 with SSE2 [^x86_32-floats-return-ABI] [`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD [^x86_32-floats-return-ABI] -`i686-unknown-redox` | ? | | i686 Redox OS +[`i686-unknown-redox`](platform-support/redox.md) | ✓ | | i686 Redox OS `i686-uwp-windows-gnu` | ? | | [^x86_32-floats-return-ABI] `i686-uwp-windows-msvc` | ? | | [^x86_32-floats-return-ABI] [`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] diff --git a/src/doc/rustc/src/platform-support/redox.md b/src/doc/rustc/src/platform-support/redox.md new file mode 100644 index 0000000000000..1b3321956ef7b --- /dev/null +++ b/src/doc/rustc/src/platform-support/redox.md @@ -0,0 +1,53 @@ +# `*-unknown-redox` + +**Tier: 2/3** + +Targets for the [Redox OS](https://redox-os.org/) operating +system. + +Target triplets available so far: + +- `x86_64-unknown-redox` (tier 2) +- `aarch64-unknown-redox` (tier 3) +- `i686-unknown-redox` (tier 3) + +## Target maintainers + +- Jeremy Soller ([@jackpot51](https://github.com/jackpot51)) + +## Requirements + +These targets are natively compiled and can be cross-compiled. Std is fully supported. + +The targets are only expected to work with the latest version of Redox OS as the ABI is not yet stable. + +`extern "C"` uses the official calling convention of the respective architectures. + +Redox OS binaries use ELF as file format. + +## Building the target + +You can build Rust with support for the targets by adding it to the `target` list in `config.toml`. In addition a copy of [relibc] needs to be present in the linker search path. + +```toml +[build] +build-stage = 1 +target = [ + "", + "x86_64-unknown-redox", + "aarch64-unknown-redox", + "i686-unknown-redox", +] +``` + +[relibc]: https://gitlab.redox-os.org/redox-os/relibc + +## Building Rust programs and testing + +Rust does not yet ship pre-compiled artifacts for Redox OS except for x86_64-unknown-redox. + +The easiest way to build and test programs for Redox OS is using [redoxer](https://gitlab.redox-os.org/redox-os/redoxer) which sets up the required compiler toolchain for building as well as runs programs inside a Redox OS VM using QEMU. + +## Cross-compilation toolchains and C code + +The target supports C code. Pre-compiled C toolchains can be found at . From 27ecb71635f0a168d8827fb4efc33b122c291e9c Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Tue, 11 Jun 2024 15:16:47 -0700 Subject: [PATCH 7/9] `UniqueRc`: support allocators and `T: ?Sized`. Added the following (all unstable): * Defaulted type pararameter `A: Allocator`. * `UniqueRc::new_in()`. * `T: ?Sized` where possible. * `impl CoerceUnsized for UniqueRc`. * Drive-by doc polish: links and periods at the end of sentences. These changes are motivated by supporting the implementation of unsized `Rc::make_mut()` (PR #116113), but are also intended to be obvious generalizations of `UniqueRc` to support the things `Rc` does. --- library/alloc/src/rc.rs | 95 ++++++++++++++++++++++++----------- library/alloc/src/rc/tests.rs | 26 ++++++++++ 2 files changed, 91 insertions(+), 30 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index f3a4803e0d4a5..336fd52d92fb3 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -3516,7 +3516,7 @@ fn data_offset_align(align: usize) -> usize { layout.size() + layout.padding_needed_for(align) } -/// A uniquely owned `Rc` +/// A uniquely owned [`Rc`]. /// /// This represents an `Rc` that is known to be uniquely owned -- that is, have exactly one strong /// reference. Multiple weak pointers can be created, but attempts to upgrade those to strong @@ -3554,13 +3554,24 @@ fn data_offset_align(align: usize) -> usize { /// including fallible or async constructors. #[unstable(feature = "unique_rc_arc", issue = "112566")] #[derive(Debug)] -pub struct UniqueRc { +pub struct UniqueRc< + T: ?Sized, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { ptr: NonNull>, phantom: PhantomData>, + alloc: A, } +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl, U: ?Sized, A: Allocator> CoerceUnsized> + for UniqueRc +{ +} + +// Depends on A = Global impl UniqueRc { - /// Creates a new `UniqueRc` + /// Creates a new `UniqueRc`. /// /// Weak references to this `UniqueRc` can be created with [`UniqueRc::downgrade`]. Upgrading /// these weak references will fail before the `UniqueRc` has been converted into an [`Rc`]. @@ -3569,34 +3580,36 @@ impl UniqueRc { #[cfg(not(no_global_oom_handling))] #[unstable(feature = "unique_rc_arc", issue = "112566")] pub fn new(value: T) -> Self { - Self { - ptr: Box::leak(Box::new(RcBox { + Self::new_in(value, Global) + } +} + +impl UniqueRc { + /// Creates a new `UniqueRc` in the provided allocator. + /// + /// Weak references to this `UniqueRc` can be created with [`UniqueRc::downgrade`]. Upgrading + /// these weak references will fail before the `UniqueRc` has been converted into an [`Rc`]. + /// After converting the `UniqueRc` into an [`Rc`], any weak references created beforehand will + /// point to the new [`Rc`]. + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "unique_rc_arc", issue = "112566")] + pub fn new_in(value: T, alloc: A) -> Self { + let (ptr, alloc) = Box::into_unique(Box::new_in( + RcBox { strong: Cell::new(0), // keep one weak reference so if all the weak pointers that are created are dropped // the UniqueRc still stays valid. weak: Cell::new(1), value, - })) - .into(), - phantom: PhantomData, - } - } - - /// Creates a new weak reference to the `UniqueRc` - /// - /// Attempting to upgrade this weak reference will fail before the `UniqueRc` has been converted - /// to a [`Rc`] using [`UniqueRc::into_rc`]. - #[unstable(feature = "unique_rc_arc", issue = "112566")] - pub fn downgrade(this: &Self) -> Weak { - // SAFETY: This pointer was allocated at creation time and we guarantee that we only have - // one strong reference before converting to a regular Rc. - unsafe { - this.ptr.as_ref().inc_weak(); - } - Weak { ptr: this.ptr, alloc: Global } + }, + alloc, + )); + Self { ptr: ptr.into(), phantom: PhantomData, alloc } } +} - /// Converts the `UniqueRc` into a regular [`Rc`] +impl UniqueRc { + /// Converts the `UniqueRc` into a regular [`Rc`]. /// /// This consumes the `UniqueRc` and returns a regular [`Rc`] that contains the `value` that /// is passed to `into_rc`. @@ -3604,19 +3617,41 @@ impl UniqueRc { /// Any weak references created before this method is called can now be upgraded to strong /// references. #[unstable(feature = "unique_rc_arc", issue = "112566")] - pub fn into_rc(this: Self) -> Rc { + pub fn into_rc(this: Self) -> Rc { let mut this = ManuallyDrop::new(this); + + // Move the allocator out. + // SAFETY: `this.alloc` will not be accessed again, nor dropped because it is in + // a `ManuallyDrop`. + let alloc: A = unsafe { ptr::read(&this.alloc) }; + // SAFETY: This pointer was allocated at creation time so we know it is valid. unsafe { // Convert our weak reference into a strong reference this.ptr.as_mut().strong.set(1); - Rc::from_inner(this.ptr) + Rc::from_inner_in(this.ptr, alloc) + } + } +} + +impl UniqueRc { + /// Creates a new weak reference to the `UniqueRc`. + /// + /// Attempting to upgrade this weak reference will fail before the `UniqueRc` has been converted + /// to a [`Rc`] using [`UniqueRc::into_rc`]. + #[unstable(feature = "unique_rc_arc", issue = "112566")] + pub fn downgrade(this: &Self) -> Weak { + // SAFETY: This pointer was allocated at creation time and we guarantee that we only have + // one strong reference before converting to a regular Rc. + unsafe { + this.ptr.as_ref().inc_weak(); } + Weak { ptr: this.ptr, alloc: this.alloc.clone() } } } #[unstable(feature = "unique_rc_arc", issue = "112566")] -impl Deref for UniqueRc { +impl Deref for UniqueRc { type Target = T; fn deref(&self) -> &T { @@ -3626,7 +3661,7 @@ impl Deref for UniqueRc { } #[unstable(feature = "unique_rc_arc", issue = "112566")] -impl DerefMut for UniqueRc { +impl DerefMut for UniqueRc { fn deref_mut(&mut self) -> &mut T { // SAFETY: This pointer was allocated at creation time so we know it is valid. We know we // have unique ownership and therefore it's safe to make a mutable reference because @@ -3636,7 +3671,7 @@ impl DerefMut for UniqueRc { } #[unstable(feature = "unique_rc_arc", issue = "112566")] -unsafe impl<#[may_dangle] T> Drop for UniqueRc { +unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueRc { fn drop(&mut self) { unsafe { // destroy the contained object @@ -3646,7 +3681,7 @@ unsafe impl<#[may_dangle] T> Drop for UniqueRc { self.ptr.as_ref().dec_weak(); if self.ptr.as_ref().weak() == 0 { - Global.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr())); + self.alloc.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr())); } } } diff --git a/library/alloc/src/rc/tests.rs b/library/alloc/src/rc/tests.rs index c8a40603d9db2..0f09be7721fa9 100644 --- a/library/alloc/src/rc/tests.rs +++ b/library/alloc/src/rc/tests.rs @@ -606,6 +606,23 @@ fn test_unique_rc_drops_contents() { assert!(dropped); } +/// Exercise the non-default allocator usage. +#[test] +fn test_unique_rc_with_alloc_drops_contents() { + let mut dropped = false; + struct DropMe<'a>(&'a mut bool); + impl Drop for DropMe<'_> { + fn drop(&mut self) { + *self.0 = true; + } + } + { + let rc = UniqueRc::new_in(DropMe(&mut dropped), std::alloc::System); + drop(rc); + } + assert!(dropped); +} + #[test] fn test_unique_rc_weak_clone_holding_ref() { let mut v = UniqueRc::new(0u8); @@ -614,3 +631,12 @@ fn test_unique_rc_weak_clone_holding_ref() { let _ = w.clone(); // touch weak count *r = 123; } + +#[test] +fn test_unique_rc_unsizing_coercion() { + let mut rc: UniqueRc<[u8]> = UniqueRc::new([0u8; 3]); + assert_eq!(rc.len(), 3); + rc[0] = 123; + let rc: Rc<[u8]> = UniqueRc::into_rc(rc); + assert_eq!(*rc, [123, 0, 0]); +} From 6d2493bf5d6c97bc52aa109944a7f27ee456192e Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 12 Jun 2024 12:48:35 -0700 Subject: [PATCH 8/9] ci: Update centos:7 to use vault repos CentOS 7 is going EOL on June 30, after which its package repos will no longer exist on the regular mirrors. We'll still be able to access packages from the vault server though, and can start doing so now. This affects `dist-i686-linux` and `dist-x86_64-linux`. I also removed `epel-release` because we were only using that for its `cmake3`, but we've been building our own version for a while. --- src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile | 6 +++++- src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile index 1704bef1e4ed0..414bcc52484c9 100644 --- a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile @@ -6,8 +6,12 @@ FROM centos:7 WORKDIR /build +# CentOS 7 EOL is June 30, 2024, but the repos remain in the vault. +RUN sed -i /etc/yum.repos.d/*.repo -e 's!^mirrorlist!#mirrorlist!' \ + -e 's!^#baseurl=http://mirror.centos.org/!baseurl=https://vault.centos.org/!' +RUN sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf + RUN yum upgrade -y && \ - yum install -y epel-release && \ yum install -y \ automake \ bzip2 \ diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index 4e1aae9822135..4aa1a3ccc2a5d 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -6,8 +6,12 @@ FROM centos:7 WORKDIR /build +# CentOS 7 EOL is June 30, 2024, but the repos remain in the vault. +RUN sed -i /etc/yum.repos.d/*.repo -e 's!^mirrorlist!#mirrorlist!' \ + -e 's!^#baseurl=http://mirror.centos.org/!baseurl=https://vault.centos.org/!' +RUN sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf + RUN yum upgrade -y && \ - yum install -y epel-release && \ yum install -y \ automake \ bzip2 \ From 58e3ac0877bc5daf53e42383fc51b8c8e2d2a7bb Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 13 Jun 2024 15:06:34 +0300 Subject: [PATCH 9/9] extend the check for LLVM build We don't build LLVM when using the precompiled version from the CI builder. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/sanity.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index b5f17b9f54edc..da80f10b7dddd 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -137,19 +137,20 @@ pub fn check(build: &mut Build) { } // We need cmake, but only if we're actually building LLVM or sanitizers. - let building_llvm = build - .hosts - .iter() - .map(|host| { - build.config.llvm_enabled(*host) - && build - .config - .target_config - .get(host) - .map(|config| config.llvm_config.is_none()) - .unwrap_or(true) - }) - .any(|build_llvm_ourselves| build_llvm_ourselves); + let building_llvm = !build.config.llvm_from_ci + && build + .hosts + .iter() + .map(|host| { + build.config.llvm_enabled(*host) + && build + .config + .target_config + .get(host) + .map(|config| config.llvm_config.is_none()) + .unwrap_or(true) + }) + .any(|build_llvm_ourselves| build_llvm_ourselves); let need_cmake = building_llvm || build.config.any_sanitizers_to_build(); if need_cmake && cmd_finder.maybe_have("cmake").is_none() {