Auto merge of #145949 - jhpratt:rollup-smzd7tr, r=jhpratt

Rollup of 5 pull requests

Successful merges:

 - rust-lang/rust#145382 (Add assembly test for `-Zreg-struct-return` option)
 - rust-lang/rust#145746 (Fix STD build failing for target_os = "espidf")
 - rust-lang/rust#145826 (Use AcceptContext in AttribueParser::check_target)
 - rust-lang/rust#145894 (Ensure the coordinator thread terminates before its channels drop)
 - rust-lang/rust#145946 (Remove unnecessary `[dependencies.unicode-properties]` entries.)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-08-28 03:06:52 +00:00
commit 43a216604a
8 changed files with 179 additions and 47 deletions

View file

@ -273,14 +273,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
(accept.accept_fn)(&mut cx, args);
if !matches!(cx.stage.should_emit(), ShouldEmit::Nothing) {
Self::check_type(accept.attribute_type, target, &mut cx);
self.check_target(
path.get_attribute_path(),
attr.span,
&accept.allowed_targets,
target,
target_id,
&mut emit_lint,
);
Self::check_target(&accept.allowed_targets, target, &mut cx);
}
}
} else {

View file

@ -3,9 +3,8 @@ use std::borrow::Cow;
use rustc_ast::AttrStyle;
use rustc_errors::DiagArgValue;
use rustc_feature::{AttributeType, Features};
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
use rustc_hir::{AttrPath, MethodKind, Target};
use rustc_span::Span;
use rustc_hir::lints::AttributeLintKind;
use rustc_hir::{MethodKind, Target};
use crate::AttributeParser;
use crate::context::{AcceptContext, Stage};
@ -71,38 +70,34 @@ pub(crate) enum Policy {
impl<'sess, S: Stage> AttributeParser<'sess, S> {
pub(crate) fn check_target(
&self,
attr_name: AttrPath,
attr_span: Span,
allowed_targets: &AllowedTargets,
target: Target,
target_id: S::Id,
mut emit_lint: impl FnMut(AttributeLint<S::Id>),
cx: &mut AcceptContext<'_, 'sess, S>,
) {
match allowed_targets.is_allowed(target) {
AllowedResult::Allowed => {}
AllowedResult::Warn => {
let allowed_targets = allowed_targets.allowed_targets();
let (applied, only) =
allowed_targets_applied(allowed_targets, target, self.features);
emit_lint(AttributeLint {
id: target_id,
span: attr_span,
kind: AttributeLintKind::InvalidTarget {
name: attr_name,
let (applied, only) = allowed_targets_applied(allowed_targets, target, cx.features);
let name = cx.attr_path.clone();
let attr_span = cx.attr_span;
cx.emit_lint(
AttributeLintKind::InvalidTarget {
name,
target,
only: if only { "only " } else { "" },
applied,
},
});
attr_span,
);
}
AllowedResult::Error => {
let allowed_targets = allowed_targets.allowed_targets();
let (applied, only) =
allowed_targets_applied(allowed_targets, target, self.features);
self.dcx().emit_err(InvalidTarget {
span: attr_span,
name: attr_name,
let (applied, only) = allowed_targets_applied(allowed_targets, target, cx.features);
let name = cx.attr_path.clone();
cx.dcx().emit_err(InvalidTarget {
span: cx.attr_span.clone(),
name,
target: target.plural_name(),
only: if only { "only " } else { "" },
applied: DiagArgValue::StrListSepByAnd(

View file

@ -1957,10 +1957,13 @@ impl<B: ExtraBackendMethods> Drop for Coordinator<B> {
pub struct OngoingCodegen<B: ExtraBackendMethods> {
pub backend: B,
pub crate_info: CrateInfo,
pub output_filenames: Arc<OutputFilenames>,
// Field order below is intended to terminate the coordinator thread before two fields below
// drop and prematurely close channels used by coordinator thread. See `Coordinator`'s
// `Drop` implementation for more info.
pub coordinator: Coordinator<B>,
pub codegen_worker_receive: Receiver<CguMessage>,
pub shared_emitter_main: SharedEmitterMain,
pub output_filenames: Arc<OutputFilenames>,
pub coordinator: Coordinator<B>,
}
impl<B: ExtraBackendMethods> OngoingCodegen<B> {

View file

@ -13,6 +13,7 @@ ena = "0.14.3"
indexmap = "2.4.0"
jobserver_crate = { version = "0.1.28", package = "jobserver" }
measureme = "12.0.1"
parking_lot = "0.12"
rustc-hash = "2.0.0"
rustc-stable-hash = { version = "0.1.0", features = ["nightly"] }
rustc_arena = { path = "../rustc_arena" }
@ -34,9 +35,6 @@ version = "0.15.2"
default-features = false
features = ["nightly"] # for may_dangle
[dependencies.parking_lot]
version = "0.12"
[target.'cfg(windows)'.dependencies.windows]
version = "0.61.0"
features = [

View file

@ -15,12 +15,8 @@ Rust lexer used by rustc. No stability guarantees are provided.
# Note that this crate purposefully does not depend on other rustc crates
[dependencies]
memchr.workspace = true
unicode-properties = { version = "0.1.0", default-features = false, features = ["emoji"] }
unicode-xid = "0.2.0"
[dependencies.unicode-properties]
version = "0.1.0"
default-features = false
features = ["emoji"]
[dev-dependencies]
expect-test = "1.4.0"

View file

@ -6,6 +6,7 @@ edition = "2024"
[dependencies]
# tidy-alphabetical-start
bitflags.workspace = true
object = { version = "0.37.0", default-features = false, features = ["elf", "macho"] }
rustc_abi = { path = "../rustc_abi" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_error_messages = { path = "../rustc_error_messages" }
@ -20,9 +21,3 @@ serde_path_to_error = "0.1.17"
tracing.workspace = true
# tidy-alphabetical-end
[dependencies.object]
# tidy-alphabetical-start
default-features = false
features = ["elf", "macho"]
version = "0.37.0"
# tidy-alphabetical-end

View file

@ -117,9 +117,18 @@ pub fn set_permissions(path: &Path, perm: FilePermissions) -> io::Result<()> {
#[cfg(unix)]
pub fn set_permissions_nofollow(path: &Path, perm: crate::fs::Permissions) -> io::Result<()> {
use crate::fs::OpenOptions;
use crate::os::unix::fs::OpenOptionsExt;
OpenOptions::new().custom_flags(libc::O_NOFOLLOW).open(path)?.set_permissions(perm)
let mut options = OpenOptions::new();
// ESP-IDF and Horizon do not support O_NOFOLLOW, so we skip setting it.
// Their filesystems do not have symbolic links, so no special handling is required.
#[cfg(not(any(target_os = "espidf", target_os = "horizon")))]
{
use crate::os::unix::fs::OpenOptionsExt;
options.custom_flags(libc::O_NOFOLLOW);
}
options.open(path)?.set_permissions(perm)
}
#[cfg(not(unix))]

View file

@ -0,0 +1,143 @@
//! Tests that -Zreg-struct-return changes ABI for small struct returns
//! from hidden-pointer convention to register-return on x86_32.
//! This test covers:
//! * Callee side, verifying that the structs are correctly loaded into registers when
//! `-Zreg-struct-return` is activated
//! * Caller side, verifying callers do receive returned structs in registers when
//! `-Zreg-struct-return` is activated
//@ add-core-stubs
//@ assembly-output: emit-asm
//@ compile-flags: -O --target=i686-unknown-linux-gnu -Crelocation-model=static
//@ revisions: WITH WITHOUT
//@[WITH] compile-flags: -Zreg-struct-return
//@ needs-llvm-components: x86
#![feature(no_core)]
#![no_std]
#![no_core]
#![crate_type = "lib"]
extern crate minicore;
use minicore::*;
// Verifies ABI changes for small structs, where both fields fit into one register.
// WITH is expected to use register return, WITHOUT should use hidden pointer.
mod Small {
struct SmallStruct {
a: i8,
b: i8,
}
unsafe extern "C" {
fn small() -> SmallStruct;
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn small_callee() -> SmallStruct {
// (42 << 8) | 42 = 10794
// WITH-LABEL: small_callee
// WITH: movw $10794, %ax
// WITH: retl
// WITHOUT-LABEL: small_callee
// WITHOUT: movl 4(%esp), %e{{.*}}
// WITHOUT: movw $10794, (%e{{.*}})
// WITHOUT: retl $4
SmallStruct { a: 42, b: 42 }
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn small_caller(dst: &mut SmallStruct) {
// WITH-LABEL: small_caller
// WITH: calll small
// WITH: movw %ax, (%e{{.*}})
// WITHOUT-LABEL: small_caller
// WITHOUT: calll small
// WITHOUT: movzwl {{.*}}(%esp), %e[[TMP:..]]
// WITHOUT: movw %[[TMP]], (%e{{..}})
*dst = small();
}
}
// Verifies ABI changes for a struct of size 8, which is the maximum size
// for reg-struct-return.
// WITH is expected to still use register return, WITHOUT should use hidden
// pointer.
mod Pivot {
struct PivotStruct {
a: i32,
b: i32,
}
unsafe extern "C" {
fn pivot() -> PivotStruct;
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pivot_callee() -> PivotStruct {
// WITH-LABEL: pivot_callee
// WITH: movl $42, %e{{.*}}
// WITH: movl $42, %e{{.*}}
// WITH: retl
// WITHOUT-LABEL: pivot_callee
// WITHOUT: movl 4(%esp), %e{{.*}}
// WITHOUT-DAG: movl $42, (%e{{.*}})
// WITHOUT-DAG: movl $42, 4(%e{{.*}})
// WITHOUT: retl $4
PivotStruct { a: 42, b: 42 }
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pivot_caller(dst: &mut PivotStruct) {
// WITH-LABEL: pivot_caller
// WITH: calll pivot
// WITH-DAG: movl %e{{.*}}, 4(%e{{.*}})
// WITH-DAG: movl %e{{.*}}, (%e{{.*}})
// WITHOUT-LABEL: pivot_caller
// WITHOUT: calll pivot
// WITHOUT: movsd {{.*}}(%esp), %[[TMP:xmm.]]
// WITHOUT: movsd %[[TMP]], (%e{{..}})
*dst = pivot();
}
}
// Verifies ABI changes for a struct of size 12, which is larger than the
// maximum size for reg-struct-return (8 bytes).
// Here, the hidden pointer convention should be used even when `-Zreg-struct-return` is set.
mod Large {
struct LargeStruct {
a: i32,
b: i32,
c: i32,
}
unsafe extern "C" {
fn large() -> LargeStruct;
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn large_callee() -> LargeStruct {
// CHECK-LABEL: large_callee
// CHECK: movl 4(%esp), %e{{.*}}
// CHECK-DAG: movl $42, (%e{{.*}})
// CHECK-DAG: movl $42, 4(%e{{.*}})
// CHECK-DAG: movl $42, 8(%e{{.*}})
// CHECK: retl $4
LargeStruct { a: 42, b: 42, c: 42 }
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn large_caller(dst: &mut LargeStruct) {
// CHECK-LABEL: large_caller
// CHECK: calll large
// CHECK-DAG: movl {{.*}}(%esp), %[[TMP1:e..]]
// CHECK-DAG: movl %[[TMP1]], {{.*}}(%e{{..}})
// CHECK-DAG: movsd {{.*}}(%esp), %[[TMP2:xmm.]]
// CHECK-DAG: movsd %[[TMP2]], {{.*}}(%e{{..}})
*dst = large();
}
}