Auto merge of #149059 - GuillaumeGomez:rollup-s6m2mmy, r=GuillaumeGomez

Rollup of 4 pull requests

Successful merges:

 - rust-lang/rust#148970 (std: sys: fs: uefi: Implement stat)
 - rust-lang/rust#149020 (flush_delayed: add note about stashed diagnostics)
 - rust-lang/rust#149026 (Add test for href of reexported enum variant)
 - rust-lang/rust#149049 (compiletest: Use JSON "binary-format" to decide `//@ only-elf` and `//@ ignore-elf`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-11-18 14:07:46 +00:00
commit 3d461af2a2
8 changed files with 108 additions and 11 deletions

View file

@ -1205,6 +1205,10 @@ impl<'a> DiagCtxtHandle<'a> {
std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations) std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations)
} }
/// Trigger an ICE if there are any delayed bugs and no hard errors.
///
/// This will panic if there are any stashed diagnostics. You can call
/// `emit_stashed_diagnostics` to emit those before calling `flush_delayed`.
pub fn flush_delayed(&self) { pub fn flush_delayed(&self) {
self.inner.borrow_mut().flush_delayed(); self.inner.borrow_mut().flush_delayed();
} }

View file

@ -7,7 +7,7 @@ use crate::hash::Hash;
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
use crate::path::{Path, PathBuf}; use crate::path::{Path, PathBuf};
use crate::sys::time::SystemTime; use crate::sys::time::SystemTime;
use crate::sys::unsupported; use crate::sys::{helpers, unsupported};
#[expect(dead_code)] #[expect(dead_code)]
const FILE_PERMISSIONS_MASK: u64 = r_efi::protocols::file::READ_ONLY; const FILE_PERMISSIONS_MASK: u64 = r_efi::protocols::file::READ_ONLY;
@ -76,6 +76,18 @@ impl FileAttr {
pub fn created(&self) -> io::Result<SystemTime> { pub fn created(&self) -> io::Result<SystemTime> {
Ok(self.created) Ok(self.created)
} }
fn from_uefi(info: helpers::UefiBox<file::Info>) -> Self {
unsafe {
Self {
attr: (*info.as_ptr()).attribute,
size: (*info.as_ptr()).size,
modified: uefi_fs::uefi_to_systemtime((*info.as_ptr()).modification_time),
accessed: uefi_fs::uefi_to_systemtime((*info.as_ptr()).last_access_time),
created: uefi_fs::uefi_to_systemtime((*info.as_ptr()).create_time),
}
}
}
} }
impl FilePermissions { impl FilePermissions {
@ -381,8 +393,10 @@ pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> {
unsupported() unsupported()
} }
pub fn stat(_p: &Path) -> io::Result<FileAttr> { pub fn stat(p: &Path) -> io::Result<FileAttr> {
unsupported() let f = uefi_fs::File::from_path(p, r_efi::protocols::file::MODE_READ, 0)?;
let inf = f.file_info()?;
Ok(FileAttr::from_uefi(inf))
} }
pub fn lstat(p: &Path) -> io::Result<FileAttr> { pub fn lstat(p: &Path) -> io::Result<FileAttr> {
@ -404,7 +418,7 @@ mod uefi_fs {
use crate::io; use crate::io;
use crate::path::Path; use crate::path::Path;
use crate::ptr::NonNull; use crate::ptr::NonNull;
use crate::sys::helpers; use crate::sys::helpers::{self, UefiBox};
use crate::sys::time::{self, SystemTime}; use crate::sys::time::{self, SystemTime};
pub(crate) struct File(NonNull<file::Protocol>); pub(crate) struct File(NonNull<file::Protocol>);
@ -492,6 +506,37 @@ mod uefi_fs {
let p = NonNull::new(file_opened).unwrap(); let p = NonNull::new(file_opened).unwrap();
Ok(File(p)) Ok(File(p))
} }
pub(crate) fn file_info(&self) -> io::Result<UefiBox<file::Info>> {
let file_ptr = self.0.as_ptr();
let mut info_id = file::INFO_ID;
let mut buf_size = 0;
let r = unsafe {
((*file_ptr).get_info)(
file_ptr,
&mut info_id,
&mut buf_size,
crate::ptr::null_mut(),
)
};
assert!(r.is_error());
if r != r_efi::efi::Status::BUFFER_TOO_SMALL {
return Err(io::Error::from_raw_os_error(r.as_usize()));
}
let mut info: UefiBox<file::Info> = UefiBox::new(buf_size)?;
let r = unsafe {
((*file_ptr).get_info)(
file_ptr,
&mut info_id,
&mut buf_size,
info.as_mut_ptr().cast(),
)
};
if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(info) }
}
} }
impl Drop for File { impl Drop for File {
@ -556,8 +601,7 @@ mod uefi_fs {
/// EDK2 FAT driver uses EFI_UNSPECIFIED_TIMEZONE to represent localtime. So for proper /// EDK2 FAT driver uses EFI_UNSPECIFIED_TIMEZONE to represent localtime. So for proper
/// conversion to SystemTime, we use the current time to get the timezone in such cases. /// conversion to SystemTime, we use the current time to get the timezone in such cases.
#[expect(dead_code)] pub(crate) fn uefi_to_systemtime(mut time: r_efi::efi::Time) -> SystemTime {
fn uefi_to_systemtime(mut time: r_efi::efi::Time) -> SystemTime {
time.timezone = if time.timezone == r_efi::efi::UNSPECIFIED_TIMEZONE { time.timezone = if time.timezone == r_efi::efi::UNSPECIFIED_TIMEZONE {
time::system_time_internal::now().unwrap().timezone time::system_time_internal::now().unwrap().timezone
} else { } else {

View file

@ -798,6 +798,10 @@ impl<T> UefiBox<T> {
pub(crate) fn as_mut_ptr(&mut self) -> *mut T { pub(crate) fn as_mut_ptr(&mut self) -> *mut T {
self.inner.as_ptr().cast() self.inner.as_ptr().cast()
} }
pub(crate) fn as_ptr(&self) -> *const T {
self.inner.as_ptr().cast()
}
} }
impl<T> Drop for UefiBox<T> { impl<T> Drop for UefiBox<T> {

View file

@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::collections::{BTreeSet, HashMap, HashSet}; use std::collections::{BTreeSet, HashMap, HashSet};
use std::iter; use std::iter;
use std::process::Command; use std::process::Command;
@ -1011,6 +1012,13 @@ pub struct TargetCfg {
// target spec). // target spec).
pub(crate) rustc_abi: Option<String>, pub(crate) rustc_abi: Option<String>,
/// ELF is the "default" binary format, so the compiler typically doesn't
/// emit a `"binary-format"` field for ELF targets.
///
/// See `impl ToJson for Target` in `compiler/rustc_target/src/spec/json.rs`.
#[serde(default = "default_binary_format_elf")]
pub(crate) binary_format: Cow<'static, str>,
// Not present in target cfg json output, additional derived information. // Not present in target cfg json output, additional derived information.
#[serde(skip)] #[serde(skip)]
/// Supported target atomic widths: e.g. `8` to `128` or `ptr`. This is derived from the builtin /// Supported target atomic widths: e.g. `8` to `128` or `ptr`. This is derived from the builtin
@ -1032,6 +1040,10 @@ fn default_reloc_model() -> String {
"pic".into() "pic".into()
} }
fn default_binary_format_elf() -> Cow<'static, str> {
Cow::Borrowed("elf")
}
#[derive(Eq, PartialEq, Clone, Debug, Default, serde::Deserialize)] #[derive(Eq, PartialEq, Clone, Debug, Default, serde::Deserialize)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
pub enum Endian { pub enum Endian {

View file

@ -169,11 +169,7 @@ fn parse_cfg_name_directive<'a>(
condition! { condition! {
name: "elf", name: "elf",
condition: !config.target.contains("windows") condition: target_cfg.binary_format == "elf",
&& !config.target.contains("wasm")
&& !config.target.contains("apple")
&& !config.target.contains("aix")
&& !config.target.contains("uefi"),
message: "when the target binary format is ELF" message: "when the target binary format is ELF"
} }

View file

@ -766,6 +766,29 @@ fn ignore_coverage() {
assert!(check_ignore(&config, "//@ ignore-coverage-run")); assert!(check_ignore(&config, "//@ ignore-coverage-run"));
} }
#[test]
fn only_ignore_elf() {
let cases = &[
("aarch64-apple-darwin", false),
("aarch64-unknown-linux-gnu", true),
("powerpc64-ibm-aix", false),
("wasm32-unknown-unknown", false),
("wasm32-wasip1", false),
("x86_64-apple-darwin", false),
("x86_64-pc-windows-msvc", false),
("x86_64-unknown-freebsd", true),
("x86_64-unknown-illumos", true),
("x86_64-unknown-linux-gnu", true),
("x86_64-unknown-none", true),
("x86_64-unknown-uefi", false),
];
for &(target, is_elf) in cases {
let config = &cfg().target(target).build();
assert_eq!(is_elf, check_ignore(config, "//@ ignore-elf"), "`//@ ignore-elf` for {target}");
assert_eq!(is_elf, !check_ignore(config, "//@ only-elf"), "`//@ only-elf` for {target}");
}
}
#[test] #[test]
fn threads_support() { fn threads_support() {
let threads = [ let threads = [

View file

@ -0,0 +1,14 @@
// This test ensures that reexported enum variants correctly link to the original variant.
#![crate_name = "foo"]
pub enum Foo {
S {
x: u32,
},
}
//@ has 'foo/index.html'
//@ has - '//*[@class="item-table reexports"]/*[@id="reexport.S"]//a[@href="enum.Foo.html#variant.S"]' 'S'
pub use self::Foo::S;