Auto merge of #105703 - matthiaskrgr:rollup-tfpeam2, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #105399 (Use more LFS functions.) - #105578 (Fix transmutes between pointers in different address spaces (e.g. fn ptrs on AVR)) - #105598 (explain mem::forget(env_lock) in fork/exec) - #105624 (Fix unsoundness in bootstrap cache code) - #105630 (Add a test for #92481) - #105684 (Improve rustdoc markdown variable naming) - #105697 (Remove fee1-dead from reviewers) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
b70baa4f92
13 changed files with 150 additions and 26 deletions
|
|
@ -1802,15 +1802,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
match (src.layout.abi, dst.layout.abi) {
|
||||
(abi::Abi::Scalar(src_scalar), abi::Abi::Scalar(dst_scalar)) => {
|
||||
// HACK(eddyb) LLVM doesn't like `bitcast`s between pointers and non-pointers.
|
||||
if (src_scalar.primitive() == abi::Pointer)
|
||||
== (dst_scalar.primitive() == abi::Pointer)
|
||||
{
|
||||
let src_is_ptr = src_scalar.primitive() == abi::Pointer;
|
||||
let dst_is_ptr = dst_scalar.primitive() == abi::Pointer;
|
||||
if src_is_ptr == dst_is_ptr {
|
||||
assert_eq!(src.layout.size, dst.layout.size);
|
||||
|
||||
// NOTE(eddyb) the `from_immediate` and `to_immediate_scalar`
|
||||
// conversions allow handling `bool`s the same as `u8`s.
|
||||
let src = bx.from_immediate(src.immediate());
|
||||
let src_as_dst = bx.bitcast(src, bx.backend_type(dst.layout));
|
||||
// LLVM also doesn't like `bitcast`s between pointers in different address spaces.
|
||||
let src_as_dst = if src_is_ptr {
|
||||
bx.pointercast(src, bx.backend_type(dst.layout))
|
||||
} else {
|
||||
bx.bitcast(src, bx.backend_type(dst.layout))
|
||||
};
|
||||
Immediate(bx.to_immediate_scalar(src_as_dst, dst_scalar)).store(bx, dst);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1759,8 +1759,13 @@ mod remove_dir_impl {
|
|||
use crate::sys::common::small_c_string::run_path_with_cstr;
|
||||
use crate::sys::{cvt, cvt_r};
|
||||
|
||||
#[cfg(not(all(target_os = "macos", not(target_arch = "aarch64")),))]
|
||||
#[cfg(not(any(
|
||||
target_os = "linux",
|
||||
all(target_os = "macos", not(target_arch = "aarch64"))
|
||||
)))]
|
||||
use libc::{fdopendir, openat, unlinkat};
|
||||
#[cfg(target_os = "linux")]
|
||||
use libc::{fdopendir, openat64 as openat, unlinkat};
|
||||
#[cfg(all(target_os = "macos", not(target_arch = "aarch64")))]
|
||||
use macos_weak::{fdopendir, openat, unlinkat};
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,10 @@ use crate::ptr;
|
|||
use crate::sync::atomic::{AtomicBool, AtomicU8, Ordering};
|
||||
use crate::sys::cvt;
|
||||
use crate::sys::weak::syscall;
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use libc::sendfile as sendfile64;
|
||||
#[cfg(target_os = "linux")]
|
||||
use libc::sendfile64;
|
||||
use libc::{EBADF, EINVAL, ENOSYS, EOPNOTSUPP, EOVERFLOW, EPERM, EXDEV};
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -647,7 +651,7 @@ fn sendfile_splice(mode: SpliceMode, reader: RawFd, writer: RawFd, len: u64) ->
|
|||
|
||||
let result = match mode {
|
||||
SpliceMode::Sendfile => {
|
||||
cvt(unsafe { libc::sendfile(writer, reader, ptr::null_mut(), chunk_size) })
|
||||
cvt(unsafe { sendfile64(writer, reader, ptr::null_mut(), chunk_size) })
|
||||
}
|
||||
SpliceMode::Splice => cvt(unsafe {
|
||||
splice(reader, ptr::null_mut(), writer, ptr::null_mut(), chunk_size, 0)
|
||||
|
|
|
|||
|
|
@ -95,6 +95,10 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
|
|||
)))]
|
||||
'poll: {
|
||||
use crate::sys::os::errno;
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use libc::open as open64;
|
||||
#[cfg(target_os = "linux")]
|
||||
use libc::open64;
|
||||
let pfds: &mut [_] = &mut [
|
||||
libc::pollfd { fd: 0, events: 0, revents: 0 },
|
||||
libc::pollfd { fd: 1, events: 0, revents: 0 },
|
||||
|
|
@ -116,7 +120,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
|
|||
if pfd.revents & libc::POLLNVAL == 0 {
|
||||
continue;
|
||||
}
|
||||
if libc::open("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 {
|
||||
if open64("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 {
|
||||
// If the stream is closed but we failed to reopen it, abort the
|
||||
// process. Otherwise we wouldn't preserve the safety of
|
||||
// operations on the corresponding Rust object Stdin, Stdout, or
|
||||
|
|
@ -139,9 +143,13 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
|
|||
)))]
|
||||
{
|
||||
use crate::sys::os::errno;
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use libc::open as open64;
|
||||
#[cfg(target_os = "linux")]
|
||||
use libc::open64;
|
||||
for fd in 0..3 {
|
||||
if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF {
|
||||
if libc::open("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 {
|
||||
if open64("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 {
|
||||
// If the stream is closed but we failed to reopen it, abort the
|
||||
// process. Otherwise we wouldn't preserve the safety of
|
||||
// operations on the corresponding Rust object Stdin, Stdout, or
|
||||
|
|
|
|||
|
|
@ -66,14 +66,15 @@ impl Command {
|
|||
//
|
||||
// Note that as soon as we're done with the fork there's no need to hold
|
||||
// a lock any more because the parent won't do anything and the child is
|
||||
// in its own process. Thus the parent drops the lock guard while the child
|
||||
// forgets it to avoid unlocking it on a new thread, which would be invalid.
|
||||
// in its own process. Thus the parent drops the lock guard immediately.
|
||||
// The child calls `mem::forget` to leak the lock, which is crucial because
|
||||
// releasing a lock is not async-signal-safe.
|
||||
let env_lock = sys::os::env_read_lock();
|
||||
let (pid, pidfd) = unsafe { self.do_fork()? };
|
||||
|
||||
if pid == 0 {
|
||||
crate::panic::always_abort();
|
||||
mem::forget(env_lock);
|
||||
mem::forget(env_lock); // avoid non-async-signal-safe unlocking
|
||||
drop(input);
|
||||
let Err(err) = unsafe { self.do_exec(theirs, envp.as_ref()) };
|
||||
let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,10 @@ mod imp {
|
|||
use crate::thread;
|
||||
|
||||
use libc::MAP_FAILED;
|
||||
use libc::{mmap, munmap};
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use libc::{mmap as mmap64, munmap};
|
||||
#[cfg(target_os = "linux")]
|
||||
use libc::{mmap64, munmap};
|
||||
use libc::{sigaction, sighandler_t, SA_ONSTACK, SA_SIGINFO, SIGBUS, SIG_DFL};
|
||||
use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE};
|
||||
use libc::{MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE, SIGSEGV};
|
||||
|
|
@ -135,7 +138,7 @@ mod imp {
|
|||
#[cfg(not(any(target_os = "openbsd", target_os = "netbsd", target_os = "linux",)))]
|
||||
let flags = MAP_PRIVATE | MAP_ANON;
|
||||
let stackp =
|
||||
mmap(ptr::null_mut(), SIGSTKSZ + page_size(), PROT_READ | PROT_WRITE, flags, -1, 0);
|
||||
mmap64(ptr::null_mut(), SIGSTKSZ + page_size(), PROT_READ | PROT_WRITE, flags, -1, 0);
|
||||
if stackp == MAP_FAILED {
|
||||
panic!("failed to allocate an alternative stack: {}", io::Error::last_os_error());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -653,7 +653,10 @@ pub mod guard {
|
|||
))]
|
||||
#[cfg_attr(test, allow(dead_code))]
|
||||
pub mod guard {
|
||||
use libc::{mmap, mprotect};
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use libc::{mmap as mmap64, mprotect};
|
||||
#[cfg(target_os = "linux")]
|
||||
use libc::{mmap64, mprotect};
|
||||
use libc::{MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE};
|
||||
|
||||
use crate::io;
|
||||
|
|
@ -803,7 +806,7 @@ pub mod guard {
|
|||
// read/write permissions and only then mprotect() it to
|
||||
// no permissions at all. See issue #50313.
|
||||
let stackptr = get_stack_start_aligned()?;
|
||||
let result = mmap(
|
||||
let result = mmap64(
|
||||
stackptr,
|
||||
page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
|
|
|
|||
|
|
@ -89,16 +89,16 @@ impl<T: Internable + Hash> Hash for Interned<T> {
|
|||
|
||||
impl<T: Internable + Deref> Deref for Interned<T> {
|
||||
type Target = T::Target;
|
||||
fn deref(&self) -> &'static Self::Target {
|
||||
fn deref(&self) -> &Self::Target {
|
||||
let l = T::intern_cache().lock().unwrap();
|
||||
unsafe { mem::transmute::<&Self::Target, &'static Self::Target>(l.get(*self)) }
|
||||
unsafe { mem::transmute::<&Self::Target, &Self::Target>(l.get(*self)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Internable + AsRef<U>, U: ?Sized> AsRef<U> for Interned<T> {
|
||||
fn as_ref(&self) -> &'static U {
|
||||
fn as_ref(&self) -> &U {
|
||||
let l = T::intern_cache().lock().unwrap();
|
||||
unsafe { mem::transmute::<&U, &'static U>(l.get(*self).as_ref()) }
|
||||
unsafe { mem::transmute::<&U, &U>(l.get(*self).as_ref()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -236,12 +236,12 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
|||
return event;
|
||||
};
|
||||
|
||||
let mut origtext = String::new();
|
||||
let mut original_text = String::new();
|
||||
for event in &mut self.inner {
|
||||
match event {
|
||||
Event::End(Tag::CodeBlock(..)) => break,
|
||||
Event::Text(ref s) => {
|
||||
origtext.push_str(s);
|
||||
original_text.push_str(s);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -258,7 +258,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
|||
<pre class=\"language-{}\"><code>{}</code></pre>\
|
||||
</div>",
|
||||
lang,
|
||||
Escape(&origtext),
|
||||
Escape(&original_text),
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
|
|
@ -268,7 +268,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
|||
CodeBlockKind::Indented => Default::default(),
|
||||
};
|
||||
|
||||
let lines = origtext.lines().filter_map(|l| map_line(l).for_html());
|
||||
let lines = original_text.lines().filter_map(|l| map_line(l).for_html());
|
||||
let text = lines.intersperse("\n".into()).collect::<String>();
|
||||
|
||||
compile_fail = parse_result.compile_fail;
|
||||
|
|
@ -285,7 +285,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
|||
if url.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let test = origtext
|
||||
let test = original_text
|
||||
.lines()
|
||||
.map(|l| map_line(l).for_code())
|
||||
.intersperse("\n".into())
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
// It also validates that functions can be called through function pointers
|
||||
// through traits.
|
||||
|
||||
#![feature(no_core, lang_items, unboxed_closures, arbitrary_self_types)]
|
||||
#![feature(no_core, lang_items, intrinsics, unboxed_closures, arbitrary_self_types)]
|
||||
#![crate_type = "lib"]
|
||||
#![no_core]
|
||||
|
||||
|
|
@ -49,6 +49,10 @@ pub trait Fn<Args: Tuple>: FnOnce<Args> {
|
|||
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
|
||||
}
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
pub fn transmute<Src, Dst>(src: Src) -> Dst;
|
||||
}
|
||||
|
||||
pub static mut STORAGE_FOO: fn(&usize, &mut u32) -> Result<(), ()> = arbitrary_black_box;
|
||||
pub static mut STORAGE_BAR: u32 = 12;
|
||||
|
||||
|
|
@ -87,3 +91,21 @@ pub extern "C" fn test() {
|
|||
STORAGE_FOO(&1, &mut buf);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate that we can codegen transmutes between data ptrs and fn ptrs.
|
||||
|
||||
// CHECK: define{{.+}}{{void \(\) addrspace\(1\)\*|ptr addrspace\(1\)}} @transmute_data_ptr_to_fn({{\{\}\*|ptr}}{{.*}} %x)
|
||||
#[no_mangle]
|
||||
pub unsafe fn transmute_data_ptr_to_fn(x: *const ()) -> fn() {
|
||||
// It doesn't matter precisely how this is codegenned (through memory or an addrspacecast),
|
||||
// as long as it doesn't cause a verifier error by using `bitcast`.
|
||||
transmute(x)
|
||||
}
|
||||
|
||||
// CHECK: define{{.+}}{{\{\}\*|ptr}} @transmute_fn_ptr_to_data({{void \(\) addrspace\(1\)\*|ptr addrspace\(1\)}}{{.*}} %x)
|
||||
#[no_mangle]
|
||||
pub unsafe fn transmute_fn_ptr_to_data(x: fn()) -> *const () {
|
||||
// It doesn't matter precisely how this is codegenned (through memory or an addrspacecast),
|
||||
// as long as it doesn't cause a verifier error by using `bitcast`.
|
||||
transmute(x)
|
||||
}
|
||||
|
|
|
|||
14
src/test/ui/typeck/issue-92481.rs
Normal file
14
src/test/ui/typeck/issue-92481.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
//check-fail
|
||||
|
||||
#![crate_type="lib"]
|
||||
|
||||
fn r({) {
|
||||
Ok { //~ ERROR mismatched types [E0308]
|
||||
d..||_=m
|
||||
}
|
||||
}
|
||||
//~^^^^^ ERROR expected parameter name, found `{`
|
||||
//~| ERROR expected one of `,`, `:`, or `}`, found `..`
|
||||
//~^^^^^ ERROR cannot find value `d` in this scope [E0425]
|
||||
//~| ERROR cannot find value `m` in this scope [E0425]
|
||||
//~| ERROR variant `Result<_, _>::Ok` has no field named `d` [E0559]
|
||||
60
src/test/ui/typeck/issue-92481.stderr
Normal file
60
src/test/ui/typeck/issue-92481.stderr
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
error: expected parameter name, found `{`
|
||||
--> $DIR/issue-92481.rs:5:6
|
||||
|
|
||||
LL | fn r({) {
|
||||
| ^ expected parameter name
|
||||
|
||||
error: expected one of `,`, `:`, or `}`, found `..`
|
||||
--> $DIR/issue-92481.rs:5:6
|
||||
|
|
||||
LL | fn r({) {
|
||||
| ^ unclosed delimiter
|
||||
LL | Ok {
|
||||
LL | d..||_=m
|
||||
| -^
|
||||
| |
|
||||
| help: `}` may belong here
|
||||
|
||||
error[E0425]: cannot find value `d` in this scope
|
||||
--> $DIR/issue-92481.rs:7:9
|
||||
|
|
||||
LL | d..||_=m
|
||||
| ^ not found in this scope
|
||||
|
||||
error[E0425]: cannot find value `m` in this scope
|
||||
--> $DIR/issue-92481.rs:7:16
|
||||
|
|
||||
LL | d..||_=m
|
||||
| ^ not found in this scope
|
||||
|
||||
error[E0559]: variant `Result<_, _>::Ok` has no field named `d`
|
||||
--> $DIR/issue-92481.rs:7:9
|
||||
|
|
||||
LL | d..||_=m
|
||||
| ^ field does not exist
|
||||
--> $SRC_DIR/core/src/result.rs:LL:COL
|
||||
|
|
||||
= note: `Result<_, _>::Ok` defined here
|
||||
|
|
||||
help: `Result<_, _>::Ok` is a tuple variant, use the appropriate syntax
|
||||
|
|
||||
LL | Result<_, _>::Ok(/* fields */)
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-92481.rs:6:5
|
||||
|
|
||||
LL | fn r({) {
|
||||
| - help: a return type might be missing here: `-> _`
|
||||
LL | / Ok {
|
||||
LL | | d..||_=m
|
||||
LL | | }
|
||||
| |_____^ expected `()`, found enum `Result`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found enum `Result<_, _>`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0425, E0559.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
|
@ -467,7 +467,6 @@ compiler-team-contributors = [
|
|||
"@compiler-errors",
|
||||
"@eholk",
|
||||
"@jackh726",
|
||||
"@fee1-dead",
|
||||
"@TaKO8Ki",
|
||||
"@Nilstrieb",
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue