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:
commit
3d461af2a2
8 changed files with 108 additions and 11 deletions
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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> {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 = [
|
||||||
|
|
|
||||||
14
tests/rustdoc/reexport/enum-variant.rs
Normal file
14
tests/rustdoc/reexport/enum-variant.rs
Normal 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;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue