Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #126465

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions compiler/rustc_data_structures/src/flock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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 ->
Expand Down
14 changes: 11 additions & 3 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1362,6 +1362,7 @@ pub enum NonLocalDefinitionsDiag {
has_trait: bool,
self_ty_str: String,
of_trait_str: Option<String>,
macro_to_change: Option<(String, &'static str)>,
},
MacroRules {
depth: u32,
Expand All @@ -1387,6 +1388,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);
Expand All @@ -1397,6 +1399,15 @@ 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 let Some(cargo_update) = cargo_update {
diag.subdiagnostic(&diag.dcx, cargo_update);
}

if has_trait {
diag.note(fluent::lint_bounds);
diag.note(fluent::lint_with_trait);
Expand All @@ -1422,9 +1433,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 {
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_lint/src/non_local_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -274,6 +281,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
move_to,
may_remove,
has_trait: impl_.of_trait.is_some(),
macro_to_change,
},
)
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_target/src/spec/base/redox.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::spec::{cvs, RelroLevel, TargetOptions};
use crate::spec::{cvs, Cc, LinkerFlavor, Lld, RelroLevel, TargetOptions};

pub fn opts() -> TargetOptions {
TargetOptions {
Expand All @@ -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()
}
}
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
27 changes: 27 additions & 0 deletions compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs
Original file line number Diff line number Diff line change
@@ -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,
}
}
95 changes: 65 additions & 30 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<T> {
pub struct UniqueRc<
T: ?Sized,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> {
ptr: NonNull<RcBox<T>>,
phantom: PhantomData<RcBox<T>>,
alloc: A,
}

#[unstable(feature = "unique_rc_arc", issue = "112566")]
impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<UniqueRc<U, A>>
for UniqueRc<T, A>
{
}

// Depends on A = Global
impl<T> UniqueRc<T> {
/// 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`].
Expand All @@ -3569,54 +3580,78 @@ impl<T> UniqueRc<T> {
#[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<T, A: Allocator> UniqueRc<T, A> {
/// 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<T> {
// 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<T: ?Sized, A: Allocator> UniqueRc<T, A> {
/// 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`.
///
/// 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<T> {
pub fn into_rc(this: Self) -> Rc<T, A> {
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<T: ?Sized, A: Allocator + Clone> UniqueRc<T, A> {
/// 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<T, A> {
// 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<T> Deref for UniqueRc<T> {
impl<T: ?Sized, A: Allocator> Deref for UniqueRc<T, A> {
type Target = T;

fn deref(&self) -> &T {
Expand All @@ -3626,7 +3661,7 @@ impl<T> Deref for UniqueRc<T> {
}

#[unstable(feature = "unique_rc_arc", issue = "112566")]
impl<T> DerefMut for UniqueRc<T> {
impl<T: ?Sized, A: Allocator> DerefMut for UniqueRc<T, A> {
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
Expand All @@ -3636,7 +3671,7 @@ impl<T> DerefMut for UniqueRc<T> {
}

#[unstable(feature = "unique_rc_arc", issue = "112566")]
unsafe impl<#[may_dangle] T> Drop for UniqueRc<T> {
unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueRc<T, A> {
fn drop(&mut self) {
unsafe {
// destroy the contained object
Expand All @@ -3646,7 +3681,7 @@ unsafe impl<#[may_dangle] T> Drop for UniqueRc<T> {
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()));
}
}
}
Expand Down
26 changes: 26 additions & 0 deletions library/alloc/src/rc/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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]);
}
28 changes: 15 additions & 13 deletions src/bootstrap/src/core/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -137,19 +138,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() {
Expand Down
6 changes: 5 additions & 1 deletion src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
Loading
Loading