Skip to content

Commit 3d461af

Browse files
committed
Auto merge of #149059 - GuillaumeGomez:rollup-s6m2mmy, r=GuillaumeGomez
Rollup of 4 pull requests Successful merges: - #148970 (std: sys: fs: uefi: Implement stat) - #149020 (flush_delayed: add note about stashed diagnostics) - #149026 (Add test for href of reexported enum variant) - #149049 (compiletest: Use JSON "binary-format" to decide `//@ only-elf` and `//@ ignore-elf`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents f9e7961 + 6120f0d commit 3d461af

File tree

8 files changed

+108
-11
lines changed

8 files changed

+108
-11
lines changed

compiler/rustc_errors/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,10 @@ impl<'a> DiagCtxtHandle<'a> {
12051205
std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations)
12061206
}
12071207

1208+
/// Trigger an ICE if there are any delayed bugs and no hard errors.
1209+
///
1210+
/// This will panic if there are any stashed diagnostics. You can call
1211+
/// `emit_stashed_diagnostics` to emit those before calling `flush_delayed`.
12081212
pub fn flush_delayed(&self) {
12091213
self.inner.borrow_mut().flush_delayed();
12101214
}

library/std/src/sys/fs/uefi.rs

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::hash::Hash;
77
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
88
use crate::path::{Path, PathBuf};
99
use crate::sys::time::SystemTime;
10-
use crate::sys::unsupported;
10+
use crate::sys::{helpers, unsupported};
1111

1212
#[expect(dead_code)]
1313
const FILE_PERMISSIONS_MASK: u64 = r_efi::protocols::file::READ_ONLY;
@@ -76,6 +76,18 @@ impl FileAttr {
7676
pub fn created(&self) -> io::Result<SystemTime> {
7777
Ok(self.created)
7878
}
79+
80+
fn from_uefi(info: helpers::UefiBox<file::Info>) -> Self {
81+
unsafe {
82+
Self {
83+
attr: (*info.as_ptr()).attribute,
84+
size: (*info.as_ptr()).size,
85+
modified: uefi_fs::uefi_to_systemtime((*info.as_ptr()).modification_time),
86+
accessed: uefi_fs::uefi_to_systemtime((*info.as_ptr()).last_access_time),
87+
created: uefi_fs::uefi_to_systemtime((*info.as_ptr()).create_time),
88+
}
89+
}
90+
}
7991
}
8092

8193
impl FilePermissions {
@@ -381,8 +393,10 @@ pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> {
381393
unsupported()
382394
}
383395

384-
pub fn stat(_p: &Path) -> io::Result<FileAttr> {
385-
unsupported()
396+
pub fn stat(p: &Path) -> io::Result<FileAttr> {
397+
let f = uefi_fs::File::from_path(p, r_efi::protocols::file::MODE_READ, 0)?;
398+
let inf = f.file_info()?;
399+
Ok(FileAttr::from_uefi(inf))
386400
}
387401

388402
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
@@ -404,7 +418,7 @@ mod uefi_fs {
404418
use crate::io;
405419
use crate::path::Path;
406420
use crate::ptr::NonNull;
407-
use crate::sys::helpers;
421+
use crate::sys::helpers::{self, UefiBox};
408422
use crate::sys::time::{self, SystemTime};
409423

410424
pub(crate) struct File(NonNull<file::Protocol>);
@@ -492,6 +506,37 @@ mod uefi_fs {
492506
let p = NonNull::new(file_opened).unwrap();
493507
Ok(File(p))
494508
}
509+
510+
pub(crate) fn file_info(&self) -> io::Result<UefiBox<file::Info>> {
511+
let file_ptr = self.0.as_ptr();
512+
let mut info_id = file::INFO_ID;
513+
let mut buf_size = 0;
514+
515+
let r = unsafe {
516+
((*file_ptr).get_info)(
517+
file_ptr,
518+
&mut info_id,
519+
&mut buf_size,
520+
crate::ptr::null_mut(),
521+
)
522+
};
523+
assert!(r.is_error());
524+
if r != r_efi::efi::Status::BUFFER_TOO_SMALL {
525+
return Err(io::Error::from_raw_os_error(r.as_usize()));
526+
}
527+
528+
let mut info: UefiBox<file::Info> = UefiBox::new(buf_size)?;
529+
let r = unsafe {
530+
((*file_ptr).get_info)(
531+
file_ptr,
532+
&mut info_id,
533+
&mut buf_size,
534+
info.as_mut_ptr().cast(),
535+
)
536+
};
537+
538+
if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(info) }
539+
}
495540
}
496541

497542
impl Drop for File {
@@ -556,8 +601,7 @@ mod uefi_fs {
556601

557602
/// EDK2 FAT driver uses EFI_UNSPECIFIED_TIMEZONE to represent localtime. So for proper
558603
/// conversion to SystemTime, we use the current time to get the timezone in such cases.
559-
#[expect(dead_code)]
560-
fn uefi_to_systemtime(mut time: r_efi::efi::Time) -> SystemTime {
604+
pub(crate) fn uefi_to_systemtime(mut time: r_efi::efi::Time) -> SystemTime {
561605
time.timezone = if time.timezone == r_efi::efi::UNSPECIFIED_TIMEZONE {
562606
time::system_time_internal::now().unwrap().timezone
563607
} else {

library/std/src/sys/pal/uefi/helpers.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,10 @@ impl<T> UefiBox<T> {
798798
pub(crate) fn as_mut_ptr(&mut self) -> *mut T {
799799
self.inner.as_ptr().cast()
800800
}
801+
802+
pub(crate) fn as_ptr(&self) -> *const T {
803+
self.inner.as_ptr().cast()
804+
}
801805
}
802806

803807
impl<T> Drop for UefiBox<T> {

src/tools/compiletest/src/common.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::borrow::Cow;
12
use std::collections::{BTreeSet, HashMap, HashSet};
23
use std::iter;
34
use std::process::Command;
@@ -1011,6 +1012,13 @@ pub struct TargetCfg {
10111012
// target spec).
10121013
pub(crate) rustc_abi: Option<String>,
10131014

1015+
/// ELF is the "default" binary format, so the compiler typically doesn't
1016+
/// emit a `"binary-format"` field for ELF targets.
1017+
///
1018+
/// See `impl ToJson for Target` in `compiler/rustc_target/src/spec/json.rs`.
1019+
#[serde(default = "default_binary_format_elf")]
1020+
pub(crate) binary_format: Cow<'static, str>,
1021+
10141022
// Not present in target cfg json output, additional derived information.
10151023
#[serde(skip)]
10161024
/// 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 {
10321040
"pic".into()
10331041
}
10341042

1043+
fn default_binary_format_elf() -> Cow<'static, str> {
1044+
Cow::Borrowed("elf")
1045+
}
1046+
10351047
#[derive(Eq, PartialEq, Clone, Debug, Default, serde::Deserialize)]
10361048
#[serde(rename_all = "kebab-case")]
10371049
pub enum Endian {

src/tools/compiletest/src/directives/cfg.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,7 @@ fn parse_cfg_name_directive<'a>(
169169

170170
condition! {
171171
name: "elf",
172-
condition: !config.target.contains("windows")
173-
&& !config.target.contains("wasm")
174-
&& !config.target.contains("apple")
175-
&& !config.target.contains("aix")
176-
&& !config.target.contains("uefi"),
172+
condition: target_cfg.binary_format == "elf",
177173
message: "when the target binary format is ELF"
178174
}
179175

src/tools/compiletest/src/directives/tests.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,29 @@ fn ignore_coverage() {
766766
assert!(check_ignore(&config, "//@ ignore-coverage-run"));
767767
}
768768

769+
#[test]
770+
fn only_ignore_elf() {
771+
let cases = &[
772+
("aarch64-apple-darwin", false),
773+
("aarch64-unknown-linux-gnu", true),
774+
("powerpc64-ibm-aix", false),
775+
("wasm32-unknown-unknown", false),
776+
("wasm32-wasip1", false),
777+
("x86_64-apple-darwin", false),
778+
("x86_64-pc-windows-msvc", false),
779+
("x86_64-unknown-freebsd", true),
780+
("x86_64-unknown-illumos", true),
781+
("x86_64-unknown-linux-gnu", true),
782+
("x86_64-unknown-none", true),
783+
("x86_64-unknown-uefi", false),
784+
];
785+
for &(target, is_elf) in cases {
786+
let config = &cfg().target(target).build();
787+
assert_eq!(is_elf, check_ignore(config, "//@ ignore-elf"), "`//@ ignore-elf` for {target}");
788+
assert_eq!(is_elf, !check_ignore(config, "//@ only-elf"), "`//@ only-elf` for {target}");
789+
}
790+
}
791+
769792
#[test]
770793
fn threads_support() {
771794
let threads = [
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// This test ensures that reexported enum variants correctly link to the original variant.
2+
3+
#![crate_name = "foo"]
4+
5+
pub enum Foo {
6+
S {
7+
x: u32,
8+
},
9+
}
10+
11+
//@ has 'foo/index.html'
12+
13+
//@ has - '//*[@class="item-table reexports"]/*[@id="reexport.S"]//a[@href="enum.Foo.html#variant.S"]' 'S'
14+
pub use self::Foo::S;

0 commit comments

Comments
 (0)