Skip to content

Rollup of 7 pull requests #105703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Dec 14, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
@@ -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;
}
7 changes: 6 additions & 1 deletion library/std/src/sys/unix/fs.rs
Original file line number Diff line number Diff line change
@@ -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};

6 changes: 5 additions & 1 deletion library/std/src/sys/unix/kernel_copy.rs
Original file line number Diff line number Diff line change
@@ -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)
12 changes: 10 additions & 2 deletions library/std/src/sys/unix/mod.rs
Original file line number Diff line number Diff line change
@@ -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
7 changes: 4 additions & 3 deletions library/std/src/sys/unix/process/process_unix.rs
Original file line number Diff line number Diff line change
@@ -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;
7 changes: 5 additions & 2 deletions library/std/src/sys/unix/stack_overflow.rs
Original file line number Diff line number Diff line change
@@ -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());
}
7 changes: 5 additions & 2 deletions library/std/src/sys/unix/thread.rs
Original file line number Diff line number Diff line change
@@ -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,
8 changes: 4 additions & 4 deletions src/bootstrap/cache.rs
Original file line number Diff line number Diff line change
@@ -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()) }
}
}

10 changes: 5 additions & 5 deletions src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
@@ -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())
24 changes: 23 additions & 1 deletion src/test/codegen/avr/avr-func-addrspace.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 14 additions & 0 deletions src/test/ui/typeck/issue-92481.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 60 additions & 0 deletions src/test/ui/typeck/issue-92481.stderr
Original file line number Diff line number Diff line change
@@ -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`.
1 change: 0 additions & 1 deletion triagebot.toml
Original file line number Diff line number Diff line change
@@ -467,7 +467,6 @@ compiler-team-contributors = [
"@compiler-errors",
"@eholk",
"@jackh726",
"@fee1-dead",
"@TaKO8Ki",
"@Nilstrieb",
]