From 6896ed383dbd3a847ef39b713449fc0393292828 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 09:47:58 +0300 Subject: [PATCH 001/462] use wasi crate --- src/libstd/sys/wasi/args.rs | 16 +- src/libstd/sys/wasi/ext/fs.rs | 8 +- src/libstd/sys/wasi/ext/io.rs | 8 +- src/libstd/sys/wasi/fd.rs | 302 +++++++++++----------------------- src/libstd/sys/wasi/fs.rs | 176 +++++++++----------- src/libstd/sys/wasi/io.rs | 11 +- src/libstd/sys/wasi/mod.rs | 31 ++-- src/libstd/sys/wasi/os.rs | 29 +--- src/libstd/sys/wasi/stdio.rs | 11 +- src/libstd/sys/wasi/thread.rs | 4 +- src/libstd/sys/wasi/time.rs | 29 ++-- 11 files changed, 249 insertions(+), 376 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index 8b4b354d9fc20..679bb1b2cbe30 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -27,14 +27,24 @@ pub fn args() -> Args { }) } +fn cvt_wasi(r: u16) -> crate::io::Result<()> { + if r != 0 { + Err(Error::from_raw_os_error(r as i32)) + } else { + Ok(()) + } +} + fn maybe_args() -> io::Result { + // FIXME: replace with safe functions + use wasi::wasi_unstable::raw::{__wasi_args_sizes_get, __wasi_args_get}; unsafe { let (mut argc, mut argv_buf_size) = (0, 0); - cvt_wasi(libc::__wasi_args_sizes_get(&mut argc, &mut argv_buf_size))?; + cvt_wasi(__wasi_args_sizes_get(&mut argc, &mut argv_buf_size))?; - let mut argc = vec![core::ptr::null_mut::(); argc]; + let mut argc = vec![core::ptr::null_mut::(); argc]; let mut argv_buf = vec![0; argv_buf_size]; - cvt_wasi(libc::__wasi_args_get(argc.as_mut_ptr(), argv_buf.as_mut_ptr()))?; + cvt_wasi(__wasi_args_get(argc.as_mut_ptr(), argv_buf.as_mut_ptr()))?; let args = argc.into_iter() .map(|ptr| CStr::from_ptr(ptr).to_bytes().to_vec()) diff --git a/src/libstd/sys/wasi/ext/fs.rs b/src/libstd/sys/wasi/ext/fs.rs index 0ec4122f385da..ecd509f01dabd 100644 --- a/src/libstd/sys/wasi/ext/fs.rs +++ b/src/libstd/sys/wasi/ext/fs.rs @@ -336,16 +336,16 @@ pub trait FileTypeExt { impl FileTypeExt for fs::FileType { fn is_block_device(&self) -> bool { - self.as_inner().bits() == libc::__WASI_FILETYPE_BLOCK_DEVICE + self.as_inner().bits() == wasi::FILETYPE_BLOCK_DEVICE } fn is_character_device(&self) -> bool { - self.as_inner().bits() == libc::__WASI_FILETYPE_CHARACTER_DEVICE + self.as_inner().bits() == wasi::FILETYPE_CHARACTER_DEVICE } fn is_socket_dgram(&self) -> bool { - self.as_inner().bits() == libc::__WASI_FILETYPE_SOCKET_DGRAM + self.as_inner().bits() == wasi::FILETYPE_SOCKET_DGRAM } fn is_socket_stream(&self) -> bool { - self.as_inner().bits() == libc::__WASI_FILETYPE_SOCKET_STREAM + self.as_inner().bits() == wasi::FILETYPE_SOCKET_STREAM } } diff --git a/src/libstd/sys/wasi/ext/io.rs b/src/libstd/sys/wasi/ext/io.rs index 12afd1d42dc19..c843144f0c406 100644 --- a/src/libstd/sys/wasi/ext/io.rs +++ b/src/libstd/sys/wasi/ext/io.rs @@ -8,6 +8,8 @@ use crate::sys; use crate::net; use crate::sys_common::{AsInner, FromInner, IntoInner}; +use wasi::wasi_unstable as wasi; + /// Raw file descriptors. pub type RawFd = u32; @@ -125,18 +127,18 @@ impl IntoRawFd for fs::File { impl AsRawFd for io::Stdin { fn as_raw_fd(&self) -> RawFd { - libc::STDIN_FILENO as u32 + wasi::STDIN_FD } } impl AsRawFd for io::Stdout { fn as_raw_fd(&self) -> RawFd { - libc::STDOUT_FILENO as u32 + wasi::STDOUT_FD } } impl AsRawFd for io::Stderr { fn as_raw_fd(&self) -> RawFd { - libc::STDERR_FILENO as u32 + wasi::STDERR_FD } } diff --git a/src/libstd/sys/wasi/fd.rs b/src/libstd/sys/wasi/fd.rs index 25692ec086801..93fe8add326c8 100644 --- a/src/libstd/sys/wasi/fd.rs +++ b/src/libstd/sys/wasi/fd.rs @@ -3,348 +3,240 @@ use crate::io::{self, IoSlice, IoSliceMut, SeekFrom}; use crate::mem; use crate::net::Shutdown; -use crate::sys::cvt_wasi; -use libc::{self, c_char, c_void}; +use wasi::wasi_unstable as wasi; #[derive(Debug)] pub struct WasiFd { - fd: libc::__wasi_fd_t, + fd: wasi::Fd, } -// FIXME: these should probably all be fancier structs, builders, enums, etc -pub type LookupFlags = u32; -pub type FdFlags = u16; -pub type Advice = u8; -pub type Rights = u64; -pub type Oflags = u16; -pub type DirCookie = u64; -pub type Timestamp = u64; -pub type FstFlags = u16; -pub type RiFlags = u16; -pub type RoFlags = u16; -pub type SiFlags = u16; - -fn iovec(a: &mut [IoSliceMut<'_>]) -> (*const libc::__wasi_iovec_t, usize) { +fn iovec(a: &mut [IoSliceMut<'_>]) -> &[wasi::IoVec] { assert_eq!( mem::size_of::>(), - mem::size_of::() + mem::size_of::() ); assert_eq!( mem::align_of::>(), - mem::align_of::() + mem::align_of::() ); - (a.as_ptr() as *const libc::__wasi_iovec_t, a.len()) + /// SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout + unsafe { mem::transmute(a) } } -fn ciovec(a: &[IoSlice<'_>]) -> (*const libc::__wasi_ciovec_t, usize) { +fn ciovec(a: &[IoSlice<'_>]) -> &[wasi::CIoVec] { assert_eq!( mem::size_of::>(), - mem::size_of::() + mem::size_of::() ); assert_eq!( mem::align_of::>(), - mem::align_of::() + mem::align_of::() ); - (a.as_ptr() as *const libc::__wasi_ciovec_t, a.len()) + /// SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout + unsafe { mem::transmute(a) } } impl WasiFd { - pub unsafe fn from_raw(fd: libc::__wasi_fd_t) -> WasiFd { + pub unsafe fn from_raw(fd: wasi::Fd) -> WasiFd { WasiFd { fd } } - pub fn into_raw(self) -> libc::__wasi_fd_t { + pub fn into_raw(self) -> wasi::Fd { let ret = self.fd; mem::forget(self); ret } - pub fn as_raw(&self) -> libc::__wasi_fd_t { + pub fn as_raw(&self) -> wasi::Fd { self.fd } pub fn datasync(&self) -> io::Result<()> { - cvt_wasi(unsafe { libc::__wasi_fd_datasync(self.fd) }) + wasi::fd_datasync(self.fd).map_err(From::from) } pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { - let mut read = 0; - let (ptr, len) = iovec(bufs); - cvt_wasi(unsafe { libc::__wasi_fd_pread(self.fd, ptr, len, offset, &mut read) })?; - Ok(read) + wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(From::from) } pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { - let mut read = 0; - let (ptr, len) = ciovec(bufs); - cvt_wasi(unsafe { libc::__wasi_fd_pwrite(self.fd, ptr, len, offset, &mut read) })?; - Ok(read) + wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(From::from) } pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - let mut read = 0; - let (ptr, len) = iovec(bufs); - cvt_wasi(unsafe { libc::__wasi_fd_read(self.fd, ptr, len, &mut read) })?; - Ok(read) + wasi::fd_read(self.fd, iovec(bufs)).map_err(From::from) } pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result { - let mut read = 0; - let (ptr, len) = ciovec(bufs); - cvt_wasi(unsafe { libc::__wasi_fd_write(self.fd, ptr, len, &mut read) })?; - Ok(read) + wasi::fd_write(self.fd, ciovec(bufs)).map_err(From::from) } pub fn seek(&self, pos: SeekFrom) -> io::Result { let (whence, offset) = match pos { - SeekFrom::Start(pos) => (libc::__WASI_WHENCE_SET, pos as i64), - SeekFrom::End(pos) => (libc::__WASI_WHENCE_END, pos), - SeekFrom::Current(pos) => (libc::__WASI_WHENCE_CUR, pos), + SeekFrom::Start(pos) => (wasi::WHENCE_SET, pos as i64), + SeekFrom::End(pos) => (wasi::WHENCE_END, pos), + SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos), }; - let mut pos = 0; - cvt_wasi(unsafe { libc::__wasi_fd_seek(self.fd, offset, whence, &mut pos) })?; - Ok(pos) + wasi::fd_seek(self.fd, offset, whence).map_err(From::from) } pub fn tell(&self) -> io::Result { - let mut pos = 0; - cvt_wasi(unsafe { libc::__wasi_fd_tell(self.fd, &mut pos) })?; - Ok(pos) + wasi::fd_tell(self.fd).map_err(From::from) } // FIXME: __wasi_fd_fdstat_get - pub fn set_flags(&self, flags: FdFlags) -> io::Result<()> { - cvt_wasi(unsafe { libc::__wasi_fd_fdstat_set_flags(self.fd, flags) }) + pub fn set_flags(&self, flags: wasi::FdFlags) -> io::Result<()> { + wasi::fd_fdstat_set_flags(self.fd, flags).map_err(From::from) } - pub fn set_rights(&self, base: Rights, inheriting: Rights) -> io::Result<()> { - cvt_wasi(unsafe { libc::__wasi_fd_fdstat_set_rights(self.fd, base, inheriting) }) + pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> { + wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(From::from) } pub fn sync(&self) -> io::Result<()> { - cvt_wasi(unsafe { libc::__wasi_fd_sync(self.fd) }) + wasi::fd_sync(self.fd).map_err(From::from) } - pub fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> { - cvt_wasi(unsafe { libc::__wasi_fd_advise(self.fd, offset, len, advice as u8) }) + pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> { + wasi::fd_advise(self.fd, offset, len, advice).map_err(From::from) } pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> { - cvt_wasi(unsafe { libc::__wasi_fd_allocate(self.fd, offset, len) }) + wasi::fd_allocate(self.fd, offset, len).map_err(From::from) } pub fn create_directory(&self, path: &[u8]) -> io::Result<()> { - cvt_wasi(unsafe { - libc::__wasi_path_create_directory(self.fd, path.as_ptr() as *const c_char, path.len()) - }) + wasi::path_create_directory(self.fd, path).map_err(From::from) } pub fn link( &self, - old_flags: LookupFlags, + old_flags: wasi::LookupFlags, old_path: &[u8], new_fd: &WasiFd, new_path: &[u8], ) -> io::Result<()> { - cvt_wasi(unsafe { - libc::__wasi_path_link( - self.fd, - old_flags, - old_path.as_ptr() as *const c_char, - old_path.len(), - new_fd.fd, - new_path.as_ptr() as *const c_char, - new_path.len(), - ) - }) + wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path) + .map_err(From::from) } pub fn open( &self, - dirflags: LookupFlags, + dirflags: wasi::LookupFlags, path: &[u8], - oflags: Oflags, - fs_rights_base: Rights, - fs_rights_inheriting: Rights, - fs_flags: FdFlags, + oflags: wasi::OFlags, + fs_rights_base: wasi::Rights, + fs_rights_inheriting: wasi::Rights, + fs_flags: wasi::FdFlags, ) -> io::Result { - unsafe { - let mut fd = 0; - cvt_wasi(libc::__wasi_path_open( - self.fd, - dirflags, - path.as_ptr() as *const c_char, - path.len(), - oflags, - fs_rights_base, - fs_rights_inheriting, - fs_flags, - &mut fd, - ))?; - Ok(WasiFd::from_raw(fd)) - } - } - - pub fn readdir(&self, buf: &mut [u8], cookie: DirCookie) -> io::Result { - let mut used = 0; - cvt_wasi(unsafe { - libc::__wasi_fd_readdir( - self.fd, - buf.as_mut_ptr() as *mut c_void, - buf.len(), - cookie, - &mut used, - ) - })?; - Ok(used) + let fd = wasi_path_open( + self.fd, + dirflags, + path, + oflags, + fs_rights_base, + fs_rights_inheriting, + fs_flags, + )?; + Ok(WasiFd::from_raw(fd)) + } + + pub fn readdir(&self, buf: &mut [u8], cookie: wasi::DirCookie) -> io::Result { + wasi::fd_readdir(self.fd, buf, cookie).map_err(From::from) } pub fn readlink(&self, path: &[u8], buf: &mut [u8]) -> io::Result { - let mut used = 0; - cvt_wasi(unsafe { - libc::__wasi_path_readlink( - self.fd, - path.as_ptr() as *const c_char, - path.len(), - buf.as_mut_ptr() as *mut c_char, - buf.len(), - &mut used, - ) - })?; - Ok(used) + wasi::path_readlink(self.fd, path, buf).map_err(From::from) } pub fn rename(&self, old_path: &[u8], new_fd: &WasiFd, new_path: &[u8]) -> io::Result<()> { - cvt_wasi(unsafe { - libc::__wasi_path_rename( - self.fd, - old_path.as_ptr() as *const c_char, - old_path.len(), - new_fd.fd, - new_path.as_ptr() as *const c_char, - new_path.len(), - ) - }) + wasi::path_rename(self.fd, old_path, new_fd.fd, new_path) + .map_err(From::from) } - pub fn filestat_get(&self, buf: *mut libc::__wasi_filestat_t) -> io::Result<()> { - cvt_wasi(unsafe { libc::__wasi_fd_filestat_get(self.fd, buf) }) + pub fn filestat_get(&self) -> io::Result { + wasi::fd_filestat_get(self.fd, buf).map_err(From::from) } pub fn filestat_set_times( &self, - atim: Timestamp, - mtim: Timestamp, - fstflags: FstFlags, + atim: wasi::Timestamp, + mtim: wasi::Timestamp, + fstflags: wasi::FstFlags, ) -> io::Result<()> { - cvt_wasi(unsafe { libc::__wasi_fd_filestat_set_times(self.fd, atim, mtim, fstflags) }) + wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags) + .map_err(From::from) } pub fn filestat_set_size(&self, size: u64) -> io::Result<()> { - cvt_wasi(unsafe { libc::__wasi_fd_filestat_set_size(self.fd, size) }) + wasi::fd_filestat_set_size(self.fd, size).map_err(From::from) } pub fn path_filestat_get( &self, - flags: LookupFlags, + flags: wasi::LookupFlags, path: &[u8], - buf: *mut libc::__wasi_filestat_t, - ) -> io::Result<()> { - cvt_wasi(unsafe { - libc::__wasi_path_filestat_get( - self.fd, - flags, - path.as_ptr() as *const c_char, - path.len(), - buf, - ) - }) + ) -> io::Result { + wasi::path_filestat_get(self.fd, flags, path).map_err(From::from) } pub fn path_filestat_set_times( &self, - flags: LookupFlags, + flags: wasi::LookupFlags, path: &[u8], - atim: Timestamp, - mtim: Timestamp, - fstflags: FstFlags, + atim: wasi::Timestamp, + mtim: wasi::Timestamp, + fstflags: wasi::FstFlags, ) -> io::Result<()> { - cvt_wasi(unsafe { - libc::__wasi_path_filestat_set_times( - self.fd, - flags, - path.as_ptr() as *const c_char, - path.len(), - atim, - mtim, - fstflags, - ) - }) + wasi::path_filestat_set_times( + self.fd, + flags, + path, + atim, + mtim, + fstflags, + ).map_err(From::from) } pub fn symlink(&self, old_path: &[u8], new_path: &[u8]) -> io::Result<()> { - cvt_wasi(unsafe { - libc::__wasi_path_symlink( - old_path.as_ptr() as *const c_char, - old_path.len(), - self.fd, - new_path.as_ptr() as *const c_char, - new_path.len(), - ) - }) + wasi::path_symlink(old_path, self.fd, new_path).map_err(From::from) } pub fn unlink_file(&self, path: &[u8]) -> io::Result<()> { - cvt_wasi(unsafe { - libc::__wasi_path_unlink_file(self.fd, path.as_ptr() as *const c_char, path.len()) - }) + wasi::path_unlink_file(self.fd, path).map_err(From::from) } pub fn remove_directory(&self, path: &[u8]) -> io::Result<()> { - cvt_wasi(unsafe { - libc::__wasi_path_remove_directory(self.fd, path.as_ptr() as *const c_char, path.len()) - }) + wasi::path_remove_directory(self.fd, path).map_err(From::from) } pub fn sock_recv( &self, ri_data: &mut [IoSliceMut<'_>], - ri_flags: RiFlags, - ) -> io::Result<(usize, RoFlags)> { - let mut ro_datalen = 0; - let mut ro_flags = 0; - let (ptr, len) = iovec(ri_data); - cvt_wasi(unsafe { - libc::__wasi_sock_recv(self.fd, ptr, len, ri_flags, &mut ro_datalen, &mut ro_flags) - })?; - Ok((ro_datalen, ro_flags)) + ri_flags: wasi::RiFlags, + ) -> io::Result<(usize, wasi::RoFlags)> { + wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(From::from) } - pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: SiFlags) -> io::Result { - let mut so_datalen = 0; - let (ptr, len) = ciovec(si_data); - cvt_wasi(unsafe { libc::__wasi_sock_send(self.fd, ptr, len, si_flags, &mut so_datalen) })?; - Ok(so_datalen) + pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::SiFlags) -> io::Result { + wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(From::from) } pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> { let how = match how { - Shutdown::Read => libc::__WASI_SHUT_RD, - Shutdown::Write => libc::__WASI_SHUT_WR, - Shutdown::Both => libc::__WASI_SHUT_WR | libc::__WASI_SHUT_RD, + Shutdown::Read => WASI::SHUT_RD, + Shutdown::Write => WASI::SHUT_WR, + Shutdown::Both => WASI::SHUT_WR | WASI::SHUT_RD, }; - cvt_wasi(unsafe { libc::__wasi_sock_shutdown(self.fd, how) })?; - Ok(()) + wasi::sock_shutdown(self.fd, how).map_err(From::from) } } impl Drop for WasiFd { fn drop(&mut self) { - unsafe { - // FIXME: can we handle the return code here even though we can't on - // unix? - libc::__wasi_fd_close(self.fd); - } + // FIXME: can we handle the return code here even though we can't on + // unix? + let _ = wasi::fd_close(self.fd); } } diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs index 172c60385b317..f23ecfc2bcd22 100644 --- a/src/libstd/sys/wasi/fs.rs +++ b/src/libstd/sys/wasi/fs.rs @@ -15,13 +15,15 @@ use crate::sys_common::FromInner; pub use crate::sys_common::fs::copy; pub use crate::sys_common::fs::remove_dir_all; +use wasi::wasi_unstable as wasi; + pub struct File { fd: WasiFd, } #[derive(Clone)] pub struct FileAttr { - meta: libc::__wasi_filestat_t, + meta: wasi::FileStat, } pub struct ReadDir { @@ -38,7 +40,7 @@ struct ReadDirInner { } pub struct DirEntry { - meta: libc::__wasi_dirent_t, + meta: wasi::Dirent, name: Vec, inner: Arc, } @@ -47,11 +49,11 @@ pub struct DirEntry { pub struct OpenOptions { read: bool, write: bool, - dirflags: libc::__wasi_lookupflags_t, - fdflags: libc::__wasi_fdflags_t, - oflags: libc::__wasi_oflags_t, - rights_base: Option, - rights_inheriting: Option, + dirflags: wasi::LookupFlags, + fdflags: wasi::FdFlags, + oflags: wasi::OFlags, + rights_base: Option, + rights_inheriting: Option, } #[derive(Clone, PartialEq, Eq, Debug)] @@ -61,7 +63,7 @@ pub struct FilePermissions { #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)] pub struct FileType { - bits: libc::__wasi_filetype_t, + bits: wasi::FileType, } #[derive(Debug)] @@ -101,7 +103,7 @@ impl FileAttr { Ok(SystemTime::from_wasi_timestamp(self.meta.st_ctim)) } - pub fn as_wasi(&self) -> &libc::__wasi_filestat_t { + pub fn as_wasi(&self) -> &wasi::FileStat { &self.meta } } @@ -118,18 +120,18 @@ impl FilePermissions { impl FileType { pub fn is_dir(&self) -> bool { - self.bits == libc::__WASI_FILETYPE_DIRECTORY + self.bits == wasi::FILETYPE_DIRECTORY } pub fn is_file(&self) -> bool { - self.bits == libc::__WASI_FILETYPE_REGULAR_FILE + self.bits == wasi::FILETYPE_REGULAR_FILE } pub fn is_symlink(&self) -> bool { - self.bits == libc::__WASI_FILETYPE_SYMBOLIC_LINK + self.bits == wasi::FILETYPE_SYMBOLIC_LINK } - pub fn bits(&self) -> libc::__wasi_filetype_t { + pub fn bits(&self) -> wasi::FileType { self.bits } } @@ -173,7 +175,7 @@ impl Iterator for ReadDir { // must have been truncated at the end of the buffer, so reset our // offset so we can go back and reread into the buffer, picking up // where we last left off. - let dirent_size = mem::size_of::(); + let dirent_size = mem::size_of::(); if data.len() < dirent_size { assert!(self.cookie.is_some()); assert!(self.buf.len() >= dirent_size); @@ -182,7 +184,7 @@ impl Iterator for ReadDir { } let (dirent, data) = data.split_at(dirent_size); let dirent = - unsafe { ptr::read_unaligned(dirent.as_ptr() as *const libc::__wasi_dirent_t) }; + unsafe { ptr::read_unaligned(dirent.as_ptr() as *const wasi::Dirent) }; // If the file name was truncated, then we need to reinvoke // `readdir` so we truncate our buffer to start over and reread this @@ -241,7 +243,7 @@ impl DirEntry { }) } - pub fn ino(&self) -> libc::__wasi_inode_t { + pub fn ino(&self) -> wasi::Inode { self.meta.d_ino } } @@ -249,7 +251,7 @@ impl DirEntry { impl OpenOptions { pub fn new() -> OpenOptions { let mut base = OpenOptions::default(); - base.dirflags = libc::__WASI_LOOKUP_SYMLINK_FOLLOW; + base.dirflags = wasi::LOOKUP_SYMLINK_FOLLOW; return base; } @@ -262,23 +264,23 @@ impl OpenOptions { } pub fn truncate(&mut self, truncate: bool) { - self.oflag(libc::__WASI_O_TRUNC, truncate); + self.oflag(wasi::O_TRUNC, truncate); } pub fn create(&mut self, create: bool) { - self.oflag(libc::__WASI_O_CREAT, create); + self.oflag(wasi::O_CREAT, create); } pub fn create_new(&mut self, create_new: bool) { - self.oflag(libc::__WASI_O_EXCL, create_new); - self.oflag(libc::__WASI_O_CREAT, create_new); + self.oflag(wasi::O_EXCL, create_new); + self.oflag(wasi::O_CREAT, create_new); } pub fn directory(&mut self, directory: bool) { - self.oflag(libc::__WASI_O_DIRECTORY, directory); + self.oflag(wasi::O_DIRECTORY, directory); } - fn oflag(&mut self, bit: libc::__wasi_oflags_t, set: bool) { + fn oflag(&mut self, bit: wasi::OFlags, set: bool) { if set { self.oflags |= bit; } else { @@ -287,26 +289,26 @@ impl OpenOptions { } pub fn append(&mut self, set: bool) { - self.fdflag(libc::__WASI_FDFLAG_APPEND, set); + self.fdflag(wasi::FDFLAG_APPEND, set); } pub fn dsync(&mut self, set: bool) { - self.fdflag(libc::__WASI_FDFLAG_DSYNC, set); + self.fdflag(wasi::FDFLAG_DSYNC, set); } pub fn nonblock(&mut self, set: bool) { - self.fdflag(libc::__WASI_FDFLAG_NONBLOCK, set); + self.fdflag(wasi::FDFLAG_NONBLOCK, set); } pub fn rsync(&mut self, set: bool) { - self.fdflag(libc::__WASI_FDFLAG_RSYNC, set); + self.fdflag(wasi::FDFLAG_RSYNC, set); } pub fn sync(&mut self, set: bool) { - self.fdflag(libc::__WASI_FDFLAG_SYNC, set); + self.fdflag(wasi::FDFLAG_SYNC, set); } - fn fdflag(&mut self, bit: libc::__wasi_fdflags_t, set: bool) { + fn fdflag(&mut self, bit: wasi::FdFlags, set: bool) { if set { self.fdflags |= bit; } else { @@ -314,15 +316,15 @@ impl OpenOptions { } } - pub fn fs_rights_base(&mut self, rights: libc::__wasi_rights_t) { + pub fn fs_rights_base(&mut self, rights: wasi::Rights) { self.rights_base = Some(rights); } - pub fn fs_rights_inheriting(&mut self, rights: libc::__wasi_rights_t) { + pub fn fs_rights_inheriting(&mut self, rights: wasi::Rights) { self.rights_inheriting = Some(rights); } - fn rights_base(&self) -> libc::__wasi_rights_t { + fn rights_base(&self) -> wasi::Rights { if let Some(rights) = self.rights_base { return rights; } @@ -334,52 +336,52 @@ impl OpenOptions { // based on that. let mut base = 0; if self.read { - base |= libc::__WASI_RIGHT_FD_READ; - base |= libc::__WASI_RIGHT_FD_READDIR; + base |= wasi::RIGHT_FD_READ; + base |= wasi::RIGHT_FD_READDIR; } if self.write { - base |= libc::__WASI_RIGHT_FD_WRITE; - base |= libc::__WASI_RIGHT_FD_DATASYNC; - base |= libc::__WASI_RIGHT_FD_ALLOCATE; - base |= libc::__WASI_RIGHT_FD_FILESTAT_SET_SIZE; + base |= wasi::RIGHT_FD_WRITE; + base |= wasi::RIGHT_FD_DATASYNC; + base |= wasi::RIGHT_FD_ALLOCATE; + base |= wasi::RIGHT_FD_FILESTAT_SET_SIZE; } // FIXME: some of these should probably be read-only or write-only... - base |= libc::__WASI_RIGHT_FD_ADVISE; - base |= libc::__WASI_RIGHT_FD_FDSTAT_SET_FLAGS; - base |= libc::__WASI_RIGHT_FD_FILESTAT_SET_TIMES; - base |= libc::__WASI_RIGHT_FD_SEEK; - base |= libc::__WASI_RIGHT_FD_SYNC; - base |= libc::__WASI_RIGHT_FD_TELL; - base |= libc::__WASI_RIGHT_PATH_CREATE_DIRECTORY; - base |= libc::__WASI_RIGHT_PATH_CREATE_FILE; - base |= libc::__WASI_RIGHT_PATH_FILESTAT_GET; - base |= libc::__WASI_RIGHT_PATH_LINK_SOURCE; - base |= libc::__WASI_RIGHT_PATH_LINK_TARGET; - base |= libc::__WASI_RIGHT_PATH_OPEN; - base |= libc::__WASI_RIGHT_PATH_READLINK; - base |= libc::__WASI_RIGHT_PATH_REMOVE_DIRECTORY; - base |= libc::__WASI_RIGHT_PATH_RENAME_SOURCE; - base |= libc::__WASI_RIGHT_PATH_RENAME_TARGET; - base |= libc::__WASI_RIGHT_PATH_SYMLINK; - base |= libc::__WASI_RIGHT_PATH_UNLINK_FILE; - base |= libc::__WASI_RIGHT_POLL_FD_READWRITE; + base |= wasi::RIGHT_FD_ADVISE; + base |= wasi::RIGHT_FD_FDSTAT_SET_FLAGS; + base |= wasi::RIGHT_FD_FILESTAT_SET_TIMES; + base |= wasi::RIGHT_FD_SEEK; + base |= wasi::RIGHT_FD_SYNC; + base |= wasi::RIGHT_FD_TELL; + base |= wasi::RIGHT_PATH_CREATE_DIRECTORY; + base |= wasi::RIGHT_PATH_CREATE_FILE; + base |= wasi::RIGHT_PATH_FILESTAT_GET; + base |= wasi::RIGHT_PATH_LINK_SOURCE; + base |= wasi::RIGHT_PATH_LINK_TARGET; + base |= wasi::RIGHT_PATH_OPEN; + base |= wasi::RIGHT_PATH_READLINK; + base |= wasi::RIGHT_PATH_REMOVE_DIRECTORY; + base |= wasi::RIGHT_PATH_RENAME_SOURCE; + base |= wasi::RIGHT_PATH_RENAME_TARGET; + base |= wasi::RIGHT_PATH_SYMLINK; + base |= wasi::RIGHT_PATH_UNLINK_FILE; + base |= wasi::RIGHT_POLL_FD_READWRITE; return base; } - fn rights_inheriting(&self) -> libc::__wasi_rights_t { + fn rights_inheriting(&self) -> wasi::Rights { self.rights_inheriting.unwrap_or_else(|| self.rights_base()) } - pub fn lookup_flags(&mut self, flags: libc::__wasi_lookupflags_t) { + pub fn lookup_flags(&mut self, flags: wasi::LookupFlags) { self.dirflags = flags; } } impl File { pub fn open(path: &Path, opts: &OpenOptions) -> io::Result { - let (dir, file) = open_parent(path, libc::__WASI_RIGHT_PATH_OPEN)?; + let (dir, file) = open_parent(path, wasi::RIGHT_PATH_OPEN)?; open_at(&dir, &file, opts) } @@ -388,14 +390,12 @@ impl File { } pub fn file_attr(&self) -> io::Result { - let mut ret = FileAttr::zero(); - self.fd.filestat_get(&mut ret.meta)?; - Ok(ret) + self.fd.filestat_get().map_ok(|meta| FileAttr { meta }) } pub fn metadata_at( &self, - flags: libc::__wasi_lookupflags_t, + flags: wasi::LookupFlags, path: &Path, ) -> io::Result { metadata_at(&self.fd, flags, path) @@ -477,7 +477,7 @@ impl DirBuilder { } pub fn mkdir(&self, p: &Path) -> io::Result<()> { - let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_CREATE_DIRECTORY)?; + let (dir, file) = open_parent(p, wasi::RIGHT_PATH_CREATE_DIRECTORY)?; dir.create_directory(file.as_os_str().as_bytes()) } } @@ -508,13 +508,13 @@ pub fn readdir(p: &Path) -> io::Result { } pub fn unlink(p: &Path) -> io::Result<()> { - let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_UNLINK_FILE)?; + let (dir, file) = open_parent(p, wasi::RIGHT_PATH_UNLINK_FILE)?; dir.unlink_file(file.as_os_str().as_bytes()) } pub fn rename(old: &Path, new: &Path) -> io::Result<()> { - let (old, old_file) = open_parent(old, libc::__WASI_RIGHT_PATH_RENAME_SOURCE)?; - let (new, new_file) = open_parent(new, libc::__WASI_RIGHT_PATH_RENAME_TARGET)?; + let (old, old_file) = open_parent(old, wasi::RIGHT_PATH_RENAME_SOURCE)?; + let (new, new_file) = open_parent(new, wasi::RIGHT_PATH_RENAME_TARGET)?; old.rename( old_file.as_os_str().as_bytes(), &new, @@ -529,12 +529,12 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> { } pub fn rmdir(p: &Path) -> io::Result<()> { - let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_REMOVE_DIRECTORY)?; + let (dir, file) = open_parent(p, wasi::RIGHT_PATH_REMOVE_DIRECTORY)?; dir.remove_directory(file.as_os_str().as_bytes()) } pub fn readlink(p: &Path) -> io::Result { - let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_READLINK)?; + let (dir, file) = open_parent(p, wasi::RIGHT_PATH_READLINK)?; read_link(&dir, &file) } @@ -570,15 +570,15 @@ fn read_link(fd: &WasiFd, file: &Path) -> io::Result { } pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> { - let (dst, dst_file) = open_parent(dst, libc::__WASI_RIGHT_PATH_SYMLINK)?; + let (dst, dst_file) = open_parent(dst, wasi::RIGHT_PATH_SYMLINK)?; dst.symlink(src.as_os_str().as_bytes(), dst_file.as_os_str().as_bytes()) } pub fn link(src: &Path, dst: &Path) -> io::Result<()> { - let (src, src_file) = open_parent(src, libc::__WASI_RIGHT_PATH_LINK_SOURCE)?; - let (dst, dst_file) = open_parent(dst, libc::__WASI_RIGHT_PATH_LINK_TARGET)?; + let (src, src_file) = open_parent(src, wasi::RIGHT_PATH_LINK_SOURCE)?; + let (dst, dst_file) = open_parent(dst, wasi::RIGHT_PATH_LINK_TARGET)?; src.link( - libc::__WASI_LOOKUP_SYMLINK_FOLLOW, + wasi::LOOKUP_SYMLINK_FOLLOW, src_file.as_os_str().as_bytes(), &dst, dst_file.as_os_str().as_bytes(), @@ -586,23 +586,22 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> { } pub fn stat(p: &Path) -> io::Result { - let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_FILESTAT_GET)?; - metadata_at(&dir, libc::__WASI_LOOKUP_SYMLINK_FOLLOW, &file) + let (dir, file) = open_parent(p, wasi::RIGHT_PATH_FILESTAT_GET)?; + metadata_at(&dir, wasi::LOOKUP_SYMLINK_FOLLOW, &file) } pub fn lstat(p: &Path) -> io::Result { - let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_FILESTAT_GET)?; + let (dir, file) = open_parent(p, wasi::RIGHT_PATH_FILESTAT_GET)?; metadata_at(&dir, 0, &file) } fn metadata_at( fd: &WasiFd, - flags: libc::__wasi_lookupflags_t, + flags: wasi::LookupFlags, path: &Path, ) -> io::Result { - let mut ret = FileAttr::zero(); - fd.path_filestat_get(flags, path.as_os_str().as_bytes(), &mut ret.meta)?; - Ok(ret) + fd.path_filestat_get(flags, path.as_os_str().as_bytes()) + .map_ok(|meta| FileAttr { meta }) } pub fn canonicalize(_p: &Path) -> io::Result { @@ -652,12 +651,12 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result { /// to any preopened file descriptor. fn open_parent( p: &Path, - rights: libc::__wasi_rights_t, + rights: wasi::Rights, ) -> io::Result<(ManuallyDrop, PathBuf)> { let p = CString::new(p.as_os_str().as_bytes())?; unsafe { let mut ret = ptr::null(); - let fd = __wasilibc_find_relpath(p.as_ptr(), rights, 0, &mut ret); + let fd = libc::__wasilibc_find_relpath(p.as_ptr(), rights, 0, &mut ret); if fd == -1 { let msg = format!( "failed to find a preopened file descriptor \ @@ -677,15 +676,4 @@ fn open_parent( return Ok((ManuallyDrop::new(WasiFd::from_raw(fd as u32)), path)); } - - // FIXME(rust-lang/libc#1314) use the `libc` crate for this when the API - // there is published - extern "C" { - pub fn __wasilibc_find_relpath( - path: *const libc::c_char, - rights_base: libc::__wasi_rights_t, - rights_inheriting: libc::__wasi_rights_t, - relative_path: *mut *const libc::c_char, - ) -> libc::c_int; - } } diff --git a/src/libstd/sys/wasi/io.rs b/src/libstd/sys/wasi/io.rs index ffecca5d1b6ff..ebea3a03e439f 100644 --- a/src/libstd/sys/wasi/io.rs +++ b/src/libstd/sys/wasi/io.rs @@ -1,11 +1,12 @@ use crate::marker::PhantomData; use crate::slice; -use libc::{__wasi_ciovec_t, __wasi_iovec_t, c_void}; +use wasi::wasi_unstable as wasi; +use core::ffi::c_void; #[repr(transparent)] pub struct IoSlice<'a> { - vec: __wasi_ciovec_t, + vec: wasi::CIoVec, _p: PhantomData<&'a [u8]>, } @@ -13,7 +14,7 @@ impl<'a> IoSlice<'a> { #[inline] pub fn new(buf: &'a [u8]) -> IoSlice<'a> { IoSlice { - vec: __wasi_ciovec_t { + vec: wasi::CIoVec { buf: buf.as_ptr() as *const c_void, buf_len: buf.len(), }, @@ -43,7 +44,7 @@ impl<'a> IoSlice<'a> { #[repr(transparent)] pub struct IoSliceMut<'a> { - vec: __wasi_iovec_t, + vec: wasi::IoVec, _p: PhantomData<&'a mut [u8]>, } @@ -51,7 +52,7 @@ impl<'a> IoSliceMut<'a> { #[inline] pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { IoSliceMut { - vec: __wasi_iovec_t { + vec: wasi::IoVec { buf: buf.as_mut_ptr() as *mut c_void, buf_len: buf.len() }, diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index f842869e08ee6..0a16c29e5af53 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -14,10 +14,10 @@ //! compiling for wasm. That way it's a compile time error for something that's //! guaranteed to be a runtime error! -use libc; -use crate::io::{Error, ErrorKind}; +use crate::io; use crate::mem; use crate::os::raw::c_char; +use wasi::wasi_unstable as wasi; pub mod alloc; pub mod args; @@ -60,12 +60,12 @@ pub fn unsupported() -> crate::io::Result { Err(unsupported_err()) } -pub fn unsupported_err() -> Error { - Error::new(ErrorKind::Other, "operation not supported on wasm yet") +pub fn unsupported_err() -> io::Error { + io::Error::new(io::ErrorKind::Other, "operation not supported on wasm yet") } -pub fn decode_error_kind(_code: i32) -> ErrorKind { - ErrorKind::Other +pub fn decode_error_kind(_code: i32) -> io::ErrorKind { + io::ErrorKind::Other } // This enum is used as the storage for a bunch of types which can't actually @@ -83,15 +83,18 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize { } pub unsafe fn abort_internal() -> ! { - libc::abort() + wasi::proc_exit(127) } pub fn hashmap_random_keys() -> (u64, u64) { let mut ret = (0u64, 0u64); unsafe { - let base = &mut ret as *mut (u64, u64) as *mut libc::c_void; + let base = &mut ret as *mut (u64, u64) as *mut core::ffi::c_void; let len = mem::size_of_val(&ret); - cvt_wasi(libc::__wasi_random_get(base, len)).unwrap(); + let ret = wasi::raw::__wasi_random_get(base, len); + if ret != 0 { + panic!("__wasi_random_get failure") + } } return ret } @@ -113,16 +116,14 @@ impl_is_minus_one! { i8 i16 i32 i64 isize } pub fn cvt(t: T) -> crate::io::Result { if t.is_minus_one() { - Err(Error::last_os_error()) + Err(io::Error::last_os_error()) } else { Ok(t) } } -pub fn cvt_wasi(r: u16) -> crate::io::Result<()> { - if r != libc::__WASI_ESUCCESS { - Err(Error::from_raw_os_error(r as i32)) - } else { - Ok(()) +impl From for io::Error { + fn from(err: wasi::Error) -> Self { + Self::from_raw_os_error(err as i32) } } diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 822ea02a11b89..026ff71de345b 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -12,6 +12,8 @@ use crate::sys::memchr; use crate::sys::{cvt, unsupported, Void}; use crate::vec; +use wasi::wasi_unstable as wasi; + #[cfg(not(target_feature = "atomics"))] pub unsafe fn env_lock() -> impl Any { // No need for a lock if we're single-threaded, but this function will need @@ -19,29 +21,11 @@ pub unsafe fn env_lock() -> impl Any { } pub fn errno() -> i32 { - extern { - #[thread_local] - static errno: libc::c_int; - } - - unsafe { errno as i32 } + panic!("unsupported") } pub fn error_string(errno: i32) -> String { - extern { - fn strerror_r(errnum: libc::c_int, buf: *mut libc::c_char, - buflen: libc::size_t) -> libc::c_int; - } - - let mut buf = [0 as libc::c_char; 1024]; - - let p = buf.as_mut_ptr(); - unsafe { - if strerror_r(errno as libc::c_int, p, buf.len()) < 0 { - panic!("strerror_r failure"); - } - str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned() - } + wasi::error_string(errno).to_string() } pub fn getcwd() -> io::Result { @@ -105,6 +89,7 @@ impl Iterator for Env { pub fn env() -> Env { unsafe { let _guard = env_lock(); + // FIXME: replace with wasi::environ_get let mut environ = libc::environ; let mut result = Vec::new(); while environ != ptr::null_mut() && *environ != ptr::null_mut() { @@ -174,9 +159,7 @@ pub fn home_dir() -> Option { } pub fn exit(code: i32) -> ! { - unsafe { - libc::exit(code) - } + unsafe { wasi::proc_exit(code as u32) } } pub fn getpid() -> u32 { diff --git a/src/libstd/sys/wasi/stdio.rs b/src/libstd/sys/wasi/stdio.rs index 2bf8d803c01bb..dc6a6ef375a1c 100644 --- a/src/libstd/sys/wasi/stdio.rs +++ b/src/libstd/sys/wasi/stdio.rs @@ -1,8 +1,9 @@ use crate::io::{self, IoSlice, IoSliceMut}; -use crate::libc; use crate::mem::ManuallyDrop; use crate::sys::fd::WasiFd; +use wasi::wasi_unstable as wasi; + pub struct Stdin; pub struct Stdout; pub struct Stderr; @@ -17,7 +18,7 @@ impl Stdin { } pub fn read_vectored(&self, data: &mut [IoSliceMut<'_>]) -> io::Result { - ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) }) + ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDIN_FD) }) .read(data) } } @@ -32,7 +33,7 @@ impl Stdout { } pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { - ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDOUT_FILENO as u32) }) + ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDOUT_FD) }) .write(data) } @@ -51,7 +52,7 @@ impl Stderr { } pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { - ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDERR_FILENO as u32) }) + ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDERR_FD) }) .write(data) } @@ -73,7 +74,7 @@ impl io::Write for Stderr { pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE; pub fn is_ebadf(err: &io::Error) -> bool { - err.raw_os_error() == Some(libc::__WASI_EBADF as i32) + err.raw_os_error() == Some(wasi::EBADF as i32) } pub fn panic_output() -> Option { diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index 5e69e4d948fee..9e0726432d9c4 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -19,8 +19,8 @@ impl Thread { } pub fn yield_now() { - let ret = unsafe { libc::__wasi_sched_yield() }; - debug_assert_eq!(ret, 0); + let ret = wasi::sched_yield(); + debug_assert_eq!(ret, Ok(())); } pub fn set_name(_name: &CStr) { diff --git a/src/libstd/sys/wasi/time.rs b/src/libstd/sys/wasi/time.rs index 3f14c80928c67..4c89a1781b9ef 100644 --- a/src/libstd/sys/wasi/time.rs +++ b/src/libstd/sys/wasi/time.rs @@ -1,7 +1,6 @@ use crate::time::Duration; use crate::mem; -use crate::sys::cvt_wasi; -use libc; +use wasi::wasi_unstable as wasi; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] pub struct Instant(Duration); @@ -12,23 +11,19 @@ pub struct SystemTime(Duration); pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0)); fn current_time(clock: u32) -> Duration { - unsafe { - let mut ts = mem::zeroed(); - cvt_wasi(libc::__wasi_clock_time_get( - clock, - 1, // precision... seems ignored though? - &mut ts, - )).unwrap(); - Duration::new( - (ts / 1_000_000_000) as u64, - (ts % 1_000_000_000) as u32, - ) - } + let ts = wasi::clock_time_get( + clock, + 1, // precision... seems ignored though? + ).unwrap(); + Duration::new( + (ts / 1_000_000_000) as u64, + (ts % 1_000_000_000) as u32, + ) } impl Instant { pub fn now() -> Instant { - Instant(current_time(libc::__WASI_CLOCK_MONOTONIC)) + Instant(current_time(wasi::CLOCK_MONOTONIC)) } pub const fn zero() -> Instant { @@ -54,10 +49,10 @@ impl Instant { impl SystemTime { pub fn now() -> SystemTime { - SystemTime(current_time(libc::__WASI_CLOCK_REALTIME)) + SystemTime(current_time(wasi::CLOCK_REALTIME)) } - pub fn from_wasi_timestamp(ts: libc::__wasi_timestamp_t) -> SystemTime { + pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime { SystemTime(Duration::from_nanos(ts)) } From 23cc850ff18652c7b75fa423f9dfff5526a239a7 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 10:44:08 +0300 Subject: [PATCH 002/462] return 0 from errno function --- src/libstd/sys/wasi/os.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 026ff71de345b..8411878eeccd9 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -21,7 +21,7 @@ pub unsafe fn env_lock() -> impl Any { } pub fn errno() -> i32 { - panic!("unsupported") + 0 } pub fn error_string(errno: i32) -> String { From cb52065d55e5ba1383aa155880a5e6661e6415a7 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 13:31:41 +0300 Subject: [PATCH 003/462] replace libc::nanosleep with wasi::poll_oneoff --- src/libstd/sys/wasi/thread.rs | 37 ++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index 9e0726432d9c4..eedc584dde500 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -1,7 +1,7 @@ use crate::cmp; use crate::ffi::CStr; use crate::io; -use crate::sys::cvt; +use crate::mem; use crate::sys::{unsupported, Void}; use crate::time::Duration; use libc; @@ -28,19 +28,28 @@ impl Thread { } pub fn sleep(dur: Duration) { - let mut secs = dur.as_secs(); - let mut nsecs = dur.subsec_nanos() as i32; - - unsafe { - while secs > 0 || nsecs > 0 { - let mut ts = libc::timespec { - tv_sec: cmp::min(libc::time_t::max_value() as u64, secs) as libc::time_t, - tv_nsec: nsecs, - }; - secs -= ts.tv_sec as u64; - cvt(libc::nanosleep(&ts, &mut ts)).unwrap(); - nsecs = 0; - } + let nanos = dur.as_nanos(); + assert!(nanos <= u64::max_value() as u128); + + let clock = wasi::raw::__wasi_subscription_u_clock_t { + identifier: 0, + clock_id: wasi::CLOCK_MONOTONIC, + timeout: nanos as u64, + precision: 0, + flags: 0, + }; + + let in_ = [wasi::Subscription { + userdata: 0, + type_: wasi::EVENTTYPE_CLOCK, + u: wasi::raw::__wasi_subscription_u { clock: clock }, + }]; + let mut out: [wasi::Event; 1] = [unsafe { mem::zeroed() }]; + let n = wasi::poll_oneoff(&in_, &mut out).unwrap(); + let wasi::Event { userdata, error, type_, .. } = out[0]; + match (n, userdata, error) { + (1, 0, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} + _ => panic!("thread::sleep(): unexpected result of poll_oneof"), } } From 75a553fa27ffa293a21be5c5138b2b9fd69adfd2 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 13:50:22 +0300 Subject: [PATCH 004/462] remove to_string --- src/libstd/sys/wasi/os.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 8411878eeccd9..091ff3480bf85 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -25,7 +25,7 @@ pub fn errno() -> i32 { } pub fn error_string(errno: i32) -> String { - wasi::error_string(errno).to_string() + wasi::error_string(errno) } pub fn getcwd() -> io::Result { From 7a4f0aece871f9850f83db4760a6fea4f595dc8d Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 14:54:37 +0300 Subject: [PATCH 005/462] use wasi::get_args --- src/libstd/sys/wasi/args.rs | 42 +++++-------------------------------- 1 file changed, 5 insertions(+), 37 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index 679bb1b2cbe30..e2fe0548f1266 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -13,47 +13,15 @@ pub unsafe fn cleanup() { } pub struct Args { - iter: vec::IntoIter, + iter: vec::IntoIter>, _dont_send_or_sync_me: PhantomData<*mut ()>, } /// Returns the command line arguments pub fn args() -> Args { - maybe_args().unwrap_or_else(|_| { - Args { - iter: Vec::new().into_iter(), - _dont_send_or_sync_me: PhantomData - } - }) -} - -fn cvt_wasi(r: u16) -> crate::io::Result<()> { - if r != 0 { - Err(Error::from_raw_os_error(r as i32)) - } else { - Ok(()) - } -} - -fn maybe_args() -> io::Result { - // FIXME: replace with safe functions - use wasi::wasi_unstable::raw::{__wasi_args_sizes_get, __wasi_args_get}; - unsafe { - let (mut argc, mut argv_buf_size) = (0, 0); - cvt_wasi(__wasi_args_sizes_get(&mut argc, &mut argv_buf_size))?; - - let mut argc = vec![core::ptr::null_mut::(); argc]; - let mut argv_buf = vec![0; argv_buf_size]; - cvt_wasi(__wasi_args_get(argc.as_mut_ptr(), argv_buf.as_mut_ptr()))?; - - let args = argc.into_iter() - .map(|ptr| CStr::from_ptr(ptr).to_bytes().to_vec()) - .map(|bytes| OsString::from_vec(bytes)) - .collect::>(); - Ok(Args { - iter: args.into_iter(), - _dont_send_or_sync_me: PhantomData, - }) + Args { + iter: wasi::get_args().unwrap_or(Vec::new()), + _dont_send_or_sync_me: PhantomData } } @@ -66,7 +34,7 @@ impl Args { impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { - self.iter.next() + self.iter.next().map(OsString::from_vec) } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() From 52d2871e10202279b7039f4ad6d4485093fb99cc Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 15:18:02 +0300 Subject: [PATCH 006/462] use wasi::get_environ --- src/libstd/sys/wasi/args.rs | 1 - src/libstd/sys/wasi/os.rs | 46 ++++++++++++++----------------------- 2 files changed, 17 insertions(+), 30 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index e2fe0548f1266..23ab2051bf6f6 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -1,6 +1,5 @@ use crate::ffi::CStr; use crate::io; -use crate::sys::cvt_wasi; use crate::ffi::OsString; use crate::marker::PhantomData; use crate::os::wasi::ffi::OsStringExt; diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 091ff3480bf85..65c80c838dc82 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -75,45 +75,33 @@ pub fn current_exe() -> io::Result { } pub struct Env { - iter: vec::IntoIter<(OsString, OsString)>, + iter: Vec>, _dont_send_or_sync_me: PhantomData<*mut ()>, } impl Iterator for Env { type Item = (OsString, OsString); - fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() } + fn next(&mut self) -> Option<(OsString, OsString)> { + self.iter.next().and_then(|input| { + // See src/libstd/sys/unix/os.rs, same as that + if input.is_empty() { + return None; + } + let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1); + pos.map(|p| ( + OsStringExt::from_vec(input[..p].to_vec()), + OsStringExt::from_vec(input[p+1..].to_vec()), + )) + }) + } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } pub fn env() -> Env { - unsafe { - let _guard = env_lock(); - // FIXME: replace with wasi::environ_get - let mut environ = libc::environ; - let mut result = Vec::new(); - while environ != ptr::null_mut() && *environ != ptr::null_mut() { - if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) { - result.push(key_value); - } - environ = environ.offset(1); - } - return Env { - iter: result.into_iter(), - _dont_send_or_sync_me: PhantomData, - } - } - - // See src/libstd/sys/unix/os.rs, same as that - fn parse(input: &[u8]) -> Option<(OsString, OsString)> { - if input.is_empty() { - return None; - } - let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1); - pos.map(|p| ( - OsStringExt::from_vec(input[..p].to_vec()), - OsStringExt::from_vec(input[p+1..].to_vec()), - )) + Env { + iter: wasi::get_environ().unwrap_or(Vec::new()), + _dont_send_or_sync_me: PhantomData, } } From 8394dbba7a46cd480b0934331b2654663d487e7b Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 15:18:39 +0300 Subject: [PATCH 007/462] remove libc import --- src/libstd/sys/wasi/thread.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index eedc584dde500..a399d1f844cb0 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -4,7 +4,6 @@ use crate::io; use crate::mem; use crate::sys::{unsupported, Void}; use crate::time::Duration; -use libc; pub struct Thread(Void); From 338fc7d042ac868e2c92bfedf2b6850bac1970c9 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 15:32:37 +0300 Subject: [PATCH 008/462] use non-zero clock id --- src/libstd/sys/wasi/thread.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index a399d1f844cb0..7a2246de86c4f 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -31,7 +31,7 @@ impl Thread { assert!(nanos <= u64::max_value() as u128); let clock = wasi::raw::__wasi_subscription_u_clock_t { - identifier: 0, + identifier: 0x0123_45678, clock_id: wasi::CLOCK_MONOTONIC, timeout: nanos as u64, precision: 0, @@ -47,7 +47,7 @@ impl Thread { let n = wasi::poll_oneoff(&in_, &mut out).unwrap(); let wasi::Event { userdata, error, type_, .. } = out[0]; match (n, userdata, error) { - (1, 0, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} + (1, 0x0123_45678, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} _ => panic!("thread::sleep(): unexpected result of poll_oneof"), } } From 7658a13c650e3dd931250f6039c4f12bcc77534f Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 15:33:05 +0300 Subject: [PATCH 009/462] typo fix --- src/libstd/sys/wasi/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index 7a2246de86c4f..f9e2433dca064 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -48,7 +48,7 @@ impl Thread { let wasi::Event { userdata, error, type_, .. } = out[0]; match (n, userdata, error) { (1, 0x0123_45678, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} - _ => panic!("thread::sleep(): unexpected result of poll_oneof"), + _ => panic!("thread::sleep(): unexpected result of poll_oneoff"), } } From e5ba80a87c54ab7770d9c300dacd0976f74e563e Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 15:36:30 +0300 Subject: [PATCH 010/462] use const --- src/libstd/sys/wasi/thread.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index f9e2433dca064..a6c8f2487013b 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -30,8 +30,10 @@ impl Thread { let nanos = dur.as_nanos(); assert!(nanos <= u64::max_value() as u128); + const CLOCK_ID: wasi::Userdata = 0x0123_45678; + let clock = wasi::raw::__wasi_subscription_u_clock_t { - identifier: 0x0123_45678, + identifier: CLOCK_ID, clock_id: wasi::CLOCK_MONOTONIC, timeout: nanos as u64, precision: 0, @@ -47,7 +49,7 @@ impl Thread { let n = wasi::poll_oneoff(&in_, &mut out).unwrap(); let wasi::Event { userdata, error, type_, .. } = out[0]; match (n, userdata, error) { - (1, 0x0123_45678, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} + (1, CLOCK_ID, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} _ => panic!("thread::sleep(): unexpected result of poll_oneoff"), } } From c05237686f994144f2f0bae68dc5b337b06e9a97 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 16:01:21 +0300 Subject: [PATCH 011/462] fix --- src/libstd/sys/wasi/args.rs | 2 +- src/libstd/sys/wasi/os.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index 23ab2051bf6f6..14aa391912ed2 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -19,7 +19,7 @@ pub struct Args { /// Returns the command line arguments pub fn args() -> Args { Args { - iter: wasi::get_args().unwrap_or(Vec::new()), + iter: wasi::get_args().unwrap_or(Vec::new()).into_iter(), _dont_send_or_sync_me: PhantomData } } diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 65c80c838dc82..04eee3ef28ff1 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -75,7 +75,7 @@ pub fn current_exe() -> io::Result { } pub struct Env { - iter: Vec>, + iter: vec::IntoIter>, _dont_send_or_sync_me: PhantomData<*mut ()>, } @@ -100,7 +100,7 @@ impl Iterator for Env { pub fn env() -> Env { Env { - iter: wasi::get_environ().unwrap_or(Vec::new()), + iter: wasi::get_environ().unwrap_or(Vec::new()).into_iter(), _dont_send_or_sync_me: PhantomData, } } From 744442d19a76c4dd39f5fa2a2bbd74638e8569ec Mon Sep 17 00:00:00 2001 From: newpavlov Date: Tue, 20 Aug 2019 15:43:34 +0300 Subject: [PATCH 012/462] fix C incompatibilities --- src/libstd/sys/wasi/mod.rs | 2 +- src/libstd/sys/wasi/os.rs | 67 ++++++++++++++++++++++++++------------ 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index 0a16c29e5af53..28b49996d1433 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -83,7 +83,7 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize { } pub unsafe fn abort_internal() -> ! { - wasi::proc_exit(127) + libc::abort() } pub fn hashmap_random_keys() -> (u64, u64) { diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 04eee3ef28ff1..dca58179e0c8d 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -21,11 +21,24 @@ pub unsafe fn env_lock() -> impl Any { } pub fn errno() -> i32 { - 0 + extern { + #[thread_local] + static errno: libc::c_int; + } + + unsafe { errno as i32 } } pub fn error_string(errno: i32) -> String { - wasi::error_string(errno) + let mut buf = [0 as libc::c_char; 1024]; + + let p = buf.as_mut_ptr(); + unsafe { + if libc::strerror_r(errno as libc::c_int, p, buf.len()) < 0 { + panic!("strerror_r failure"); + } + str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned() + } } pub fn getcwd() -> io::Result { @@ -73,35 +86,45 @@ impl StdError for JoinPathsError { pub fn current_exe() -> io::Result { unsupported() } - pub struct Env { - iter: vec::IntoIter>, + iter: vec::IntoIter<(OsString, OsString)>, _dont_send_or_sync_me: PhantomData<*mut ()>, } impl Iterator for Env { type Item = (OsString, OsString); - fn next(&mut self) -> Option<(OsString, OsString)> { - self.iter.next().and_then(|input| { - // See src/libstd/sys/unix/os.rs, same as that - if input.is_empty() { - return None; - } - let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1); - pos.map(|p| ( - OsStringExt::from_vec(input[..p].to_vec()), - OsStringExt::from_vec(input[p+1..].to_vec()), - )) - }) - } + fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } pub fn env() -> Env { - Env { - iter: wasi::get_environ().unwrap_or(Vec::new()).into_iter(), - _dont_send_or_sync_me: PhantomData, + unsafe { + let _guard = env_lock(); + let mut environ = libc::environ; + let mut result = Vec::new(); + while environ != ptr::null_mut() && *environ != ptr::null_mut() { + if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) { + result.push(key_value); + } + environ = environ.offset(1); + } + return Env { + iter: result.into_iter(), + _dont_send_or_sync_me: PhantomData, + } + } + + // See src/libstd/sys/unix/os.rs, same as that + fn parse(input: &[u8]) -> Option<(OsString, OsString)> { + if input.is_empty() { + return None; + } + let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1); + pos.map(|p| ( + OsStringExt::from_vec(input[..p].to_vec()), + OsStringExt::from_vec(input[p+1..].to_vec()), + )) } } @@ -147,7 +170,9 @@ pub fn home_dir() -> Option { } pub fn exit(code: i32) -> ! { - unsafe { wasi::proc_exit(code as u32) } + unsafe { + libc::exit(code) + } } pub fn getpid() -> u32 { From 4dee102a67466ca0c95f540aa458f8779f3a1cb5 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Tue, 20 Aug 2019 19:16:01 +0300 Subject: [PATCH 013/462] use new get_args --- src/libstd/sys/wasi/args.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index 14aa391912ed2..2d0ddea385afd 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -12,14 +12,16 @@ pub unsafe fn cleanup() { } pub struct Args { - iter: vec::IntoIter>, + iter: vec::IntoIter, _dont_send_or_sync_me: PhantomData<*mut ()>, } /// Returns the command line arguments pub fn args() -> Args { + let mut buf = Vec::new(); + let _ = wasi::get_args(|arg| buf.push(OsString::from_vec(arg.to_vec()))); Args { - iter: wasi::get_args().unwrap_or(Vec::new()).into_iter(), + iter: buf.into_iter(), _dont_send_or_sync_me: PhantomData } } @@ -33,7 +35,7 @@ impl Args { impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { - self.iter.next().map(OsString::from_vec) + self.iter.next() } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() From 88fd9450aa2111fcbe981006a9c391d57775ec14 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Wed, 21 Aug 2019 04:16:05 +0300 Subject: [PATCH 014/462] update args --- src/libstd/sys/wasi/args.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index 2d0ddea385afd..de9ca62469d5d 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -18,8 +18,14 @@ pub struct Args { /// Returns the command line arguments pub fn args() -> Args { - let mut buf = Vec::new(); - let _ = wasi::get_args(|arg| buf.push(OsString::from_vec(arg.to_vec()))); + let buf = wasi::args_sizes_get().and_then(|args_sizes| { + let mut buf = Vec::with_capacity(args_sizes.get_count()); + wasi::get_args(args_sizes, |arg| { + let arg = OsString::from_vec(arg.to_vec()); + buf.push(arg); + })?; + Ok(buf) + }).unwrap_or(vec![]); Args { iter: buf.into_iter(), _dont_send_or_sync_me: PhantomData From 39260d9016db6925414541ad2dce6502dded3a64 Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Wed, 21 Aug 2019 14:10:40 +0200 Subject: [PATCH 015/462] make abs, wrapping_abs, and overflowing_abs const functions --- src/libcore/num/mod.rs | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index b46e06f8d8ada..df1c00ccd184f 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1401,12 +1401,8 @@ $EndFeature, " ```"), #[stable(feature = "no_panic_abs", since = "1.13.0")] #[inline] - pub fn wrapping_abs(self) -> Self { - if self.is_negative() { - self.wrapping_neg() - } else { - self - } + pub const fn wrapping_abs(self) -> Self { + (self ^ (self >> ($BITS - 1))).wrapping_sub(self >> ($BITS - 1)) } } @@ -1764,12 +1760,8 @@ $EndFeature, " ```"), #[stable(feature = "no_panic_abs", since = "1.13.0")] #[inline] - pub fn overflowing_abs(self) -> (Self, bool) { - if self.is_negative() { - self.overflowing_neg() - } else { - (self, false) - } + pub const fn overflowing_abs(self) -> (Self, bool) { + (self ^ (self >> ($BITS - 1))).overflowing_sub(self >> ($BITS - 1)) } } @@ -1973,15 +1965,11 @@ $EndFeature, " #[stable(feature = "rust1", since = "1.0.0")] #[inline] #[rustc_inherit_overflow_checks] - pub fn abs(self) -> Self { - if self.is_negative() { - // Note that the #[inline] above means that the overflow - // semantics of this negation depend on the crate we're being - // inlined into. - -self - } else { - self - } + pub const fn abs(self) -> Self { + // Note that the #[inline] above means that the overflow + // semantics of the subtraction depend on the crate we're being + // inlined into. + (self ^ (self >> ($BITS - 1))) - (self >> ($BITS - 1)) } } From adee559659774054497fc36afea0076c334c0bb2 Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Wed, 21 Aug 2019 15:40:12 +0200 Subject: [PATCH 016/462] test const abs, wrapping_abs, and overflowing_abs --- src/test/ui/consts/const-int-overflowing-rpass.rs | 8 ++++++++ src/test/ui/consts/const-int-sign-rpass.rs | 6 ++++++ src/test/ui/consts/const-int-wrapping-rpass.rs | 8 ++++++++ 3 files changed, 22 insertions(+) diff --git a/src/test/ui/consts/const-int-overflowing-rpass.rs b/src/test/ui/consts/const-int-overflowing-rpass.rs index b619c7908aa22..9be87a6447cda 100644 --- a/src/test/ui/consts/const-int-overflowing-rpass.rs +++ b/src/test/ui/consts/const-int-overflowing-rpass.rs @@ -18,6 +18,10 @@ const SHR_B: (u32, bool) = 0x10u32.overflowing_shr(132); const NEG_A: (u32, bool) = 0u32.overflowing_neg(); const NEG_B: (u32, bool) = core::u32::MAX.overflowing_neg(); +const ABS_POS: (i32, bool) = 10i32.overflowing_abs(); +const ABS_NEG: (i32, bool) = (-10i32).overflowing_abs(); +const ABS_MIN: (i32, bool) = i32::min_value().overflowing_abs(); + fn main() { assert_eq!(ADD_A, (7, false)); assert_eq!(ADD_B, (0, true)); @@ -36,4 +40,8 @@ fn main() { assert_eq!(NEG_A, (0, false)); assert_eq!(NEG_B, (1, true)); + + assert_eq!(ABS_POS, (10, false)); + assert_eq!(ABS_NEG, (10, false)); + assert_eq!(ABS_MIN, (i32::min_value(), true)); } diff --git a/src/test/ui/consts/const-int-sign-rpass.rs b/src/test/ui/consts/const-int-sign-rpass.rs index 05726cb228647..dc46fce39a93c 100644 --- a/src/test/ui/consts/const-int-sign-rpass.rs +++ b/src/test/ui/consts/const-int-sign-rpass.rs @@ -11,6 +11,9 @@ const SIGNUM_POS: i32 = 10i32.signum(); const SIGNUM_NIL: i32 = 0i32.signum(); const SIGNUM_NEG: i32 = (-42i32).signum(); +const ABS_A: i32 = 10i32.abs(); +const ABS_B: i32 = (-10i32).abs(); + fn main() { assert!(NEGATIVE_A); assert!(!NEGATIVE_B); @@ -20,4 +23,7 @@ fn main() { assert_eq!(SIGNUM_POS, 1); assert_eq!(SIGNUM_NIL, 0); assert_eq!(SIGNUM_NEG, -1); + + assert_eq!(ABS_A, 10); + assert_eq!(ABS_B, 10); } diff --git a/src/test/ui/consts/const-int-wrapping-rpass.rs b/src/test/ui/consts/const-int-wrapping-rpass.rs index 73147d7912d19..2bbad99a52a90 100644 --- a/src/test/ui/consts/const-int-wrapping-rpass.rs +++ b/src/test/ui/consts/const-int-wrapping-rpass.rs @@ -18,6 +18,10 @@ const SHR_B: u32 = 128u32.wrapping_shr(128); const NEG_A: u32 = 5u32.wrapping_neg(); const NEG_B: u32 = 1234567890u32.wrapping_neg(); +const ABS_POS: i32 = 10i32.wrapping_abs(); +const ABS_NEG: i32 = (-10i32).wrapping_abs(); +const ABS_MIN: i32 = i32::min_value().wrapping_abs(); + fn main() { assert_eq!(ADD_A, 255); assert_eq!(ADD_B, 199); @@ -36,4 +40,8 @@ fn main() { assert_eq!(NEG_A, 4294967291); assert_eq!(NEG_B, 3060399406); + + assert_eq!(ABS_POS, 10); + assert_eq!(ABS_NEG, 10); + assert_eq!(ABS_MIN, i32::min_value()); } From a47e3c077cd7f201dbbf12140c12663df0fcda6f Mon Sep 17 00:00:00 2001 From: newpavlov Date: Wed, 21 Aug 2019 17:57:22 +0300 Subject: [PATCH 017/462] fixes --- src/libstd/sys/wasi/args.rs | 6 +-- src/libstd/sys/wasi/ext/fs.rs | 2 + src/libstd/sys/wasi/ext/io.rs | 2 +- src/libstd/sys/wasi/fd.rs | 76 +++++++++++++++++------------------ src/libstd/sys/wasi/fs.rs | 16 +++----- src/libstd/sys/wasi/io.rs | 2 +- src/libstd/sys/wasi/mod.rs | 27 +++++++------ src/libstd/sys/wasi/os.rs | 2 - src/libstd/sys/wasi/stdio.rs | 4 +- src/libstd/sys/wasi/thread.rs | 3 +- src/libstd/sys/wasi/time.rs | 3 +- 11 files changed, 69 insertions(+), 74 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index de9ca62469d5d..3280c4990dc66 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -1,10 +1,10 @@ -use crate::ffi::CStr; -use crate::io; use crate::ffi::OsString; use crate::marker::PhantomData; use crate::os::wasi::ffi::OsStringExt; use crate::vec; +use ::wasi::wasi_unstable as wasi; + pub unsafe fn init(_argc: isize, _argv: *const *const u8) { } @@ -20,7 +20,7 @@ pub struct Args { pub fn args() -> Args { let buf = wasi::args_sizes_get().and_then(|args_sizes| { let mut buf = Vec::with_capacity(args_sizes.get_count()); - wasi::get_args(args_sizes, |arg| { + wasi::args_get(args_sizes, |arg| { let arg = OsString::from_vec(arg.to_vec()); buf.push(arg); })?; diff --git a/src/libstd/sys/wasi/ext/fs.rs b/src/libstd/sys/wasi/ext/fs.rs index ecd509f01dabd..9fa4abfd171b5 100644 --- a/src/libstd/sys/wasi/ext/fs.rs +++ b/src/libstd/sys/wasi/ext/fs.rs @@ -8,6 +8,8 @@ use crate::os::wasi::ffi::OsStrExt; use crate::path::{Path, PathBuf}; use crate::sys_common::{AsInner, AsInnerMut, FromInner}; +use ::wasi::wasi_unstable as wasi; + /// WASI-specific extensions to [`File`]. /// /// [`File`]: ../../../../std/fs/struct.File.html diff --git a/src/libstd/sys/wasi/ext/io.rs b/src/libstd/sys/wasi/ext/io.rs index c843144f0c406..f1839df380112 100644 --- a/src/libstd/sys/wasi/ext/io.rs +++ b/src/libstd/sys/wasi/ext/io.rs @@ -8,7 +8,7 @@ use crate::sys; use crate::net; use crate::sys_common::{AsInner, FromInner, IntoInner}; -use wasi::wasi_unstable as wasi; +use ::wasi::wasi_unstable as wasi; /// Raw file descriptors. pub type RawFd = u32; diff --git a/src/libstd/sys/wasi/fd.rs b/src/libstd/sys/wasi/fd.rs index 93fe8add326c8..275e1319be6ad 100644 --- a/src/libstd/sys/wasi/fd.rs +++ b/src/libstd/sys/wasi/fd.rs @@ -3,14 +3,15 @@ use crate::io::{self, IoSlice, IoSliceMut, SeekFrom}; use crate::mem; use crate::net::Shutdown; -use wasi::wasi_unstable as wasi; +use super::err2io; +use ::wasi::wasi_unstable as wasi; #[derive(Debug)] pub struct WasiFd { fd: wasi::Fd, } -fn iovec(a: &mut [IoSliceMut<'_>]) -> &[wasi::IoVec] { +fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::IoVec] { assert_eq!( mem::size_of::>(), mem::size_of::() @@ -23,7 +24,7 @@ fn iovec(a: &mut [IoSliceMut<'_>]) -> &[wasi::IoVec] { unsafe { mem::transmute(a) } } -fn ciovec(a: &[IoSlice<'_>]) -> &[wasi::CIoVec] { +fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::CIoVec] { assert_eq!( mem::size_of::>(), mem::size_of::() @@ -52,23 +53,23 @@ impl WasiFd { } pub fn datasync(&self) -> io::Result<()> { - wasi::fd_datasync(self.fd).map_err(From::from) + wasi::fd_datasync(self.fd).map_err(err2io) } pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { - wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(From::from) + wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io) } pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { - wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(From::from) + wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io) } pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - wasi::fd_read(self.fd, iovec(bufs)).map_err(From::from) + wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io) } pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result { - wasi::fd_write(self.fd, ciovec(bufs)).map_err(From::from) + wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io) } pub fn seek(&self, pos: SeekFrom) -> io::Result { @@ -77,37 +78,37 @@ impl WasiFd { SeekFrom::End(pos) => (wasi::WHENCE_END, pos), SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos), }; - wasi::fd_seek(self.fd, offset, whence).map_err(From::from) + wasi::fd_seek(self.fd, offset, whence).map_err(err2io) } pub fn tell(&self) -> io::Result { - wasi::fd_tell(self.fd).map_err(From::from) + wasi::fd_tell(self.fd).map_err(err2io) } // FIXME: __wasi_fd_fdstat_get pub fn set_flags(&self, flags: wasi::FdFlags) -> io::Result<()> { - wasi::fd_fdstat_set_flags(self.fd, flags).map_err(From::from) + wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) } pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> { - wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(From::from) + wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io) } pub fn sync(&self) -> io::Result<()> { - wasi::fd_sync(self.fd).map_err(From::from) + wasi::fd_sync(self.fd).map_err(err2io) } pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> { - wasi::fd_advise(self.fd, offset, len, advice).map_err(From::from) + wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io) } pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> { - wasi::fd_allocate(self.fd, offset, len).map_err(From::from) + wasi::fd_allocate(self.fd, offset, len).map_err(err2io) } pub fn create_directory(&self, path: &[u8]) -> io::Result<()> { - wasi::path_create_directory(self.fd, path).map_err(From::from) + wasi::path_create_directory(self.fd, path).map_err(err2io) } pub fn link( @@ -118,7 +119,7 @@ impl WasiFd { new_path: &[u8], ) -> io::Result<()> { wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path) - .map_err(From::from) + .map_err(err2io) } pub fn open( @@ -130,7 +131,7 @@ impl WasiFd { fs_rights_inheriting: wasi::Rights, fs_flags: wasi::FdFlags, ) -> io::Result { - let fd = wasi_path_open( + wasi::path_open( self.fd, dirflags, path, @@ -138,25 +139,24 @@ impl WasiFd { fs_rights_base, fs_rights_inheriting, fs_flags, - )?; - Ok(WasiFd::from_raw(fd)) + ).map(|fd| unsafe { WasiFd::from_raw(fd) }).map_err(err2io) } pub fn readdir(&self, buf: &mut [u8], cookie: wasi::DirCookie) -> io::Result { - wasi::fd_readdir(self.fd, buf, cookie).map_err(From::from) + wasi::fd_readdir(self.fd, buf, cookie).map_err(err2io) } pub fn readlink(&self, path: &[u8], buf: &mut [u8]) -> io::Result { - wasi::path_readlink(self.fd, path, buf).map_err(From::from) + wasi::path_readlink(self.fd, path, buf).map_err(err2io) } pub fn rename(&self, old_path: &[u8], new_fd: &WasiFd, new_path: &[u8]) -> io::Result<()> { wasi::path_rename(self.fd, old_path, new_fd.fd, new_path) - .map_err(From::from) + .map_err(err2io) } - pub fn filestat_get(&self) -> io::Result { - wasi::fd_filestat_get(self.fd, buf).map_err(From::from) + pub fn filestat_get(&self) -> io::Result { + wasi::fd_filestat_get(self.fd).map_err(err2io) } pub fn filestat_set_times( @@ -166,11 +166,11 @@ impl WasiFd { fstflags: wasi::FstFlags, ) -> io::Result<()> { wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags) - .map_err(From::from) + .map_err(err2io) } pub fn filestat_set_size(&self, size: u64) -> io::Result<()> { - wasi::fd_filestat_set_size(self.fd, size).map_err(From::from) + wasi::fd_filestat_set_size(self.fd, size).map_err(err2io) } pub fn path_filestat_get( @@ -178,7 +178,7 @@ impl WasiFd { flags: wasi::LookupFlags, path: &[u8], ) -> io::Result { - wasi::path_filestat_get(self.fd, flags, path).map_err(From::from) + wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) } pub fn path_filestat_set_times( @@ -196,19 +196,19 @@ impl WasiFd { atim, mtim, fstflags, - ).map_err(From::from) + ).map_err(err2io) } pub fn symlink(&self, old_path: &[u8], new_path: &[u8]) -> io::Result<()> { - wasi::path_symlink(old_path, self.fd, new_path).map_err(From::from) + wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) } pub fn unlink_file(&self, path: &[u8]) -> io::Result<()> { - wasi::path_unlink_file(self.fd, path).map_err(From::from) + wasi::path_unlink_file(self.fd, path).map_err(err2io) } pub fn remove_directory(&self, path: &[u8]) -> io::Result<()> { - wasi::path_remove_directory(self.fd, path).map_err(From::from) + wasi::path_remove_directory(self.fd, path).map_err(err2io) } pub fn sock_recv( @@ -216,20 +216,20 @@ impl WasiFd { ri_data: &mut [IoSliceMut<'_>], ri_flags: wasi::RiFlags, ) -> io::Result<(usize, wasi::RoFlags)> { - wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(From::from) + wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io) } pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::SiFlags) -> io::Result { - wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(From::from) + wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io) } pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> { let how = match how { - Shutdown::Read => WASI::SHUT_RD, - Shutdown::Write => WASI::SHUT_WR, - Shutdown::Both => WASI::SHUT_WR | WASI::SHUT_RD, + Shutdown::Read => wasi::SHUT_RD, + Shutdown::Write => wasi::SHUT_WR, + Shutdown::Both => wasi::SHUT_WR | wasi::SHUT_RD, }; - wasi::sock_shutdown(self.fd, how).map_err(From::from) + wasi::sock_shutdown(self.fd, how).map_err(err2io) } } diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs index f23ecfc2bcd22..4113f6a2e09c0 100644 --- a/src/libstd/sys/wasi/fs.rs +++ b/src/libstd/sys/wasi/fs.rs @@ -7,7 +7,7 @@ use crate::os::wasi::ffi::{OsStrExt, OsStringExt}; use crate::path::{Path, PathBuf}; use crate::ptr; use crate::sync::Arc; -use crate::sys::fd::{DirCookie, WasiFd}; +use crate::sys::fd::WasiFd; use crate::sys::time::SystemTime; use crate::sys::unsupported; use crate::sys_common::FromInner; @@ -15,7 +15,7 @@ use crate::sys_common::FromInner; pub use crate::sys_common::fs::copy; pub use crate::sys_common::fs::remove_dir_all; -use wasi::wasi_unstable as wasi; +use ::wasi::wasi_unstable as wasi; pub struct File { fd: WasiFd, @@ -28,7 +28,7 @@ pub struct FileAttr { pub struct ReadDir { inner: Arc, - cookie: Option, + cookie: Option, buf: Vec, offset: usize, cap: usize, @@ -70,12 +70,6 @@ pub struct FileType { pub struct DirBuilder {} impl FileAttr { - fn zero() -> FileAttr { - FileAttr { - meta: unsafe { mem::zeroed() }, - } - } - pub fn size(&self) -> u64 { self.meta.st_size } @@ -390,7 +384,7 @@ impl File { } pub fn file_attr(&self) -> io::Result { - self.fd.filestat_get().map_ok(|meta| FileAttr { meta }) + self.fd.filestat_get().map(|meta| FileAttr { meta }) } pub fn metadata_at( @@ -601,7 +595,7 @@ fn metadata_at( path: &Path, ) -> io::Result { fd.path_filestat_get(flags, path.as_os_str().as_bytes()) - .map_ok(|meta| FileAttr { meta }) + .map(|meta| FileAttr { meta }) } pub fn canonicalize(_p: &Path) -> io::Result { diff --git a/src/libstd/sys/wasi/io.rs b/src/libstd/sys/wasi/io.rs index ebea3a03e439f..4be92faed308f 100644 --- a/src/libstd/sys/wasi/io.rs +++ b/src/libstd/sys/wasi/io.rs @@ -1,7 +1,7 @@ use crate::marker::PhantomData; use crate::slice; -use wasi::wasi_unstable as wasi; +use ::wasi::wasi_unstable as wasi; use core::ffi::c_void; #[repr(transparent)] diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index 28b49996d1433..89f7c887aafc0 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -14,10 +14,10 @@ //! compiling for wasm. That way it's a compile time error for something that's //! guaranteed to be a runtime error! -use crate::io; +use crate::io as std_io; use crate::mem; use crate::os::raw::c_char; -use wasi::wasi_unstable as wasi; +use ::wasi::wasi_unstable as wasi; pub mod alloc; pub mod args; @@ -56,16 +56,19 @@ pub mod ext; pub fn init() { } -pub fn unsupported() -> crate::io::Result { +pub fn unsupported() -> std_io::Result { Err(unsupported_err()) } -pub fn unsupported_err() -> io::Error { - io::Error::new(io::ErrorKind::Other, "operation not supported on wasm yet") +pub fn unsupported_err() -> std_io::Error { + std_io::Error::new( + std_io::ErrorKind::Other, + "operation not supported on wasm yet", + ) } -pub fn decode_error_kind(_code: i32) -> io::ErrorKind { - io::ErrorKind::Other +pub fn decode_error_kind(_code: i32) -> std_io::ErrorKind { + std_io::ErrorKind::Other } // This enum is used as the storage for a bunch of types which can't actually @@ -114,16 +117,14 @@ macro_rules! impl_is_minus_one { impl_is_minus_one! { i8 i16 i32 i64 isize } -pub fn cvt(t: T) -> crate::io::Result { +pub fn cvt(t: T) -> std_io::Result { if t.is_minus_one() { - Err(io::Error::last_os_error()) + Err(std_io::Error::last_os_error()) } else { Ok(t) } } -impl From for io::Error { - fn from(err: wasi::Error) -> Self { - Self::from_raw_os_error(err as i32) - } +fn err2io(err: wasi::Error) -> std_io::Error { + std_io::Error::from_raw_os_error(err.get() as i32) } diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index dca58179e0c8d..7ee23c9a35ec7 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -12,8 +12,6 @@ use crate::sys::memchr; use crate::sys::{cvt, unsupported, Void}; use crate::vec; -use wasi::wasi_unstable as wasi; - #[cfg(not(target_feature = "atomics"))] pub unsafe fn env_lock() -> impl Any { // No need for a lock if we're single-threaded, but this function will need diff --git a/src/libstd/sys/wasi/stdio.rs b/src/libstd/sys/wasi/stdio.rs index dc6a6ef375a1c..1d57b9922e599 100644 --- a/src/libstd/sys/wasi/stdio.rs +++ b/src/libstd/sys/wasi/stdio.rs @@ -2,7 +2,7 @@ use crate::io::{self, IoSlice, IoSliceMut}; use crate::mem::ManuallyDrop; use crate::sys::fd::WasiFd; -use wasi::wasi_unstable as wasi; +use ::wasi::wasi_unstable as wasi; pub struct Stdin; pub struct Stdout; @@ -74,7 +74,7 @@ impl io::Write for Stderr { pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE; pub fn is_ebadf(err: &io::Error) -> bool { - err.raw_os_error() == Some(wasi::EBADF as i32) + err.raw_os_error() == Some(wasi::EBADF.get() as i32) } pub fn panic_output() -> Option { diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index a6c8f2487013b..dc5a72e82a354 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -1,10 +1,11 @@ -use crate::cmp; use crate::ffi::CStr; use crate::io; use crate::mem; use crate::sys::{unsupported, Void}; use crate::time::Duration; +use ::wasi::wasi_unstable as wasi; + pub struct Thread(Void); pub const DEFAULT_MIN_STACK_SIZE: usize = 4096; diff --git a/src/libstd/sys/wasi/time.rs b/src/libstd/sys/wasi/time.rs index 4c89a1781b9ef..4394a22f9c233 100644 --- a/src/libstd/sys/wasi/time.rs +++ b/src/libstd/sys/wasi/time.rs @@ -1,6 +1,5 @@ use crate::time::Duration; -use crate::mem; -use wasi::wasi_unstable as wasi; +use ::wasi::wasi_unstable as wasi; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] pub struct Instant(Duration); From 926f36400f1667edec92959d8b640dea5084674c Mon Sep 17 00:00:00 2001 From: newpavlov Date: Wed, 21 Aug 2019 19:36:12 +0300 Subject: [PATCH 018/462] move cvt --- src/libstd/Cargo.toml | 1 + src/libstd/sys/wasi/mod.rs | 23 ----------------------- src/libstd/sys/wasi/os.rs | 25 ++++++++++++++++++++++++- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index bb77a5bdea493..d801b051357a4 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -24,6 +24,7 @@ compiler_builtins = { version = "0.1.16" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } unwind = { path = "../libunwind" } hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] } +wasi = { git = "https://github.com/newpavlov/rust-wasi", branch = "safe_rework", features = ['rustc-dep-of-std', 'alloc'] } [dependencies.backtrace] version = "0.3.35" diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index 89f7c887aafc0..f87e4d16fcdac 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -102,29 +102,6 @@ pub fn hashmap_random_keys() -> (u64, u64) { return ret } -#[doc(hidden)] -pub trait IsMinusOne { - fn is_minus_one(&self) -> bool; -} - -macro_rules! impl_is_minus_one { - ($($t:ident)*) => ($(impl IsMinusOne for $t { - fn is_minus_one(&self) -> bool { - *self == -1 - } - })*) -} - -impl_is_minus_one! { i8 i16 i32 i64 isize } - -pub fn cvt(t: T) -> std_io::Result { - if t.is_minus_one() { - Err(std_io::Error::last_os_error()) - } else { - Ok(t) - } -} - fn err2io(err: wasi::Error) -> std_io::Error { std_io::Error::from_raw_os_error(err.get() as i32) } diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 7ee23c9a35ec7..feee840782550 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -9,7 +9,7 @@ use crate::path::{self, PathBuf}; use crate::ptr; use crate::str; use crate::sys::memchr; -use crate::sys::{cvt, unsupported, Void}; +use crate::sys::{unsupported, Void}; use crate::vec; #[cfg(not(target_feature = "atomics"))] @@ -176,3 +176,26 @@ pub fn exit(code: i32) -> ! { pub fn getpid() -> u32 { panic!("unsupported"); } + +#[doc(hidden)] +pub trait IsMinusOne { + fn is_minus_one(&self) -> bool; +} + +macro_rules! impl_is_minus_one { + ($($t:ident)*) => ($(impl IsMinusOne for $t { + fn is_minus_one(&self) -> bool { + *self == -1 + } + })*) +} + +impl_is_minus_one! { i8 i16 i32 i64 isize } + +fn cvt(t: T) -> io::Result { + if t.is_minus_one() { + Err(io::Error::last_os_error()) + } else { + Ok(t) + } +} From 33788c252c83aeea913482b283e33ccc41bd2860 Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 24 Aug 2019 14:49:17 +0200 Subject: [PATCH 019/462] Added table containing the system calls used by Instant and SystemTime. --- src/libstd/time.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 98371b9ba3d7e..f03020bb4954e 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -59,6 +59,21 @@ pub use core::time::Duration; /// println!("{}", now.elapsed().as_secs()); /// } /// ``` +/// +/// # Underlying System calls +/// Currently, the following system calls are being used to get the current time using `now()`: +/// +/// | Platform | System call | +/// |:---------:|:------------------------------------------------:| +/// | Cloud ABI | [clock_time_get (Monotonic Clock)](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt) | +/// | SGX | Not implemented | +/// | UNIX | [mach_absolute_time](https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html) | +/// | VXWorks | [clock_gettime (Monotonic Clock)](https://linux.die.net/man/3/clock_gettime) | +/// | WASI | [__wasi_clock_time_get (Monotonic Clock)](https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get) | +/// | Windows | [QueryPerformanceCounter](https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter) | +/// +/// **Disclaimer:** These system calls might change over time. +/// #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[stable(feature = "time2", since = "1.8.0")] pub struct Instant(time::Instant); @@ -114,6 +129,21 @@ pub struct Instant(time::Instant); /// } /// } /// ``` +/// +/// # Underlying System calls +/// Currently, the following system calls are being used to get the current time using `now()`: +/// +/// | Platform | System call | +/// |:---------:|:------------------------------------------------:| +/// | Cloud ABI | [clock_time_get (Realtime Clock)](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt) | +/// | SGX | Not implemented | +/// | UNIX | [gettimeofday](http://man7.org/linux/man-pages/man2/gettimeofday.2.html) | +/// | VXWorks | [clock_gettime (Realtime Clock)](https://linux.die.net/man/3/clock_gettime) | +/// | WASI | [__wasi_clock_time_get (Realtime Clock)](https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get) | +/// | Windows | [GetSystemTimeAsFileTime](https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimeasfiletime) | +/// +/// **Disclaimer:** These system calls might change over time. +/// #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[stable(feature = "time2", since = "1.8.0")] pub struct SystemTime(time::SystemTime); From c8619ae7916459bec1b7e5583d75c69b10f06df9 Mon Sep 17 00:00:00 2001 From: Marcin Mielniczuk Date: Sun, 25 Aug 2019 00:09:12 +0200 Subject: [PATCH 020/462] Document platform-specific behavior of the iterator returned by std::fs::read_dir --- src/libstd/fs.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 5f76875bd66c4..90d911a6f9ac0 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1956,7 +1956,8 @@ pub fn remove_dir_all>(path: P) -> io::Result<()> { /// # Platform-specific behavior /// /// This function currently corresponds to the `opendir` function on Unix -/// and the `FindFirstFile` function on Windows. +/// and the `FindFirstFile` function on Windows. Advancing the iterator +/// currently corresponds to `readdir` on Unix and `FindNextFile` on Windows. /// Note that, this [may change in the future][changes]. /// /// [changes]: ../io/index.html#platform-specific-behavior From d86516d91e643fd87eadf057096989ce454f4d81 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sun, 25 Aug 2019 13:06:49 +0200 Subject: [PATCH 021/462] Stabilise weak_ptr_eq --- src/liballoc/rc.rs | 4 +--- src/liballoc/sync.rs | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 2b222caf13f3d..1752c1342c856 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1843,7 +1843,6 @@ impl Weak { /// # Examples /// /// ``` - /// #![feature(weak_ptr_eq)] /// use std::rc::Rc; /// /// let first_rc = Rc::new(5); @@ -1861,7 +1860,6 @@ impl Weak { /// Comparing `Weak::new`. /// /// ``` - /// #![feature(weak_ptr_eq)] /// use std::rc::{Rc, Weak}; /// /// let first = Weak::new(); @@ -1873,7 +1871,7 @@ impl Weak { /// assert!(!first.ptr_eq(&third)); /// ``` #[inline] - #[unstable(feature = "weak_ptr_eq", issue = "55981")] + #[stable(feature = "weak_ptr_eq", since = "1.39.0")] pub fn ptr_eq(&self, other: &Self) -> bool { self.ptr.as_ptr() == other.ptr.as_ptr() } diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 9ffc1673e5ab8..e89433d67bdd6 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1562,7 +1562,6 @@ impl Weak { /// # Examples /// /// ``` - /// #![feature(weak_ptr_eq)] /// use std::sync::Arc; /// /// let first_rc = Arc::new(5); @@ -1580,7 +1579,6 @@ impl Weak { /// Comparing `Weak::new`. /// /// ``` - /// #![feature(weak_ptr_eq)] /// use std::sync::{Arc, Weak}; /// /// let first = Weak::new(); @@ -1592,7 +1590,7 @@ impl Weak { /// assert!(!first.ptr_eq(&third)); /// ``` #[inline] - #[unstable(feature = "weak_ptr_eq", issue = "55981")] + #[stable(feature = "weak_ptr_eq", since = "1.39.0")] pub fn ptr_eq(&self, other: &Self) -> bool { self.ptr.as_ptr() == other.ptr.as_ptr() } From 307804a00d191b6f15d1a1a5b98fbae5ea6593b0 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sun, 25 Aug 2019 13:02:45 +0200 Subject: [PATCH 022/462] Update {rc, sync}::Weak::ptr_eq doc about comparing Weak::new --- src/liballoc/rc.rs | 5 +++-- src/liballoc/sync.rs | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 1752c1342c856..a10f7c60031e0 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1832,8 +1832,9 @@ impl Weak { } } - /// Returns `true` if the two `Weak`s point to the same value (not just values - /// that compare as equal). + /// Returns `true` if the two `Weak`s point to the same value (not just + /// values that compare as equal), or if both don't point to any value + /// (because they were created with `Weak::new()`). /// /// # Notes /// diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index e89433d67bdd6..716d750915e12 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1550,15 +1550,15 @@ impl Weak { } } - /// Returns `true` if the two `Weak`s point to the same value (not just values - /// that compare as equal). + /// Returns `true` if the two `Weak`s point to the same value (not just + /// values that compare as equal), or if both don't point to any value + /// (because they were created with `Weak::new()`). /// /// # Notes /// /// Since this compares pointers it means that `Weak::new()` will equal each /// other, even though they don't point to any value. /// - /// /// # Examples /// /// ``` From 1478ef45287c4da0da0daf1715d00e8b06fa333b Mon Sep 17 00:00:00 2001 From: Christian Veenman <46896178+DevQps@users.noreply.github.com> Date: Mon, 26 Aug 2019 22:05:26 +0200 Subject: [PATCH 023/462] Update src/libstd/time.rs Co-Authored-By: lzutao --- src/libstd/time.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index f03020bb4954e..c05f02389dfa0 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -70,7 +70,9 @@ pub use core::time::Duration; /// | UNIX | [mach_absolute_time](https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html) | /// | VXWorks | [clock_gettime (Monotonic Clock)](https://linux.die.net/man/3/clock_gettime) | /// | WASI | [__wasi_clock_time_get (Monotonic Clock)](https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get) | -/// | Windows | [QueryPerformanceCounter](https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter) | +/// | Windows | [QueryPerformanceCounter] | + +[QueryPerformanceCounter]: https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter /// /// **Disclaimer:** These system calls might change over time. /// From 6876f9bcdc94c5e0c8cde03040b428f24f19a051 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Mon, 26 Aug 2019 18:06:24 -0500 Subject: [PATCH 024/462] filter linkcheck spurious failure --- src/tools/rustbook/src/main.rs | 54 ++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs index 95530b210afd6..0915600bb3875 100644 --- a/src/tools/rustbook/src/main.rs +++ b/src/tools/rustbook/src/main.rs @@ -1,18 +1,18 @@ -use clap::{crate_version}; +use clap::crate_version; use std::env; use std::path::{Path, PathBuf}; -use clap::{App, ArgMatches, SubCommand, AppSettings}; +use clap::{App, AppSettings, ArgMatches, SubCommand}; +use mdbook::errors::Result as Result3; use mdbook::MDBook; -use mdbook::errors::{Result as Result3}; +use failure::Error; #[cfg(feature = "linkcheck")] use mdbook::renderer::RenderContext; #[cfg(feature = "linkcheck")] use mdbook_linkcheck::{self, errors::BrokenLinks}; -use failure::Error; fn main() { let d_message = "-d, --dest-dir=[dest-dir] @@ -21,18 +21,22 @@ fn main() { 'A directory for your book{n}(Defaults to Current Directory when omitted)'"; let matches = App::new("rustbook") - .about("Build a book with mdBook") - .author("Steve Klabnik ") - .version(&*format!("v{}", crate_version!())) - .setting(AppSettings::SubcommandRequired) - .subcommand(SubCommand::with_name("build") - .about("Build the book from the markdown files") - .arg_from_usage(d_message) - .arg_from_usage(dir_message)) - .subcommand(SubCommand::with_name("linkcheck") - .about("Run linkcheck with mdBook 3") - .arg_from_usage(dir_message)) - .get_matches(); + .about("Build a book with mdBook") + .author("Steve Klabnik ") + .version(&*format!("v{}", crate_version!())) + .setting(AppSettings::SubcommandRequired) + .subcommand( + SubCommand::with_name("build") + .about("Build the book from the markdown files") + .arg_from_usage(d_message) + .arg_from_usage(dir_message), + ) + .subcommand( + SubCommand::with_name("linkcheck") + .about("Run linkcheck with mdBook 3") + .arg_from_usage(dir_message), + ) + .get_matches(); // Check which subcomamnd the user ran... match matches.subcommand() { @@ -46,23 +50,35 @@ fn main() { ::std::process::exit(101); } - }, + } ("linkcheck", Some(sub_matches)) => { if let Err(err) = linkcheck(sub_matches) { eprintln!("Error: {}", err); + // HACK: ignore timeouts + #[allow(unused_mut)] + let mut actually_broken = false; + #[cfg(feature = "linkcheck")] { if let Ok(broken_links) = err.downcast::() { for cause in broken_links.links().iter() { eprintln!("\tCaused By: {}", cause); + + if cause.contains("timed out") { + actually_broken = true; + } } } } - ::std::process::exit(101); + if actually_broken { + std::process::exit(101); + } else { + std::process::exit(0); + } } - }, + } (_, _) => unreachable!(), }; } From 6374b8458f0796a1ff3ee2caec41321e801c35d1 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Thu, 29 Aug 2019 20:13:15 +0300 Subject: [PATCH 025/462] update to wasi v0.7 --- Cargo.lock | 12 ++++ src/libstd/Cargo.toml | 2 +- src/libstd/sys/wasi/fd.rs | 104 ++++++++++++++++++---------------- src/libstd/sys/wasi/mod.rs | 13 ++++- src/libstd/sys/wasi/thread.rs | 2 +- 5 files changed, 80 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ae21c8663706..3719b36236797 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3866,6 +3866,7 @@ dependencies = [ "rustc_msan", "rustc_tsan", "unwind", + "wasi", ] [[package]] @@ -4664,6 +4665,17 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + [[package]] name = "winapi" version = "0.2.8" diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index d801b051357a4..0d04b7a274037 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -24,7 +24,7 @@ compiler_builtins = { version = "0.1.16" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } unwind = { path = "../libunwind" } hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] } -wasi = { git = "https://github.com/newpavlov/rust-wasi", branch = "safe_rework", features = ['rustc-dep-of-std', 'alloc'] } +wasi = { version = "0.7.0", features = ['rustc-dep-of-std', 'alloc'] } [dependencies.backtrace] version = "0.3.35" diff --git a/src/libstd/sys/wasi/fd.rs b/src/libstd/sys/wasi/fd.rs index 275e1319be6ad..5b7a8678b66ea 100644 --- a/src/libstd/sys/wasi/fd.rs +++ b/src/libstd/sys/wasi/fd.rs @@ -53,23 +53,23 @@ impl WasiFd { } pub fn datasync(&self) -> io::Result<()> { - wasi::fd_datasync(self.fd).map_err(err2io) + unsafe { wasi::fd_datasync(self.fd).map_err(err2io) } } pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { - wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io) + unsafe { wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io) } } pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { - wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io) + unsafe { wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io) } } pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io) + unsafe { wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io) } } pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result { - wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io) + unsafe { wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io) } } pub fn seek(&self, pos: SeekFrom) -> io::Result { @@ -78,37 +78,37 @@ impl WasiFd { SeekFrom::End(pos) => (wasi::WHENCE_END, pos), SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos), }; - wasi::fd_seek(self.fd, offset, whence).map_err(err2io) + unsafe { wasi::fd_seek(self.fd, offset, whence).map_err(err2io) } } pub fn tell(&self) -> io::Result { - wasi::fd_tell(self.fd).map_err(err2io) + unsafe { wasi::fd_tell(self.fd).map_err(err2io) } } // FIXME: __wasi_fd_fdstat_get pub fn set_flags(&self, flags: wasi::FdFlags) -> io::Result<()> { - wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) + unsafe { wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) } } pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> { - wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io) + unsafe { wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io) } } pub fn sync(&self) -> io::Result<()> { - wasi::fd_sync(self.fd).map_err(err2io) + unsafe { wasi::fd_sync(self.fd).map_err(err2io) } } pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> { - wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io) + unsafe { wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io) } } pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> { - wasi::fd_allocate(self.fd, offset, len).map_err(err2io) + unsafe { wasi::fd_allocate(self.fd, offset, len).map_err(err2io) } } pub fn create_directory(&self, path: &[u8]) -> io::Result<()> { - wasi::path_create_directory(self.fd, path).map_err(err2io) + unsafe { wasi::path_create_directory(self.fd, path).map_err(err2io) } } pub fn link( @@ -118,8 +118,10 @@ impl WasiFd { new_fd: &WasiFd, new_path: &[u8], ) -> io::Result<()> { - wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path) - .map_err(err2io) + unsafe { + wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path) + .map_err(err2io) + } } pub fn open( @@ -131,32 +133,35 @@ impl WasiFd { fs_rights_inheriting: wasi::Rights, fs_flags: wasi::FdFlags, ) -> io::Result { - wasi::path_open( - self.fd, - dirflags, - path, - oflags, - fs_rights_base, - fs_rights_inheriting, - fs_flags, - ).map(|fd| unsafe { WasiFd::from_raw(fd) }).map_err(err2io) + unsafe { + wasi::path_open( + self.fd, + dirflags, + path, + oflags, + fs_rights_base, + fs_rights_inheriting, + fs_flags, + ).map(|fd| WasiFd::from_raw(fd)).map_err(err2io) + } } pub fn readdir(&self, buf: &mut [u8], cookie: wasi::DirCookie) -> io::Result { - wasi::fd_readdir(self.fd, buf, cookie).map_err(err2io) + unsafe { wasi::fd_readdir(self.fd, buf, cookie).map_err(err2io) } } pub fn readlink(&self, path: &[u8], buf: &mut [u8]) -> io::Result { - wasi::path_readlink(self.fd, path, buf).map_err(err2io) + unsafe { wasi::path_readlink(self.fd, path, buf).map_err(err2io) } } pub fn rename(&self, old_path: &[u8], new_fd: &WasiFd, new_path: &[u8]) -> io::Result<()> { - wasi::path_rename(self.fd, old_path, new_fd.fd, new_path) - .map_err(err2io) + unsafe { + wasi::path_rename(self.fd, old_path, new_fd.fd, new_path).map_err(err2io) + } } pub fn filestat_get(&self) -> io::Result { - wasi::fd_filestat_get(self.fd).map_err(err2io) + unsafe { wasi::fd_filestat_get(self.fd).map_err(err2io) } } pub fn filestat_set_times( @@ -165,12 +170,13 @@ impl WasiFd { mtim: wasi::Timestamp, fstflags: wasi::FstFlags, ) -> io::Result<()> { - wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags) - .map_err(err2io) + unsafe { + wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags).map_err(err2io) + } } pub fn filestat_set_size(&self, size: u64) -> io::Result<()> { - wasi::fd_filestat_set_size(self.fd, size).map_err(err2io) + unsafe { wasi::fd_filestat_set_size(self.fd, size).map_err(err2io) } } pub fn path_filestat_get( @@ -178,7 +184,7 @@ impl WasiFd { flags: wasi::LookupFlags, path: &[u8], ) -> io::Result { - wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) + unsafe { wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) } } pub fn path_filestat_set_times( @@ -189,26 +195,28 @@ impl WasiFd { mtim: wasi::Timestamp, fstflags: wasi::FstFlags, ) -> io::Result<()> { - wasi::path_filestat_set_times( - self.fd, - flags, - path, - atim, - mtim, - fstflags, - ).map_err(err2io) + unsafe { + wasi::path_filestat_set_times( + self.fd, + flags, + path, + atim, + mtim, + fstflags, + ).map_err(err2io) + } } pub fn symlink(&self, old_path: &[u8], new_path: &[u8]) -> io::Result<()> { - wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) + unsafe { wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) } } pub fn unlink_file(&self, path: &[u8]) -> io::Result<()> { - wasi::path_unlink_file(self.fd, path).map_err(err2io) + unsafe { wasi::path_unlink_file(self.fd, path).map_err(err2io) } } pub fn remove_directory(&self, path: &[u8]) -> io::Result<()> { - wasi::path_remove_directory(self.fd, path).map_err(err2io) + unsafe { wasi::path_remove_directory(self.fd, path).map_err(err2io) } } pub fn sock_recv( @@ -216,11 +224,11 @@ impl WasiFd { ri_data: &mut [IoSliceMut<'_>], ri_flags: wasi::RiFlags, ) -> io::Result<(usize, wasi::RoFlags)> { - wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io) + unsafe { wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io) } } pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::SiFlags) -> io::Result { - wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io) + unsafe { wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io) } } pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> { @@ -229,7 +237,7 @@ impl WasiFd { Shutdown::Write => wasi::SHUT_WR, Shutdown::Both => wasi::SHUT_WR | wasi::SHUT_RD, }; - wasi::sock_shutdown(self.fd, how).map_err(err2io) + unsafe { wasi::sock_shutdown(self.fd, how).map_err(err2io) } } } @@ -237,6 +245,6 @@ impl Drop for WasiFd { fn drop(&mut self) { // FIXME: can we handle the return code here even though we can't on // unix? - let _ = wasi::fd_close(self.fd); + let _ = unsafe { wasi::fd_close(self.fd) }; } } diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index 4007b7ac0ec5f..517e3be9cb58c 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -69,10 +69,17 @@ pub fn unsupported_err() -> std_io::Error { pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { use std_io::ErrorKind::*; - match errno as libc::c_int { + if errno > u16::max_value() as i32 || errno < 0 { + return Other; + } + let code = match wasi::Error::new(errno as u16) { + Some(code) => code, + None => return Other, + }; + match code { wasi::ECONNREFUSED => ConnectionRefused, wasi::ECONNRESET => ConnectionReset, - wasi::EPERM | libc::EACCES => PermissionDenied, + wasi::EPERM | wasi::EACCES => PermissionDenied, wasi::EPIPE => BrokenPipe, wasi::ENOTCONN => NotConnected, wasi::ECONNABORTED => ConnectionAborted, @@ -84,7 +91,7 @@ pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { wasi::ETIMEDOUT => TimedOut, wasi::EEXIST => AlreadyExists, wasi::EAGAIN => WouldBlock, - _ => ErrorKind::Other, + _ => Other, } } diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index dc5a72e82a354..987bf7580838b 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -47,7 +47,7 @@ impl Thread { u: wasi::raw::__wasi_subscription_u { clock: clock }, }]; let mut out: [wasi::Event; 1] = [unsafe { mem::zeroed() }]; - let n = wasi::poll_oneoff(&in_, &mut out).unwrap(); + let n = unsafe { wasi::poll_oneoff(&in_, &mut out).unwrap() }; let wasi::Event { userdata, error, type_, .. } = out[0]; match (n, userdata, error) { (1, CLOCK_ID, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} From 06acfb22e03ff482275e1ffd78f691b0e5d88ffb Mon Sep 17 00:00:00 2001 From: newpavlov Date: Thu, 29 Aug 2019 20:22:24 +0300 Subject: [PATCH 026/462] add wasi license to the licenses whitelist --- src/tools/tidy/src/deps.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index e07a07234c71e..6ca912db5930d 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -15,6 +15,7 @@ const LICENSES: &[&str] = &[ "Apache-2.0 / MIT", "MIT OR Apache-2.0", "Apache-2.0 OR MIT", + "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", // wasi license "MIT", "Unlicense/MIT", "Unlicense OR MIT", From 2e59c4afd16ea7b887f3d81b5aeea8669b843afe Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 29 Aug 2019 13:03:22 -0500 Subject: [PATCH 027/462] fix bugs + review comments --- src/tools/rustbook/src/main.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs index 0915600bb3875..e155f3f7607f3 100644 --- a/src/tools/rustbook/src/main.rs +++ b/src/tools/rustbook/src/main.rs @@ -56,21 +56,22 @@ fn main() { eprintln!("Error: {}", err); // HACK: ignore timeouts - #[allow(unused_mut)] - let mut actually_broken = false; - - #[cfg(feature = "linkcheck")] - { - if let Ok(broken_links) = err.downcast::() { - for cause in broken_links.links().iter() { - eprintln!("\tCaused By: {}", cause); - - if cause.contains("timed out") { - actually_broken = true; - } - } + let actually_broken = { + #[cfg(feature = "linkcheck")] + { + err.downcast::() + .unwrap_or(false) + .links() + .iter() + .inspect(|cause| eprintln!("\tCaused By: {}", cause)) + .any(|cause| !cause.contains("timed out")); } - } + + #[cfg(not(feature = "linkcheck"))] + { + false + } + }; if actually_broken { std::process::exit(101); From 127311b75efd47a6f54aca49523c050566fc9823 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 29 Aug 2019 18:08:13 +0000 Subject: [PATCH 028/462] whitelist wasi crate --- src/tools/tidy/src/deps.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 6ca912db5930d..c31da3c6f4887 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -172,6 +172,7 @@ const WHITELIST: &[Crate<'_>] = &[ Crate("vcpkg"), Crate("version_check"), Crate("void"), + Crate("wasi"), Crate("winapi"), Crate("winapi-build"), Crate("winapi-i686-pc-windows-gnu"), From 5da1123c5efbd91813fb5ba7cec5298d960ae3af Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Thu, 29 Aug 2019 17:49:46 -0700 Subject: [PATCH 029/462] Update zx_time_t to an i64 --- src/libstd/sys/unix/process/zircon.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/unix/process/zircon.rs b/src/libstd/sys/unix/process/zircon.rs index ec715d5490f6f..9224bef7c4a5f 100644 --- a/src/libstd/sys/unix/process/zircon.rs +++ b/src/libstd/sys/unix/process/zircon.rs @@ -3,7 +3,7 @@ use crate::convert::TryInto; use crate::io; use crate::os::raw::c_char; -use crate::u64; +use crate::i64; use libc::{c_int, c_void, size_t}; @@ -14,8 +14,8 @@ pub type zx_status_t = i32; pub const ZX_HANDLE_INVALID: zx_handle_t = 0; -pub type zx_time_t = u64; -pub const ZX_TIME_INFINITE : zx_time_t = u64::MAX; +pub type zx_time_t = i64; +pub const ZX_TIME_INFINITE : zx_time_t = i64::MAX; pub type zx_signals_t = u32; From fdc4f9028f838605d031248abda0ebfb7450bf9f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Aug 2019 13:21:47 +0200 Subject: [PATCH 030/462] Add missing examples for Option type --- src/libcore/option.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 259ed36c57885..79bd04b724390 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -1110,6 +1110,18 @@ impl Option { /// to the original one, additionally coercing the contents via [`Deref`]. /// /// [`Deref`]: ../../std/ops/trait.Deref.html + /// + /// # Examples + /// + /// ``` + /// #![feature(inner_deref)] + /// + /// let x: Option = Some("hey".to_owned()); + /// assert_eq!(x.as_deref(), Some("hey")); + /// + /// let x: Option = None; + /// assert_eq!(x.as_deref(), None); + /// ``` pub fn as_deref(&self) -> Option<&T::Target> { self.as_ref().map(|t| t.deref()) } @@ -1121,6 +1133,18 @@ impl Option { /// /// Leaves the original `Option` in-place, creating a new one containing a mutable reference to /// the inner type's `Deref::Target` type. + /// + /// # Examples + /// + /// ``` + /// #![feature(inner_deref)] + /// + /// let mut x: Option = Some("hey".to_owned()); + /// assert_eq!(x.as_deref_mut().map(|x| { + /// x.make_ascii_uppercase(); + /// x + /// }), Some("HEY".to_owned().as_mut_str())); + /// ``` pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> { self.as_mut().map(|t| t.deref_mut()) } @@ -1199,6 +1223,13 @@ impl Clone for Option { #[stable(feature = "rust1", since = "1.0.0")] impl Default for Option { /// Returns [`None`][Option::None]. + /// + /// # Examples + /// + /// ``` + /// let opt: Option = Option::default(); + /// assert!(opt.is_none()); + /// ``` #[inline] fn default() -> Option { None } } From a8926a5e9c5becdf18acede5f7e114cd5f8655b6 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 6 May 2019 13:47:58 +0200 Subject: [PATCH 031/462] Use `panic::set_hook` to print the ICE message --- Cargo.lock | 1 + src/librustc_driver/Cargo.toml | 1 + src/librustc_driver/lib.rs | 109 +++++++++++++++---------- src/librustdoc/lib.rs | 2 +- src/test/ui-fulldeps/compiler-calls.rs | 2 +- 5 files changed, 68 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae641d6ae32b1..179bf59388a29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3204,6 +3204,7 @@ version = "0.0.0" dependencies = [ "env_logger 0.5.13", "graphviz", + "lazy_static 1.3.0", "log", "rustc", "rustc_ast_borrowck", diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index b030517e28ec2..8bd61c25843aa 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -11,6 +11,7 @@ crate-type = ["dylib"] [dependencies] graphviz = { path = "../libgraphviz" } +lazy_static = "1.0" log = "0.4" env_logger = { version = "0.5", default-features = false } rustc = { path = "../librustc" } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index e3ea92dc8ab38..5b7ac14ba3585 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -21,6 +21,8 @@ pub extern crate getopts; extern crate libc; #[macro_use] extern crate log; +#[macro_use] +extern crate lazy_static; pub extern crate rustc_plugin_impl as plugin; @@ -1143,61 +1145,77 @@ fn extra_compiler_flags() -> Option<(Vec, bool)> { } } -/// Runs a procedure which will detect panics in the compiler and print nicer -/// error messages rather than just failing the test. +/// Runs a closure and catches unwinds triggered by fatal errors. /// -/// The diagnostic emitter yielded to the procedure should be used for reporting -/// errors of the compiler. -pub fn report_ices_to_stderr_if_any R, R>(f: F) -> Result { +/// The compiler currently panics with a special sentinel value to abort +/// compilation on fatal errors. This function catches that sentinel and turns +/// the panic into a `Result` instead. +pub fn catch_fatal_errors R, R>(f: F) -> Result { catch_unwind(panic::AssertUnwindSafe(f)).map_err(|value| { if value.is::() { ErrorReported } else { - // Thread panicked without emitting a fatal diagnostic - eprintln!(""); - - let emitter = Box::new(errors::emitter::EmitterWriter::stderr( - errors::ColorConfig::Auto, - None, - false, - false, - None, - )); - let handler = errors::Handler::with_emitter(true, None, emitter); - - // a .span_bug or .bug call has already printed what - // it wants to print. - if !value.is::() { - handler.emit(&MultiSpan::new(), - "unexpected panic", - errors::Level::Bug); - } + panic::resume_unwind(value); + } + }) +} - let mut xs: Vec> = vec![ - "the compiler unexpectedly panicked. this is a bug.".into(), - format!("we would appreciate a bug report: {}", BUG_REPORT_URL).into(), - format!("rustc {} running on {}", - option_env!("CFG_VERSION").unwrap_or("unknown_version"), - config::host_triple()).into(), - ]; +lazy_static! { + static ref DEFAULT_HOOK: Box) + Sync + Send + 'static> = { + let hook = panic::take_hook(); + panic::set_hook(Box::new(report_ice)); + hook + }; +} - if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() { - xs.push(format!("compiler flags: {}", flags.join(" ")).into()); +pub fn report_ice(info: &panic::PanicInfo<'_>) { + (*DEFAULT_HOOK)(info); + + // Thread panicked without emitting a fatal diagnostic + eprintln!(); + + let emitter = Box::new(errors::emitter::EmitterWriter::stderr( + errors::ColorConfig::Auto, + None, + false, + false, + None, + )); + let handler = errors::Handler::with_emitter(true, None, emitter); + + // a .span_bug or .bug call has already printed what + // it wants to print. + if !info.payload().is::() { + handler.emit(&MultiSpan::new(), + "unexpected panic", + errors::Level::Bug); + } - if excluded_cargo_defaults { - xs.push("some of the compiler flags provided by cargo are hidden".into()); - } - } + let mut xs: Vec> = vec![ + "the compiler unexpectedly panicked. this is a bug.".into(), + format!("we would appreciate a bug report: {}", BUG_REPORT_URL).into(), + format!("rustc {} running on {}", + option_env!("CFG_VERSION").unwrap_or("unknown_version"), + config::host_triple()).into(), + ]; - for note in &xs { - handler.emit(&MultiSpan::new(), - note, - errors::Level::Note); - } + if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() { + xs.push(format!("compiler flags: {}", flags.join(" ")).into()); - panic::resume_unwind(Box::new(errors::FatalErrorMarker)); + if excluded_cargo_defaults { + xs.push("some of the compiler flags provided by cargo are hidden".into()); } - }) + } + + for note in &xs { + handler.emit(&MultiSpan::new(), + note, + errors::Level::Note); + } +} + +pub fn install_ice_hook() { + lazy_static::initialize(&DEFAULT_HOOK); } /// This allows tools to enable rust logging without having to magically match rustc's @@ -1210,7 +1228,8 @@ pub fn main() { let start = Instant::now(); init_rustc_env_logger(); let mut callbacks = TimePassesCallbacks::default(); - let result = report_ices_to_stderr_if_any(|| { + install_ice_hook(); + let result = catch_fatal_errors(|| { let args = env::args_os().enumerate() .map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| { early_error(ErrorOutputType::default(), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 87dac0f226896..0b366da29d37e 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -453,7 +453,7 @@ where R: 'static + Send, // First, parse the crate and extract all relevant information. info!("starting to run rustc"); - let result = rustc_driver::report_ices_to_stderr_if_any(move || { + let result = rustc_driver::catch_fatal_errors(move || { let crate_name = options.crate_name.clone(); let crate_version = options.crate_version.clone(); let (mut krate, renderinfo, renderopts) = core::run_core(options); diff --git a/src/test/ui-fulldeps/compiler-calls.rs b/src/test/ui-fulldeps/compiler-calls.rs index ea24f5809d52a..bd9113c7079ea 100644 --- a/src/test/ui-fulldeps/compiler-calls.rs +++ b/src/test/ui-fulldeps/compiler-calls.rs @@ -24,7 +24,7 @@ impl rustc_driver::Callbacks for TestCalls<'_> { fn main() { let mut count = 1; let args = vec!["compiler-calls".to_string(), "foo.rs".to_string()]; - rustc_driver::report_ices_to_stderr_if_any(|| { + rustc_driver::catch_fatal_errors(|| { rustc_driver::run_compiler(&args, &mut TestCalls { count: &mut count }, None, None).ok(); }).ok(); assert_eq!(count, 2); From e296ed321e37dc5ba21536a1f4b277b5536f6838 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 7 May 2019 00:14:40 +0200 Subject: [PATCH 032/462] Move librustc panic handler into the new one --- src/librustc/Cargo.toml | 1 - src/librustc/lib.rs | 1 - src/librustc/util/common.rs | 37 ------------------------------------- src/librustc_driver/lib.rs | 27 ++++++++++++++++++++++----- 4 files changed, 22 insertions(+), 44 deletions(-) diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 0222a3dde7ab9..4ab982f6f91f5 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -15,7 +15,6 @@ bitflags = "1.0" fmt_macros = { path = "../libfmt_macros" } graphviz = { path = "../libgraphviz" } jobserver = "0.1" -lazy_static = "1.0.0" num_cpus = "1.0" scoped-tls = "1.0" log = { version = "0.4", features = ["release_max_level_info", "std"] } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 368f5bb64fe6c..c2befabcb69b3 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -68,7 +68,6 @@ #[macro_use] extern crate bitflags; extern crate getopts; -#[macro_use] extern crate lazy_static; #[macro_use] extern crate scoped_tls; #[cfg(windows)] extern crate libc; diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 7118d05204c3b..2475b93d95f32 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -5,17 +5,13 @@ use rustc_data_structures::{fx::FxHashMap, sync::Lock}; use std::cell::{RefCell, Cell}; use std::fmt::Debug; use std::hash::Hash; -use std::panic; -use std::env; use std::time::{Duration, Instant}; use std::sync::mpsc::{Sender}; use syntax_pos::{SpanData}; use syntax::symbol::{Symbol, sym}; use rustc_macros::HashStable; -use crate::ty::TyCtxt; use crate::dep_graph::{DepNode}; -use lazy_static; use crate::session::Session; #[cfg(test)] @@ -31,39 +27,6 @@ pub struct ErrorReported; thread_local!(static TIME_DEPTH: Cell = Cell::new(0)); -lazy_static! { - static ref DEFAULT_HOOK: Box) + Sync + Send + 'static> = { - let hook = panic::take_hook(); - panic::set_hook(Box::new(panic_hook)); - hook - }; -} - -fn panic_hook(info: &panic::PanicInfo<'_>) { - (*DEFAULT_HOOK)(info); - - let backtrace = env::var_os("RUST_BACKTRACE").map(|x| &x != "0").unwrap_or(false); - - if backtrace { - TyCtxt::try_print_query_stack(); - } - - #[cfg(windows)] - unsafe { - if env::var("RUSTC_BREAK_ON_ICE").is_ok() { - extern "system" { - fn DebugBreak(); - } - // Trigger a debugger if we crashed during bootstrap. - DebugBreak(); - } - } -} - -pub fn install_panic_hook() { - lazy_static::initialize(&DEFAULT_HOOK); -} - /// Parameters to the `Dump` variant of type `ProfileQueriesMsg`. #[derive(Clone,Debug)] pub struct ProfQDumpParams { diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 5b7ac14ba3585..ece82233e9951 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -38,8 +38,8 @@ use rustc::session::{early_error, early_warn}; use rustc::lint::Lint; use rustc::lint; use rustc::hir::def_id::LOCAL_CRATE; -use rustc::util::common::{ErrorReported, install_panic_hook, print_time_passes_entry}; -use rustc::util::common::{set_time_depth, time}; +use rustc::ty::TyCtxt; +use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorReported}; use rustc_metadata::locator; use rustc_metadata::cstore::CStore; use rustc_codegen_utils::codegen_backend::CodegenBackend; @@ -164,8 +164,6 @@ pub fn run_compiler( None => return Ok(()), }; - install_panic_hook(); - let (sopts, cfg) = config::build_session_options_and_crate_config(&matches); let mut dummy_config = |sopts, cfg, diagnostic_output| { @@ -1169,9 +1167,10 @@ lazy_static! { } pub fn report_ice(info: &panic::PanicInfo<'_>) { + // Invoke the default handler, which prints the actual panic message and optionally a backtrace (*DEFAULT_HOOK)(info); - // Thread panicked without emitting a fatal diagnostic + // Print the infamous ICE message eprintln!(); let emitter = Box::new(errors::emitter::EmitterWriter::stderr( @@ -1212,6 +1211,24 @@ pub fn report_ice(info: &panic::PanicInfo<'_>) { note, errors::Level::Note); } + + // If backtraces are enabled, also print the query stack + let backtrace = env::var_os("RUST_BACKTRACE").map(|x| &x != "0").unwrap_or(false); + + if backtrace { + TyCtxt::try_print_query_stack(); + } + + #[cfg(windows)] + unsafe { + if env::var("RUSTC_BREAK_ON_ICE").is_ok() { + extern "system" { + fn DebugBreak(); + } + // Trigger a debugger if we crashed during bootstrap + DebugBreak(); + } + } } pub fn install_ice_hook() { From 035333993d09df69dd82723881b05cda5f0cde07 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 10 May 2019 17:44:25 +0200 Subject: [PATCH 033/462] Clarify that rustc unwinds on errors, not panics --- src/librustc_driver/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index ece82233e9951..0fd00af0bd03d 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1145,7 +1145,7 @@ fn extra_compiler_flags() -> Option<(Vec, bool)> { /// Runs a closure and catches unwinds triggered by fatal errors. /// -/// The compiler currently panics with a special sentinel value to abort +/// The compiler currently unwinds with a special sentinel value to abort /// compilation on fatal errors. This function catches that sentinel and turns /// the panic into a `Result` instead. pub fn catch_fatal_errors R, R>(f: F) -> Result { From 3e2d4d28b1c1a96e7c7482ae3e82fbf81505e8a7 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 26 Jul 2019 23:31:02 +0200 Subject: [PATCH 034/462] Document the ICE hook and make it more flexible --- src/librustc_driver/lib.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 0fd00af0bd03d..97542a0e84ed0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1161,12 +1161,18 @@ pub fn catch_fatal_errors R, R>(f: F) -> Result lazy_static! { static ref DEFAULT_HOOK: Box) + Sync + Send + 'static> = { let hook = panic::take_hook(); - panic::set_hook(Box::new(report_ice)); + panic::set_hook(Box::new(|info| report_ice(info, BUG_REPORT_URL))); hook }; } -pub fn report_ice(info: &panic::PanicInfo<'_>) { +/// Prints the ICE message, including backtrace and query stack. +/// +/// The message will point the user at `bug_report_url` to report the ICE. +/// +/// When `install_ice_hook` is called, this function will be called as the panic +/// hook. +pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { // Invoke the default handler, which prints the actual panic message and optionally a backtrace (*DEFAULT_HOOK)(info); @@ -1192,7 +1198,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>) { let mut xs: Vec> = vec![ "the compiler unexpectedly panicked. this is a bug.".into(), - format!("we would appreciate a bug report: {}", BUG_REPORT_URL).into(), + format!("we would appreciate a bug report: {}", bug_report_url).into(), format!("rustc {} running on {}", option_env!("CFG_VERSION").unwrap_or("unknown_version"), config::host_triple()).into(), @@ -1231,6 +1237,9 @@ pub fn report_ice(info: &panic::PanicInfo<'_>) { } } +/// Installs a panic hook that will print the ICE message on unexpected panics. +/// +/// A custom rustc driver can skip calling this to set up a custom ICE hook. pub fn install_ice_hook() { lazy_static::initialize(&DEFAULT_HOOK); } From cf1db72281134ab7375447f17bc2becb3943ee5d Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 27 Jul 2019 16:38:52 +0200 Subject: [PATCH 035/462] Update comment --- src/librustc_driver/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 97542a0e84ed0..fe1ed10884a4d 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1176,7 +1176,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { // Invoke the default handler, which prints the actual panic message and optionally a backtrace (*DEFAULT_HOOK)(info); - // Print the infamous ICE message + // Separate the output with an empty line eprintln!(); let emitter = Box::new(errors::emitter::EmitterWriter::stderr( From 547f96f19c45c469a65f5f3862213165cf899d54 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sun, 4 Aug 2019 14:59:13 +0200 Subject: [PATCH 036/462] Update proc-macro tests Due to #59998, the panic hook fires incorrectly for errors that should not be treated as ICEs. Previously, this would only print the default panic message, but moving the ICE printing into the panic handler will now print the entire ICE ordeal we all hate to see. Unfortunately this will make #59998 a lot more visible. --- src/test/ui/proc-macro/invalid-punct-ident-1.rs | 5 +++++ src/test/ui/proc-macro/invalid-punct-ident-1.stderr | 2 +- src/test/ui/proc-macro/invalid-punct-ident-2.rs | 5 +++++ src/test/ui/proc-macro/invalid-punct-ident-2.stderr | 2 +- src/test/ui/proc-macro/invalid-punct-ident-3.rs | 5 +++++ src/test/ui/proc-macro/invalid-punct-ident-3.stderr | 2 +- 6 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/test/ui/proc-macro/invalid-punct-ident-1.rs b/src/test/ui/proc-macro/invalid-punct-ident-1.rs index c9881ad2c38af..3b6498b4b0ee9 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-1.rs +++ b/src/test/ui/proc-macro/invalid-punct-ident-1.rs @@ -3,6 +3,11 @@ // FIXME https://github.com/rust-lang/rust/issues/59998 // normalize-stderr-test "thread.*panicked.*proc_macro_server.rs.*\n" -> "" // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +// normalize-stderr-test "error: internal compiler error.*\n" -> "" +// normalize-stderr-test "note:.*unexpectedly panicked.*\n" -> "" +// normalize-stderr-test "note: we would appreciate a bug report.*\n" -> "" +// normalize-stderr-test "note: compiler flags.*\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*\n" -> "" #[macro_use] extern crate invalid_punct_ident; diff --git a/src/test/ui/proc-macro/invalid-punct-ident-1.stderr b/src/test/ui/proc-macro/invalid-punct-ident-1.stderr index 40333a3f4c211..107f5fb515b1c 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-1.stderr +++ b/src/test/ui/proc-macro/invalid-punct-ident-1.stderr @@ -1,5 +1,5 @@ error: proc macro panicked - --> $DIR/invalid-punct-ident-1.rs:10:1 + --> $DIR/invalid-punct-ident-1.rs:15:1 | LL | invalid_punct!(); | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/proc-macro/invalid-punct-ident-2.rs b/src/test/ui/proc-macro/invalid-punct-ident-2.rs index 15e2286a65049..ee57752e2be27 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-2.rs +++ b/src/test/ui/proc-macro/invalid-punct-ident-2.rs @@ -3,6 +3,11 @@ // FIXME https://github.com/rust-lang/rust/issues/59998 // normalize-stderr-test "thread.*panicked.*proc_macro_server.rs.*\n" -> "" // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +// normalize-stderr-test "error: internal compiler error.*\n" -> "" +// normalize-stderr-test "note:.*unexpectedly panicked.*\n" -> "" +// normalize-stderr-test "note: we would appreciate a bug report.*\n" -> "" +// normalize-stderr-test "note: compiler flags.*\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*\n" -> "" #[macro_use] extern crate invalid_punct_ident; diff --git a/src/test/ui/proc-macro/invalid-punct-ident-2.stderr b/src/test/ui/proc-macro/invalid-punct-ident-2.stderr index ec97e265c3fcd..f1b9ecc6cbfe4 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-2.stderr +++ b/src/test/ui/proc-macro/invalid-punct-ident-2.stderr @@ -1,5 +1,5 @@ error: proc macro panicked - --> $DIR/invalid-punct-ident-2.rs:10:1 + --> $DIR/invalid-punct-ident-2.rs:15:1 | LL | invalid_ident!(); | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/proc-macro/invalid-punct-ident-3.rs b/src/test/ui/proc-macro/invalid-punct-ident-3.rs index 629bbaa9e3888..efcd6801ecbdd 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-3.rs +++ b/src/test/ui/proc-macro/invalid-punct-ident-3.rs @@ -3,6 +3,11 @@ // FIXME https://github.com/rust-lang/rust/issues/59998 // normalize-stderr-test "thread.*panicked.*proc_macro_server.rs.*\n" -> "" // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +// normalize-stderr-test "error: internal compiler error.*\n" -> "" +// normalize-stderr-test "note:.*unexpectedly panicked.*\n" -> "" +// normalize-stderr-test "note: we would appreciate a bug report.*\n" -> "" +// normalize-stderr-test "note: compiler flags.*\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*\n" -> "" #[macro_use] extern crate invalid_punct_ident; diff --git a/src/test/ui/proc-macro/invalid-punct-ident-3.stderr b/src/test/ui/proc-macro/invalid-punct-ident-3.stderr index a5e5ded65333a..6044b9887401e 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-3.stderr +++ b/src/test/ui/proc-macro/invalid-punct-ident-3.stderr @@ -1,5 +1,5 @@ error: proc macro panicked - --> $DIR/invalid-punct-ident-3.rs:10:1 + --> $DIR/invalid-punct-ident-3.rs:15:1 | LL | invalid_raw_ident!(); | ^^^^^^^^^^^^^^^^^^^^^ From eefae7b1a9980b10f9b44a3ed14e47cf062b0c96 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 19 Aug 2019 22:56:02 +0200 Subject: [PATCH 037/462] Update Cargo.lock --- Cargo.lock | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 179bf59388a29..91ff6cd1006ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2844,7 +2844,6 @@ dependencies = [ "fmt_macros", "graphviz", "jobserver", - "lazy_static 1.3.0", "log", "measureme", "num_cpus", From 9fd203a01e0fe6fb307809fdfdbfcd3bda350cfc Mon Sep 17 00:00:00 2001 From: newpavlov Date: Fri, 30 Aug 2019 17:30:33 +0300 Subject: [PATCH 038/462] simplify code --- src/libstd/sys/wasi/thread.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index 987bf7580838b..28a504f197974 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -46,11 +46,18 @@ impl Thread { type_: wasi::EVENTTYPE_CLOCK, u: wasi::raw::__wasi_subscription_u { clock: clock }, }]; - let mut out: [wasi::Event; 1] = [unsafe { mem::zeroed() }]; - let n = unsafe { wasi::poll_oneoff(&in_, &mut out).unwrap() }; - let wasi::Event { userdata, error, type_, .. } = out[0]; - match (n, userdata, error) { - (1, CLOCK_ID, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} + let (res, event) = unsafe { + let mut out: [wasi::Event; 1] = mem::zeroed(); + let res = wasi::poll_oneoff(&in_, &mut out); + (res, out[0]) + }; + match (res, event) { + (Ok(1), wasi::Event { + userdata: CLOCK_ID, + error: 0, + type_: wasi::EVENTTYPE_CLOCK, + .. + }) => {} _ => panic!("thread::sleep(): unexpected result of poll_oneoff"), } } From 403701f97628b85bfa3e5ec0e5ca82b81d53ba1e Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 30 Aug 2019 11:51:04 -0700 Subject: [PATCH 039/462] Don't try to use /dev/null on Fuchsia --- src/libstd/sys/unix/process/process_common.rs | 28 +++++++++++++++++-- .../sys/unix/process/process_fuchsia.rs | 15 ++++++---- src/libstd/sys/unix/process/zircon.rs | 2 +- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 6bb20bbe08794..511e67840803e 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -1,19 +1,27 @@ use crate::os::unix::prelude::*; -use crate::ffi::{OsString, OsStr, CString, CStr}; +use crate::ffi::{OsString, OsStr, CString}; use crate::fmt; use crate::io; use crate::ptr; use crate::sys::fd::FileDesc; -use crate::sys::fs::{File, OpenOptions}; +use crate::sys::fs::File; use crate::sys::pipe::{self, AnonPipe}; use crate::sys_common::process::{CommandEnv, DefaultEnvKey}; use crate::collections::BTreeMap; +#[cfg(not(target_os = "fuchsia"))] +use { + crate::ffi::CStr, + crate::sys::fs::OpenOptions, +}; + use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE}; cfg_if::cfg_if! { - if #[cfg(target_os = "redox")] { + if #[cfg(target_os = "fuchsia")] { + // fuchsia doesn't have /dev/null + } else if #[cfg(target_os = "redox")] { const DEV_NULL: &'static str = "null:\0"; } else { const DEV_NULL: &'static str = "/dev/null\0"; @@ -83,6 +91,11 @@ pub enum ChildStdio { Inherit, Explicit(c_int), Owned(FileDesc), + + // On Fuchsia, null stdio is the default, so we simply don't specify + // any actions at the time of spawning. + #[cfg(target_os = "fuchsia")] + Null, } pub enum Stdio { @@ -301,6 +314,7 @@ impl Stdio { Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours))) } + #[cfg(not(target_os = "fuchsia"))] Stdio::Null => { let mut opts = OpenOptions::new(); opts.read(readable); @@ -311,6 +325,11 @@ impl Stdio { let fd = File::open_c(&path, &opts)?; Ok((ChildStdio::Owned(fd.into_fd()), None)) } + + #[cfg(target_os = "fuchsia")] + Stdio::Null => { + Ok((ChildStdio::Null, None)) + } } } } @@ -333,6 +352,9 @@ impl ChildStdio { ChildStdio::Inherit => None, ChildStdio::Explicit(fd) => Some(fd), ChildStdio::Owned(ref fd) => Some(fd.raw()), + + #[cfg(target_os = "fuchsia")] + ChildStdio::Null => None, } } } diff --git a/src/libstd/sys/unix/process/process_fuchsia.rs b/src/libstd/sys/unix/process/process_fuchsia.rs index 7c6be9b0a6047..295ec59eb32cf 100644 --- a/src/libstd/sys/unix/process/process_fuchsia.rs +++ b/src/libstd/sys/unix/process/process_fuchsia.rs @@ -52,7 +52,7 @@ impl Command { None => ptr::null(), }; - let transfer_or_clone = |opt_fd, target_fd| if let Some(local_fd) = opt_fd { + let make_action = |local_io: &ChildStdio, target_fd| if let Some(local_fd) = local_io.fd() { fdio_spawn_action_t { action: FDIO_SPAWN_ACTION_TRANSFER_FD, local_fd, @@ -60,6 +60,10 @@ impl Command { ..Default::default() } } else { + if let ChildStdio::Null = local_io { + // acts as no-op + return Default::default(); + } fdio_spawn_action_t { action: FDIO_SPAWN_ACTION_CLONE_FD, local_fd: target_fd, @@ -69,9 +73,9 @@ impl Command { }; // Clone stdin, stdout, and stderr - let action1 = transfer_or_clone(stdio.stdin.fd(), 0); - let action2 = transfer_or_clone(stdio.stdout.fd(), 1); - let action3 = transfer_or_clone(stdio.stderr.fd(), 2); + let action1 = make_action(&stdio.stdin, 0); + let action2 = make_action(&stdio.stdout, 1); + let action3 = make_action(&stdio.stderr, 2); let actions = [action1, action2, action3]; // We don't want FileDesc::drop to be called on any stdio. fdio_spawn_etc @@ -86,7 +90,8 @@ impl Command { zx_cvt(fdio_spawn_etc( 0, FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE, - self.get_argv()[0], self.get_argv().as_ptr(), envp, 3, actions.as_ptr(), + self.get_argv()[0], self.get_argv().as_ptr(), envp, + actions.len() as size_t, actions.as_ptr(), &mut process_handle, ptr::null_mut(), ))?; diff --git a/src/libstd/sys/unix/process/zircon.rs b/src/libstd/sys/unix/process/zircon.rs index 9224bef7c4a5f..29032f5e0d200 100644 --- a/src/libstd/sys/unix/process/zircon.rs +++ b/src/libstd/sys/unix/process/zircon.rs @@ -120,7 +120,7 @@ pub struct fdio_spawn_action_t { extern { pub fn fdio_spawn_etc(job: zx_handle_t, flags: u32, path: *const c_char, argv: *const *const c_char, envp: *const *const c_char, - action_count: u64, actions: *const fdio_spawn_action_t, + action_count: size_t, actions: *const fdio_spawn_action_t, process: *mut zx_handle_t, err_msg: *mut c_char) -> zx_status_t; } From 3f6db849f7270b9126e6609a87058c1bc3aef1da Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 30 Aug 2019 14:05:39 -0500 Subject: [PATCH 040/462] actually compiles now? --- src/tools/rustbook/src/main.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs index e155f3f7607f3..b2111442310ef 100644 --- a/src/tools/rustbook/src/main.rs +++ b/src/tools/rustbook/src/main.rs @@ -60,11 +60,14 @@ fn main() { #[cfg(feature = "linkcheck")] { err.downcast::() + .map(|broken_links| { + broken_links + .links() + .iter() + .inspect(|cause| eprintln!("\tCaused By: {}", cause)) + .any(|cause| !format!("{}", cause).contains("timed out")) + }) .unwrap_or(false) - .links() - .iter() - .inspect(|cause| eprintln!("\tCaused By: {}", cause)) - .any(|cause| !cause.contains("timed out")); } #[cfg(not(feature = "linkcheck"))] From 3cc8087c4849fcbb8eeae208ace59bdf9b156ca8 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 29 Aug 2019 08:52:13 +0200 Subject: [PATCH 041/462] qualify_consts: extractt 'determine_mode'. --- src/librustc_mir/transform/qualify_consts.rs | 49 ++++++++++---------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index a77421ce15008..959d21ecfadeb 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -30,6 +30,7 @@ use std::fmt; use std::ops::{Deref, Index, IndexMut}; use std::usize; +use rustc::hir::HirId; use crate::transform::{MirPass, MirSource}; use super::promote_consts::{self, Candidate, TempState}; @@ -1596,27 +1597,12 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> { } let def_id = src.def_id(); - let id = tcx.hir().as_local_hir_id(def_id).unwrap(); - let mut const_promoted_temps = None; - let mode = match tcx.hir().body_owner_kind(id) { - hir::BodyOwnerKind::Closure => Mode::NonConstFn, - hir::BodyOwnerKind::Fn => { - if tcx.is_const_fn(def_id) { - Mode::ConstFn - } else { - Mode::NonConstFn - } - } - hir::BodyOwnerKind::Const => { - const_promoted_temps = Some(tcx.mir_const_qualif(def_id).1); - Mode::Const - } - hir::BodyOwnerKind::Static(hir::MutImmutable) => Mode::Static, - hir::BodyOwnerKind::Static(hir::MutMutable) => Mode::StaticMut, - }; + let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); + + let mode = determine_mode(tcx, hir_id, def_id); debug!("run_pass: mode={:?}", mode); - if mode == Mode::NonConstFn || mode == Mode::ConstFn { + if let Mode::NonConstFn | Mode::ConstFn = mode { // This is ugly because Checker holds onto mir, // which can't be mutated until its scope ends. let (temps, candidates) = { @@ -1664,6 +1650,11 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> { promote_consts::promote_candidates(def_id, body, tcx, temps, candidates) ); } else { + let const_promoted_temps = match mode { + Mode::Const => Some(tcx.mir_const_qualif(def_id).1), + _ => None, + }; + if !body.control_flow_destroyed.is_empty() { let mut locals = body.vars_iter(); if let Some(local) = locals.next() { @@ -1695,11 +1686,10 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> { error.emit(); } } - let promoted_temps = if mode == Mode::Const { + let promoted_temps = match mode { // Already computed by `mir_const_qualif`. - const_promoted_temps.unwrap() - } else { - Checker::new(tcx, def_id, body, mode).check_const().1 + Mode::Const => const_promoted_temps.unwrap(), + _ => Checker::new(tcx, def_id, body, mode).check_const().1, }; // In `const` and `static` everything without `StorageDead` @@ -1747,7 +1737,7 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> { let ty = body.return_ty(); tcx.infer_ctxt().enter(|infcx| { let param_env = ty::ParamEnv::empty(); - let cause = traits::ObligationCause::new(body.span, id, traits::SharedStatic); + let cause = traits::ObligationCause::new(body.span, hir_id, traits::SharedStatic); let mut fulfillment_cx = traits::FulfillmentContext::new(); fulfillment_cx.register_bound(&infcx, param_env, @@ -1765,6 +1755,17 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> { } } +fn determine_mode(tcx: TyCtxt<'_>, hir_id: HirId, def_id: DefId) -> Mode { + match tcx.hir().body_owner_kind(hir_id) { + hir::BodyOwnerKind::Closure => Mode::NonConstFn, + hir::BodyOwnerKind::Fn if tcx.is_const_fn(def_id) => Mode::ConstFn, + hir::BodyOwnerKind::Fn => Mode::NonConstFn, + hir::BodyOwnerKind::Const => Mode::Const, + hir::BodyOwnerKind::Static(hir::MutImmutable) => Mode::Static, + hir::BodyOwnerKind::Static(hir::MutMutable) => Mode::StaticMut, + } +} + fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { let attrs = tcx.get_attrs(def_id); let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?; From 8f184b369d6332195ef61f0395cf32bd787e4368 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 29 Aug 2019 08:58:52 +0200 Subject: [PATCH 042/462] qualify_consts: misc cleanup. --- src/librustc_mir/transform/qualify_consts.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 959d21ecfadeb..fcbb3433a62d9 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1714,12 +1714,8 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> { }, target, .. - } => { - if promoted_temps.contains(index) { - terminator.kind = TerminatorKind::Goto { - target, - }; - } + } if promoted_temps.contains(index) => { + terminator.kind = TerminatorKind::Goto { target }; } _ => {} } @@ -1727,7 +1723,7 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> { } // Statics must be Sync. - if mode == Mode::Static { + if let Mode::Static = mode { // `#[thread_local]` statics don't have to be `Sync`. for attr in &tcx.get_attrs(def_id)[..] { if attr.check_name(sym::thread_local) { From b6360fbc4c6d3898d51dfcbe9b042fef515133d1 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 29 Aug 2019 09:10:26 +0200 Subject: [PATCH 043/462] qualify_consts: extract check_short_circuiting_in_const_local. --- src/librustc_mir/transform/qualify_consts.rs | 66 +++++++++++--------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index fcbb3433a62d9..0a9e2a5974300 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1655,37 +1655,8 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> { _ => None, }; - if !body.control_flow_destroyed.is_empty() { - let mut locals = body.vars_iter(); - if let Some(local) = locals.next() { - let span = body.local_decls[local].source_info.span; - let mut error = tcx.sess.struct_span_err( - span, - &format!( - "new features like let bindings are not permitted in {}s \ - which also use short circuiting operators", - mode, - ), - ); - for (span, kind) in body.control_flow_destroyed.iter() { - error.span_note( - *span, - &format!("use of {} here does not actually short circuit due to \ - the const evaluator presently not being able to do control flow. \ - See https://github.com/rust-lang/rust/issues/49146 for more \ - information.", kind), - ); - } - for local in locals { - let span = body.local_decls[local].source_info.span; - error.span_note( - span, - "more locals defined here", - ); - } - error.emit(); - } - } + check_short_circuiting_in_const_local(tcx, body, mode); + let promoted_temps = match mode { // Already computed by `mir_const_qualif`. Mode::Const => const_promoted_temps.unwrap(), @@ -1762,6 +1733,39 @@ fn determine_mode(tcx: TyCtxt<'_>, hir_id: HirId, def_id: DefId) -> Mode { } } +fn check_short_circuiting_in_const_local(tcx: TyCtxt<'_>, body: &mut Body<'tcx>, mode: Mode) { + if body.control_flow_destroyed.is_empty() { + return; + } + + let mut locals = body.vars_iter(); + if let Some(local) = locals.next() { + let span = body.local_decls[local].source_info.span; + let mut error = tcx.sess.struct_span_err( + span, + &format!( + "new features like let bindings are not permitted in {}s \ + which also use short circuiting operators", + mode, + ), + ); + for (span, kind) in body.control_flow_destroyed.iter() { + error.span_note( + *span, + &format!("use of {} here does not actually short circuit due to \ + the const evaluator presently not being able to do control flow. \ + See https://github.com/rust-lang/rust/issues/49146 for more \ + information.", kind), + ); + } + for local in locals { + let span = body.local_decls[local].source_info.span; + error.span_note(span, "more locals defined here"); + } + error.emit(); + } +} + fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { let attrs = tcx.get_attrs(def_id); let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?; From c1d440070e088c6b239bcf5f9f22dfc6d5b2b639 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 29 Aug 2019 09:15:59 +0200 Subject: [PATCH 044/462] qualify_consts: fuse prompted_temps. --- src/librustc_mir/transform/qualify_consts.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 0a9e2a5974300..b052d1e9bb468 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1650,16 +1650,10 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> { promote_consts::promote_candidates(def_id, body, tcx, temps, candidates) ); } else { - let const_promoted_temps = match mode { - Mode::Const => Some(tcx.mir_const_qualif(def_id).1), - _ => None, - }; - check_short_circuiting_in_const_local(tcx, body, mode); let promoted_temps = match mode { - // Already computed by `mir_const_qualif`. - Mode::Const => const_promoted_temps.unwrap(), + Mode::Const => tcx.mir_const_qualif(def_id).1, _ => Checker::new(tcx, def_id, body, mode).check_const().1, }; From 7bfa2be4efa2d4649e8db7548f1980156d58017e Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 30 Aug 2019 18:21:57 -0700 Subject: [PATCH 045/462] fuchsia: Don't fail to spawn if no stdin exists --- .../sys/unix/process/process_fuchsia.rs | 57 ++++++++++++------- src/libstd/sys/unix/process/zircon.rs | 6 +- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/src/libstd/sys/unix/process/process_fuchsia.rs b/src/libstd/sys/unix/process/process_fuchsia.rs index 295ec59eb32cf..2b3795292f42a 100644 --- a/src/libstd/sys/unix/process/process_fuchsia.rs +++ b/src/libstd/sys/unix/process/process_fuchsia.rs @@ -52,30 +52,45 @@ impl Command { None => ptr::null(), }; - let make_action = |local_io: &ChildStdio, target_fd| if let Some(local_fd) = local_io.fd() { - fdio_spawn_action_t { - action: FDIO_SPAWN_ACTION_TRANSFER_FD, - local_fd, - target_fd, - ..Default::default() - } - } else { - if let ChildStdio::Null = local_io { - // acts as no-op - return Default::default(); - } - fdio_spawn_action_t { - action: FDIO_SPAWN_ACTION_CLONE_FD, - local_fd: target_fd, - target_fd, - ..Default::default() + let make_action = |local_io: &ChildStdio, target_fd| -> io::Result { + if let Some(local_fd) = local_io.fd() { + Ok(fdio_spawn_action_t { + action: FDIO_SPAWN_ACTION_TRANSFER_FD, + local_fd, + target_fd, + ..Default::default() + }) + } else { + if let ChildStdio::Null = local_io { + // acts as no-op + return Ok(Default::default()); + } + + let mut handle = ZX_HANDLE_INVALID; + let status = fdio_fd_clone(target_fd, &mut handle); + if status == ERR_INVALID_ARGS || status == ERR_NOT_SUPPORTED { + // This descriptor is closed; skip it rather than generating an + // error. + return Ok(Default::default()); + } + zx_cvt(status)?; + + let mut cloned_fd = 0; + zx_cvt(fdio_fd_create(handle, &mut cloned_fd))?; + + Ok(fdio_spawn_action_t { + action: FDIO_SPAWN_ACTION_TRANSFER_FD, + local_fd: cloned_fd as i32, + target_fd, + ..Default::default() + }) } }; // Clone stdin, stdout, and stderr - let action1 = make_action(&stdio.stdin, 0); - let action2 = make_action(&stdio.stdout, 1); - let action3 = make_action(&stdio.stderr, 2); + let action1 = make_action(&stdio.stdin, 0)?; + let action2 = make_action(&stdio.stdout, 1)?; + let action3 = make_action(&stdio.stderr, 2)?; let actions = [action1, action2, action3]; // We don't want FileDesc::drop to be called on any stdio. fdio_spawn_etc @@ -88,7 +103,7 @@ impl Command { let mut process_handle: zx_handle_t = 0; zx_cvt(fdio_spawn_etc( - 0, + ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE, self.get_argv()[0], self.get_argv().as_ptr(), envp, actions.len() as size_t, actions.as_ptr(), diff --git a/src/libstd/sys/unix/process/zircon.rs b/src/libstd/sys/unix/process/zircon.rs index 29032f5e0d200..1ba48de3c0785 100644 --- a/src/libstd/sys/unix/process/zircon.rs +++ b/src/libstd/sys/unix/process/zircon.rs @@ -2,8 +2,9 @@ use crate::convert::TryInto; use crate::io; -use crate::os::raw::c_char; use crate::i64; +use crate::mem::MaybeUninit; +use crate::os::raw::c_char; use libc::{c_int, c_void, size_t}; @@ -122,6 +123,9 @@ extern { argv: *const *const c_char, envp: *const *const c_char, action_count: size_t, actions: *const fdio_spawn_action_t, process: *mut zx_handle_t, err_msg: *mut c_char) -> zx_status_t; + + pub fn fdio_fd_clone(fd: c_int, out_handle: *mut zx_handle_t) -> zx_status_t; + pub fn fdio_fd_create(handle: zx_handle_t, fd: *mut c_int) -> zx_status_t; } // fdio_spawn_etc flags From 5f91ad0e3300c36033bf409ceefb00480fecbed3 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 30 Aug 2019 18:52:19 -0700 Subject: [PATCH 046/462] fuchsia: Fix default environment behavior when spawning --- src/libstd/sys/unix/process/process_fuchsia.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/process/process_fuchsia.rs b/src/libstd/sys/unix/process/process_fuchsia.rs index 2b3795292f42a..fff9fc6b3bbc8 100644 --- a/src/libstd/sys/unix/process/process_fuchsia.rs +++ b/src/libstd/sys/unix/process/process_fuchsia.rs @@ -48,8 +48,10 @@ impl Command { use crate::sys::process::zircon::*; let envp = match maybe_envp { - Some(envp) => envp.as_ptr(), + // None means to clone the current environment, which is done in the + // flags below. None => ptr::null(), + Some(envp) => envp.as_ptr(), }; let make_action = |local_io: &ChildStdio, target_fd| -> io::Result { @@ -104,7 +106,8 @@ impl Command { let mut process_handle: zx_handle_t = 0; zx_cvt(fdio_spawn_etc( ZX_HANDLE_INVALID, - FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE, + FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE + | FDIO_SPAWN_CLONE_ENVIRON, // this is ignored when envp is non-null self.get_argv()[0], self.get_argv().as_ptr(), envp, actions.len() as size_t, actions.as_ptr(), &mut process_handle, From 8af33b325377ea64fb9bbdc10073f9063293c9a6 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 29 Aug 2019 09:35:37 +0200 Subject: [PATCH 047/462] qualify_consts: extract check_non_thread_local_static_is_sync --- src/librustc_mir/transform/qualify_consts.rs | 49 ++++++++++---------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index b052d1e9bb468..dbb994183e9d5 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1687,31 +1687,9 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> { } } - // Statics must be Sync. if let Mode::Static = mode { - // `#[thread_local]` statics don't have to be `Sync`. - for attr in &tcx.get_attrs(def_id)[..] { - if attr.check_name(sym::thread_local) { - return; - } - } - let ty = body.return_ty(); - tcx.infer_ctxt().enter(|infcx| { - let param_env = ty::ParamEnv::empty(); - let cause = traits::ObligationCause::new(body.span, hir_id, traits::SharedStatic); - let mut fulfillment_cx = traits::FulfillmentContext::new(); - fulfillment_cx.register_bound(&infcx, - param_env, - ty, - tcx.require_lang_item( - lang_items::SyncTraitLangItem, - Some(body.span) - ), - cause); - if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) { - infcx.report_fulfillment_errors(&err, None, false); - } - }); + // `static`s (not `static mut`s) which are not `#[thread_local]` must be `Sync`. + check_non_thread_local_static_is_sync(tcx, body, def_id, hir_id); } } } @@ -1760,6 +1738,29 @@ fn check_short_circuiting_in_const_local(tcx: TyCtxt<'_>, body: &mut Body<'tcx>, } } +fn check_non_thread_local_static_is_sync( + tcx: TyCtxt<'tcx>, + body: &mut Body<'tcx>, + def_id: DefId, + hir_id: HirId, +) { + // `#[thread_local]` statics don't have to be `Sync`. + if tcx.has_attr(def_id, sym::thread_local) { + return; + } + + let ty = body.return_ty(); + tcx.infer_ctxt().enter(|infcx| { + let cause = traits::ObligationCause::new(body.span, hir_id, traits::SharedStatic); + let mut fulfillment_cx = traits::FulfillmentContext::new(); + let sync_def_id = tcx.require_lang_item(lang_items::SyncTraitLangItem, Some(body.span)); + fulfillment_cx.register_bound(&infcx, ty::ParamEnv::empty(), ty, sync_def_id, cause); + if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) { + infcx.report_fulfillment_errors(&err, None, false); + } + }); +} + fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { let attrs = tcx.get_attrs(def_id); let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?; From 2f733aad5a73b7cb8ceec37a8ecec497f8807034 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 29 Aug 2019 09:43:16 +0200 Subject: [PATCH 048/462] qualify_consts: extract remove_drop_and_storage_dead_on_promoted_locals. --- src/librustc_mir/transform/qualify_consts.rs | 63 +++++++++++--------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index dbb994183e9d5..fe02e120f3b49 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1656,35 +1656,7 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> { Mode::Const => tcx.mir_const_qualif(def_id).1, _ => Checker::new(tcx, def_id, body, mode).check_const().1, }; - - // In `const` and `static` everything without `StorageDead` - // is `'static`, we don't have to create promoted MIR fragments, - // just remove `Drop` and `StorageDead` on "promoted" locals. - debug!("run_pass: promoted_temps={:?}", promoted_temps); - for block in body.basic_blocks_mut() { - block.statements.retain(|statement| { - match statement.kind { - StatementKind::StorageDead(index) => { - !promoted_temps.contains(index) - } - _ => true - } - }); - let terminator = block.terminator_mut(); - match terminator.kind { - TerminatorKind::Drop { - location: Place { - base: PlaceBase::Local(index), - projection: None, - }, - target, - .. - } if promoted_temps.contains(index) => { - terminator.kind = TerminatorKind::Goto { target }; - } - _ => {} - } - } + remove_drop_and_storage_dead_on_promoted_locals(body, promoted_temps); } if let Mode::Static = mode { @@ -1738,6 +1710,39 @@ fn check_short_circuiting_in_const_local(tcx: TyCtxt<'_>, body: &mut Body<'tcx>, } } +/// In `const` and `static` everything without `StorageDead` +/// is `'static`, we don't have to create promoted MIR fragments, +/// just remove `Drop` and `StorageDead` on "promoted" locals. +fn remove_drop_and_storage_dead_on_promoted_locals( + body: &mut Body<'tcx>, + promoted_temps: &BitSet, +) { + debug!("run_pass: promoted_temps={:?}", promoted_temps); + + for block in body.basic_blocks_mut() { + block.statements.retain(|statement| { + match statement.kind { + StatementKind::StorageDead(index) => !promoted_temps.contains(index), + _ => true + } + }); + let terminator = block.terminator_mut(); + match terminator.kind { + TerminatorKind::Drop { + location: Place { + base: PlaceBase::Local(index), + projection: None, + }, + target, + .. + } if promoted_temps.contains(index) => { + terminator.kind = TerminatorKind::Goto { target }; + } + _ => {} + } + } +} + fn check_non_thread_local_static_is_sync( tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, From 9196af0b3647c29cb1c268ba9b01546df55fc004 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 29 Aug 2019 10:16:41 +0200 Subject: [PATCH 049/462] qualify_consts: extract error_min_const_fn_violation. --- src/librustc_mir/transform/qualify_consts.rs | 26 +++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index fe02e120f3b49..73475be24d445 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -25,6 +25,7 @@ use syntax::feature_gate::{emit_feature_err, GateIssue}; use syntax::symbol::sym; use syntax_pos::{Span, DUMMY_SP}; +use std::borrow::Cow; use std::cell::Cell; use std::fmt; use std::ops::{Deref, Index, IndexMut}; @@ -1607,26 +1608,14 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> { // which can't be mutated until its scope ends. let (temps, candidates) = { let mut checker = Checker::new(tcx, def_id, body, mode); - if mode == Mode::ConstFn { + if let Mode::ConstFn = mode { if tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you { checker.check_const(); } else if tcx.is_min_const_fn(def_id) { - // enforce `min_const_fn` for stable const fns + // Enforce `min_const_fn` for stable `const fn`s. use super::qualify_min_const_fn::is_min_const_fn; if let Err((span, err)) = is_min_const_fn(tcx, def_id, body) { - let mut diag = struct_span_err!( - tcx.sess, - span, - E0723, - "{}", - err, - ); - diag.note("for more information, see issue \ - https://github.com/rust-lang/rust/issues/57563"); - diag.help( - "add `#![feature(const_fn)]` to the crate attributes to enable", - ); - diag.emit(); + error_min_const_fn_violation(tcx, span, err); } else { // this should not produce any errors, but better safe than sorry // FIXME(#53819) @@ -1677,6 +1666,13 @@ fn determine_mode(tcx: TyCtxt<'_>, hir_id: HirId, def_id: DefId) -> Mode { } } +fn error_min_const_fn_violation(tcx: TyCtxt<'_>, span: Span, msg: Cow<'_, str>) { + struct_span_err!(tcx.sess, span, E0723, "{}", msg) + .note("for more information, see issue https://github.com/rust-lang/rust/issues/57563") + .help("add `#![feature(const_fn)]` to the crate attributes to enable") + .emit(); +} + fn check_short_circuiting_in_const_local(tcx: TyCtxt<'_>, body: &mut Body<'tcx>, mode: Mode) { if body.control_flow_destroyed.is_empty() { return; From 0a8a3dd88a1216e7487b8e39179fbac16d07bafe Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 31 Aug 2019 06:17:10 +0200 Subject: [PATCH 050/462] qualify_consts: move thread_local condition out. --- src/librustc_mir/transform/qualify_consts.rs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 73475be24d445..32b49ee942300 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1648,9 +1648,9 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> { remove_drop_and_storage_dead_on_promoted_locals(body, promoted_temps); } - if let Mode::Static = mode { + if mode == Mode::Static && !tcx.has_attr(def_id, sym::thread_local) { // `static`s (not `static mut`s) which are not `#[thread_local]` must be `Sync`. - check_non_thread_local_static_is_sync(tcx, body, def_id, hir_id); + check_static_is_sync(tcx, body, hir_id); } } } @@ -1739,17 +1739,7 @@ fn remove_drop_and_storage_dead_on_promoted_locals( } } -fn check_non_thread_local_static_is_sync( - tcx: TyCtxt<'tcx>, - body: &mut Body<'tcx>, - def_id: DefId, - hir_id: HirId, -) { - // `#[thread_local]` statics don't have to be `Sync`. - if tcx.has_attr(def_id, sym::thread_local) { - return; - } - +fn check_static_is_sync(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, hir_id: HirId) { let ty = body.return_ty(); tcx.infer_ctxt().enter(|infcx| { let cause = traits::ObligationCause::new(body.span, hir_id, traits::SharedStatic); From 6ed50f4777b65f117648dc2f524d684424c2730d Mon Sep 17 00:00:00 2001 From: Joe Ranweiler Date: Sat, 31 Aug 2019 20:00:08 -0700 Subject: [PATCH 051/462] Rename test locals to work around LLDB bug LLDB's expression parser can't unambiguously resolve local variables in some cases, as described in #47938. Work around this by using names that don't shadow direct submodules of `core`. --- src/test/debuginfo/boxed-struct.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/debuginfo/boxed-struct.rs b/src/test/debuginfo/boxed-struct.rs index c0ff90c3ffb9b..8709fb681704b 100644 --- a/src/test/debuginfo/boxed-struct.rs +++ b/src/test/debuginfo/boxed-struct.rs @@ -8,11 +8,11 @@ // gdb-command:run -// gdb-command:print *unique +// gdb-command:print *boxed_with_padding // gdbg-check:$1 = {x = 99, y = 999, z = 9999, w = 99999} // gdbr-check:$1 = boxed_struct::StructWithSomePadding {x: 99, y: 999, z: 9999, w: 99999} -// gdb-command:print *unique_dtor +// gdb-command:print *boxed_with_dtor // gdbg-check:$2 = {x = 77, y = 777, z = 7777, w = 77777} // gdbr-check:$2 = boxed_struct::StructWithDestructor {x: 77, y: 777, z: 7777, w: 77777} @@ -21,13 +21,13 @@ // lldb-command:run -// lldb-command:print *unique +// lldb-command:print *boxed_with_padding // lldbg-check:[...]$0 = StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 } -// lldbr-check:(boxed_struct::StructWithSomePadding) *unique = StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 } +// lldbr-check:(boxed_struct::StructWithSomePadding) *boxed_with_padding = StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 } -// lldb-command:print *unique_dtor +// lldb-command:print *boxed_with_dtor // lldbg-check:[...]$1 = StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 } -// lldbr-check:(boxed_struct::StructWithDestructor) *unique_dtor = StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 } +// lldbr-check:(boxed_struct::StructWithDestructor) *boxed_with_dtor = StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 } #![allow(unused_variables)] #![feature(box_syntax)] @@ -54,9 +54,9 @@ impl Drop for StructWithDestructor { fn main() { - let unique: Box<_> = box StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 }; + let boxed_with_padding: Box<_> = box StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 }; - let unique_dtor: Box<_> = box StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 }; + let boxed_with_dtor: Box<_> = box StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 }; zzz(); // #break } From 0c9aeba5f44b9ddb259154484d2ed6c270da6211 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 1 Sep 2019 10:09:45 -0400 Subject: [PATCH 052/462] Remove no-prefer-dynamic from valgrind tests --- src/test/run-pass-valgrind/cast-enum-with-dtor.rs | 2 -- src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs | 2 -- src/test/run-pass-valgrind/cleanup-stdin.rs | 2 -- src/test/run-pass-valgrind/down-with-thread-dtors.rs | 1 - src/test/run-pass-valgrind/dst-dtor-1.rs | 2 -- src/test/run-pass-valgrind/dst-dtor-2.rs | 2 -- src/test/run-pass-valgrind/dst-dtor-3.rs | 2 -- src/test/run-pass-valgrind/dst-dtor-4.rs | 2 -- src/test/run-pass-valgrind/exit-flushes.rs | 1 - src/test/run-pass-valgrind/osx-frameworks.rs | 1 - 10 files changed, 17 deletions(-) diff --git a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs index 42445b9056f9d..93c47d32f92a1 100644 --- a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs +++ b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs @@ -1,5 +1,3 @@ -// no-prefer-dynamic - #![allow(dead_code)] // check dtor calling order when casting enums. diff --git a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs index 925ffe75fe785..fb2b4d476355e 100644 --- a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs +++ b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs @@ -1,5 +1,3 @@ -// no-prefer-dynamic - // This would previously leak the Box because we wouldn't // schedule cleanups when auto borrowing trait objects. // This program should be valgrind clean. diff --git a/src/test/run-pass-valgrind/cleanup-stdin.rs b/src/test/run-pass-valgrind/cleanup-stdin.rs index 3505074293264..cf8f81cf5aa7c 100644 --- a/src/test/run-pass-valgrind/cleanup-stdin.rs +++ b/src/test/run-pass-valgrind/cleanup-stdin.rs @@ -1,5 +1,3 @@ -// no-prefer-dynamic - fn main() { let _ = std::io::stdin(); let _ = std::io::stdout(); diff --git a/src/test/run-pass-valgrind/down-with-thread-dtors.rs b/src/test/run-pass-valgrind/down-with-thread-dtors.rs index c3567a9b20097..8531b8d832604 100644 --- a/src/test/run-pass-valgrind/down-with-thread-dtors.rs +++ b/src/test/run-pass-valgrind/down-with-thread-dtors.rs @@ -1,4 +1,3 @@ -// no-prefer-dynamic // ignore-emscripten thread_local!(static FOO: Foo = Foo); diff --git a/src/test/run-pass-valgrind/dst-dtor-1.rs b/src/test/run-pass-valgrind/dst-dtor-1.rs index 7533a7bd2353b..5b8433f614567 100644 --- a/src/test/run-pass-valgrind/dst-dtor-1.rs +++ b/src/test/run-pass-valgrind/dst-dtor-1.rs @@ -1,5 +1,3 @@ -// no-prefer-dynamic - static mut DROP_RAN: bool = false; struct Foo; diff --git a/src/test/run-pass-valgrind/dst-dtor-2.rs b/src/test/run-pass-valgrind/dst-dtor-2.rs index ebf0c17fecb56..991fe00950bba 100644 --- a/src/test/run-pass-valgrind/dst-dtor-2.rs +++ b/src/test/run-pass-valgrind/dst-dtor-2.rs @@ -1,5 +1,3 @@ -// no-prefer-dynamic - static mut DROP_RAN: isize = 0; struct Foo; diff --git a/src/test/run-pass-valgrind/dst-dtor-3.rs b/src/test/run-pass-valgrind/dst-dtor-3.rs index e15908dfcc31f..f0c2dda5ab05b 100644 --- a/src/test/run-pass-valgrind/dst-dtor-3.rs +++ b/src/test/run-pass-valgrind/dst-dtor-3.rs @@ -1,5 +1,3 @@ -// no-prefer-dynamic - #![feature(unsized_tuple_coercion)] static mut DROP_RAN: bool = false; diff --git a/src/test/run-pass-valgrind/dst-dtor-4.rs b/src/test/run-pass-valgrind/dst-dtor-4.rs index 52bf0c364b24d..ad6d46f7c0886 100644 --- a/src/test/run-pass-valgrind/dst-dtor-4.rs +++ b/src/test/run-pass-valgrind/dst-dtor-4.rs @@ -1,5 +1,3 @@ -// no-prefer-dynamic - #![feature(unsized_tuple_coercion)] static mut DROP_RAN: isize = 0; diff --git a/src/test/run-pass-valgrind/exit-flushes.rs b/src/test/run-pass-valgrind/exit-flushes.rs index cd5edb84bdfe4..a68c6f3355644 100644 --- a/src/test/run-pass-valgrind/exit-flushes.rs +++ b/src/test/run-pass-valgrind/exit-flushes.rs @@ -1,4 +1,3 @@ -// no-prefer-dynamic // ignore-cloudabi // ignore-emscripten // ignore-sgx no processes diff --git a/src/test/run-pass-valgrind/osx-frameworks.rs b/src/test/run-pass-valgrind/osx-frameworks.rs index 4ea804a184474..ea1403645a515 100644 --- a/src/test/run-pass-valgrind/osx-frameworks.rs +++ b/src/test/run-pass-valgrind/osx-frameworks.rs @@ -1,4 +1,3 @@ -// no-prefer-dynamic // pretty-expanded FIXME #23616 #![feature(rustc_private)] From 7fdcbce499990498bca38ebce6b215206dcbb591 Mon Sep 17 00:00:00 2001 From: limira <20672976+limira@users.noreply.github.com> Date: Mon, 2 Sep 2019 00:14:58 +0700 Subject: [PATCH 053/462] Replace file_stem by file_name in rustdoc markdown --- src/librustdoc/markdown.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index a30fc05f36acd..401bd5f6e66c1 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -43,7 +43,7 @@ pub fn render( edition: Edition ) -> i32 { let mut output = options.output; - output.push(input.file_stem().unwrap()); + output.push(input.file_name().unwrap()); output.set_extension("html"); let mut css = String::new(); From 4dec571ec69e14673b4e185e9881e4b71cd42aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 1 Sep 2019 15:09:05 -0700 Subject: [PATCH 054/462] Be accurate on `format!` parse error expectations --- src/libsyntax_ext/format.rs | 16 ++++++++++++---- src/test/ui/codemap_tests/bad-format-args.rs | 2 +- src/test/ui/codemap_tests/bad-format-args.stderr | 4 ++-- src/test/ui/type/ascription/issue-54516.rs | 2 +- src/test/ui/type/ascription/issue-54516.stderr | 4 ++-- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 47394c02b4186..d9ca693aca504 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -138,15 +138,23 @@ fn parse_args<'a>( } let fmtstr = p.parse_expr()?; + let mut first = true; let mut named = false; while p.token != token::Eof { if !p.eat(&token::Comma) { - let mut err = ecx.struct_span_err(p.token.span, "expected token: `,`"); - err.span_label(p.token.span, "expected `,`"); - p.maybe_annotate_with_ascription(&mut err, false); - return Err(err); + if first { + // After `format!(""` we always expect *only* a comma... + let mut err = ecx.struct_span_err(p.token.span, "expected token: `,`"); + err.span_label(p.token.span, "expected `,`"); + p.maybe_annotate_with_ascription(&mut err, false); + return Err(err); + } else { + // ...after that delegate to `expect` to also include the other expected tokens. + return Err(p.expect(&token::Comma).err().unwrap()); + } } + first = false; if p.token == token::Eof { break; } // accept trailing commas diff --git a/src/test/ui/codemap_tests/bad-format-args.rs b/src/test/ui/codemap_tests/bad-format-args.rs index 9f90185774467..dff248344a53d 100644 --- a/src/test/ui/codemap_tests/bad-format-args.rs +++ b/src/test/ui/codemap_tests/bad-format-args.rs @@ -1,5 +1,5 @@ fn main() { format!(); //~ ERROR requires at least a format string argument format!("" 1); //~ ERROR expected token: `,` - format!("", 1 1); //~ ERROR expected token: `,` + format!("", 1 1); //~ ERROR expected one of } diff --git a/src/test/ui/codemap_tests/bad-format-args.stderr b/src/test/ui/codemap_tests/bad-format-args.stderr index 5b01314d8ad4f..3372ef6dea1fc 100644 --- a/src/test/ui/codemap_tests/bad-format-args.stderr +++ b/src/test/ui/codemap_tests/bad-format-args.stderr @@ -12,11 +12,11 @@ error: expected token: `,` LL | format!("" 1); | ^ expected `,` -error: expected token: `,` +error: expected one of `,`, `.`, `?`, or an operator, found `1` --> $DIR/bad-format-args.rs:4:19 | LL | format!("", 1 1); - | ^ expected `,` + | ^ expected one of `,`, `.`, `?`, or an operator here error: aborting due to 3 previous errors diff --git a/src/test/ui/type/ascription/issue-54516.rs b/src/test/ui/type/ascription/issue-54516.rs index 6d65760e299b5..b53bfe5df03f3 100644 --- a/src/test/ui/type/ascription/issue-54516.rs +++ b/src/test/ui/type/ascription/issue-54516.rs @@ -2,5 +2,5 @@ use std::collections::BTreeMap; fn main() { println!("{}", std::mem:size_of::>()); - //~^ ERROR expected token: `,` + //~^ ERROR expected one of } diff --git a/src/test/ui/type/ascription/issue-54516.stderr b/src/test/ui/type/ascription/issue-54516.stderr index a846f3bc320e6..97942904a0ffa 100644 --- a/src/test/ui/type/ascription/issue-54516.stderr +++ b/src/test/ui/type/ascription/issue-54516.stderr @@ -1,8 +1,8 @@ -error: expected token: `,` +error: expected one of `!`, `,`, or `::`, found `(` --> $DIR/issue-54516.rs:4:58 | LL | println!("{}", std::mem:size_of::>()); - | - ^ expected `,` + | - ^ expected one of `!`, `,`, or `::` here | | | help: maybe write a path separator here: `::` | From db576f8103ed0cdda4e77d977c1eab8456233e11 Mon Sep 17 00:00:00 2001 From: Baoshan Pang Date: Sun, 1 Sep 2019 17:56:36 -0700 Subject: [PATCH 055/462] vxWorks: set DEFAULT_MIN_STACK_SIZE to 256K and use min_stack to pass initial stack size to rtpSpawn --- src/libstd/sys/vxworks/process/process_vxworks.rs | 6 ++++-- src/libstd/sys/vxworks/thread.rs | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/vxworks/process/process_vxworks.rs b/src/libstd/sys/vxworks/process/process_vxworks.rs index b07966fa20626..12aa779746866 100644 --- a/src/libstd/sys/vxworks/process/process_vxworks.rs +++ b/src/libstd/sys/vxworks/process/process_vxworks.rs @@ -1,3 +1,5 @@ +// Copyright (c) 2019 Wind River Systems, Inc. + use crate::io::{self, Error, ErrorKind}; use libc::{self, c_int, c_char}; use libc::{RTP_ID}; @@ -5,6 +7,7 @@ use crate::sys; use crate::sys::cvt; use crate::sys::process::rtp; use crate::sys::process::process_common::*; +use crate::sys_common::thread; //////////////////////////////////////////////////////////////////////////////// // Command @@ -57,8 +60,7 @@ impl Command { self.get_argv().as_ptr() as *const _, // argv *sys::os::environ() as *const *const c_char, 100 as c_int, // initial priority - 0x16000, // initial stack size. 0 defaults - // to 0x4000 in 32 bit and 0x8000 in 64 bit + thread::min_stack(), // initial stack size. 0, // options 0 // task options ); diff --git a/src/libstd/sys/vxworks/thread.rs b/src/libstd/sys/vxworks/thread.rs index ef896f6a6e8cf..f9305afdeb6d1 100644 --- a/src/libstd/sys/vxworks/thread.rs +++ b/src/libstd/sys/vxworks/thread.rs @@ -1,3 +1,5 @@ +// Copyright (c) 2019 Wind River Systems, Inc. + use crate::cmp; use crate::ffi::CStr; use crate::io; @@ -8,7 +10,7 @@ use crate::time::Duration; use crate::sys_common::thread::*; -pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; +pub const DEFAULT_MIN_STACK_SIZE: usize = 0x40000; // 256K pub struct Thread { id: libc::pthread_t, From 991f4366336820a61dd7f22e849c57d4a64b41ea Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 2 Sep 2019 15:58:05 +0200 Subject: [PATCH 056/462] Fix regex replacement in theme detection --- src/librustdoc/html/static/storage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index 40a6a156972f6..eae998ca3ecbf 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -119,7 +119,7 @@ function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) { function getSystemValue() { var property = getComputedStyle(document.documentElement).getPropertyValue('content'); - return property.replace(/\"\'/g, ""); + return property.replace(/[\"\']/g, ""); } switchTheme(currentTheme, mainTheme, From 37f5cc22391e693523e8320a1d5c214610790911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 2 Sep 2019 18:03:54 -0700 Subject: [PATCH 057/462] Do not complain about unconstrained params when Self is Ty Error --- .../constrained_generic_params.rs | 18 ++++++++---------- src/librustc_typeck/impl_wf_check.rs | 4 ++++ src/test/ui/issues/issue-36836.rs | 5 +++++ src/test/ui/issues/issue-36836.stderr | 9 +++++++++ 4 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/issues/issue-36836.rs create mode 100644 src/test/ui/issues/issue-36836.stderr diff --git a/src/librustc_typeck/constrained_generic_params.rs b/src/librustc_typeck/constrained_generic_params.rs index 79a04b9423a8e..c95f81506cd59 100644 --- a/src/librustc_typeck/constrained_generic_params.rs +++ b/src/librustc_typeck/constrained_generic_params.rs @@ -20,10 +20,10 @@ impl From for Parameter { } /// Returns the set of parameters constrained by the impl header. -pub fn parameters_for_impl<'tcx>(impl_self_ty: Ty<'tcx>, - impl_trait_ref: Option>) - -> FxHashSet -{ +pub fn parameters_for_impl<'tcx>( + impl_self_ty: Ty<'tcx>, + impl_trait_ref: Option>, +) -> FxHashSet { let vec = match impl_trait_ref { Some(tr) => parameters_for(&tr, false), None => parameters_for(&impl_self_ty, false), @@ -36,12 +36,10 @@ pub fn parameters_for_impl<'tcx>(impl_self_ty: Ty<'tcx>, /// uniquely determined by `t` (see RFC 447). If it is true, return the list /// of parameters whose values are needed in order to constrain `ty` - these /// differ, with the latter being a superset, in the presence of projections. -pub fn parameters_for<'tcx, T>(t: &T, - include_nonconstraining: bool) - -> Vec - where T: TypeFoldable<'tcx> -{ - +pub fn parameters_for<'tcx, T: TypeFoldable<'tcx>>( + t: &T, + include_nonconstraining: bool, +) -> Vec { let mut collector = ParameterCollector { parameters: vec![], include_nonconstraining, diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index fcfd9adef54df..8e69fbd9a79ef 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -99,6 +99,10 @@ fn enforce_impl_params_are_constrained( ) { // Every lifetime used in an associated type must be constrained. let impl_self_ty = tcx.type_of(impl_def_id); + if impl_self_ty.sty == ty::Error { + // Don't complain about unconstrained type params when self ty doesn't exist. (#36836) + return; + } let impl_generics = tcx.generics_of(impl_def_id); let impl_predicates = tcx.predicates_of(impl_def_id); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id); diff --git a/src/test/ui/issues/issue-36836.rs b/src/test/ui/issues/issue-36836.rs new file mode 100644 index 0000000000000..56d5a7cca4566 --- /dev/null +++ b/src/test/ui/issues/issue-36836.rs @@ -0,0 +1,5 @@ +trait Foo {} + +impl Foo for Bar {} //~ ERROR cannot find type `Bar` in this scope + +fn main() {} diff --git a/src/test/ui/issues/issue-36836.stderr b/src/test/ui/issues/issue-36836.stderr new file mode 100644 index 0000000000000..bfda9b0bbdd7e --- /dev/null +++ b/src/test/ui/issues/issue-36836.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Bar` in this scope + --> $DIR/issue-36836.rs:3:17 + | +LL | impl Foo for Bar {} + | ^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. From 3cb1ed4279d8ca4528e3777d5470ca7dc85a976a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 2 Sep 2019 20:51:31 -0700 Subject: [PATCH 058/462] review comments --- src/librustc_typeck/constrained_generic_params.rs | 4 ++-- src/test/ui/issues/issue-36836.rs | 10 ++++++++++ src/test/ui/issues/issue-36836.stderr | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/constrained_generic_params.rs b/src/librustc_typeck/constrained_generic_params.rs index c95f81506cd59..dd44f86717fe5 100644 --- a/src/librustc_typeck/constrained_generic_params.rs +++ b/src/librustc_typeck/constrained_generic_params.rs @@ -36,8 +36,8 @@ pub fn parameters_for_impl<'tcx>( /// uniquely determined by `t` (see RFC 447). If it is true, return the list /// of parameters whose values are needed in order to constrain `ty` - these /// differ, with the latter being a superset, in the presence of projections. -pub fn parameters_for<'tcx, T: TypeFoldable<'tcx>>( - t: &T, +pub fn parameters_for<'tcx>( + t: &impl TypeFoldable<'tcx>, include_nonconstraining: bool, ) -> Vec { let mut collector = ParameterCollector { diff --git a/src/test/ui/issues/issue-36836.rs b/src/test/ui/issues/issue-36836.rs index 56d5a7cca4566..99c56213153e4 100644 --- a/src/test/ui/issues/issue-36836.rs +++ b/src/test/ui/issues/issue-36836.rs @@ -1,3 +1,13 @@ +// Previously, in addition to the real cause of the problem as seen below, +// the compiler would tell the user: +// +// ``` +// error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or +// predicates +// ``` +// +// With this test, we check that only the relevant error is emitted. + trait Foo {} impl Foo for Bar {} //~ ERROR cannot find type `Bar` in this scope diff --git a/src/test/ui/issues/issue-36836.stderr b/src/test/ui/issues/issue-36836.stderr index bfda9b0bbdd7e..418194fac9923 100644 --- a/src/test/ui/issues/issue-36836.stderr +++ b/src/test/ui/issues/issue-36836.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `Bar` in this scope - --> $DIR/issue-36836.rs:3:17 + --> $DIR/issue-36836.rs:13:17 | LL | impl Foo for Bar {} | ^^^ not found in this scope From ff63bf8fc7a19ca27b3d43aa36036f8e77567b20 Mon Sep 17 00:00:00 2001 From: Hal Gentz Date: Tue, 3 Sep 2019 01:28:33 -0600 Subject: [PATCH 059/462] Fix minor typo in docs. --- src/librustc_mir/const_eval.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 5aa487d901663..a745559d8514d 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -589,7 +589,7 @@ pub fn const_eval_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { - // see comment in const_eval_provider for what we're doing here + // see comment in const_eval_raw_provider for what we're doing here if key.param_env.reveal == Reveal::All { let mut key = key.clone(); key.param_env.reveal = Reveal::UserFacing; From 7589d3a400dfaa13027232ef0a5352fd20680193 Mon Sep 17 00:00:00 2001 From: Hal Gentz Date: Tue, 3 Sep 2019 01:54:48 -0600 Subject: [PATCH 060/462] Update other doc. Value was renamed to Operand in https://github.com/rust-lang/rust/commit/ad2de8b4ee099916113b7b3577ac86857b1568be ScalarPair to Slice in https://github.com/rust-lang/rust/commit/fe50b4eb1d6f7a31c53798bca3d0fa2b0670fa3d Not familiar enough with rustc's source to know if the comment is even still applicable. --- src/librustc/mir/interpret/value.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 3da5a65c37932..811c872968a56 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -17,8 +17,8 @@ pub struct RawConst<'tcx> { pub ty: Ty<'tcx>, } -/// Represents a constant value in Rust. `Scalar` and `ScalarPair` are optimizations that -/// match the `LocalState` optimizations for easy conversions between `Value` and `ConstValue`. +/// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations that +/// match the `LocalState` optimizations for easy conversions between `Operand` and `ConstValue`. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, HashStable)] pub enum ConstValue<'tcx> { From 0662fcf4f950ec2800f0b1e02254ef2389b55079 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 3 Sep 2019 14:37:53 +0000 Subject: [PATCH 061/462] make wasi a target-specific dependency --- src/libstd/Cargo.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 0d04b7a274037..173bcea0846a0 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -24,7 +24,6 @@ compiler_builtins = { version = "0.1.16" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } unwind = { path = "../libunwind" } hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] } -wasi = { version = "0.7.0", features = ['rustc-dep-of-std', 'alloc'] } [dependencies.backtrace] version = "0.3.35" @@ -57,6 +56,9 @@ dlmalloc = { version = "0.1", features = ['rustc-dep-of-std'] } [target.x86_64-fortanix-unknown-sgx.dependencies] fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] } +[target.wasm32-wasi.dependencies] +wasi = { version = "0.7.0", features = ['rustc-dep-of-std', 'alloc'] } + [build-dependencies] cc = "1.0" From 87866714ee1cf3fba6e659f46413e361b9088362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 3 Sep 2019 08:12:28 -0700 Subject: [PATCH 062/462] fix comment and add delay_span_bug --- src/librustc_typeck/impl_wf_check.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index 8e69fbd9a79ef..82acbf7c74803 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -12,7 +12,7 @@ use crate::constrained_generic_params as cgp; use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::def_id::DefId; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, TyCtxt, TypeFoldable}; use rustc::ty::query::Providers; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use std::collections::hash_map::Entry::{Occupied, Vacant}; @@ -99,8 +99,13 @@ fn enforce_impl_params_are_constrained( ) { // Every lifetime used in an associated type must be constrained. let impl_self_ty = tcx.type_of(impl_def_id); - if impl_self_ty.sty == ty::Error { - // Don't complain about unconstrained type params when self ty doesn't exist. (#36836) + if impl_self_ty.references_error() { + // Don't complain about unconstrained type params when self ty isn't known due to errors. + // (#36836) + tcx.sess.delay_span_bug(tcx.def_span(impl_def_id), &format( + "potentially unconstrained type parameters weren't evaluated on `{:?}`", + impl_self_ty, + )); return; } let impl_generics = tcx.generics_of(impl_def_id); From c44ffafab902e687ef01d2366a7de7237e25245c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 3 Sep 2019 08:33:06 -0700 Subject: [PATCH 063/462] review comment --- src/librustc_typeck/impl_wf_check.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index 82acbf7c74803..bc0f17c3bf0fb 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -102,10 +102,10 @@ fn enforce_impl_params_are_constrained( if impl_self_ty.references_error() { // Don't complain about unconstrained type params when self ty isn't known due to errors. // (#36836) - tcx.sess.delay_span_bug(tcx.def_span(impl_def_id), &format( - "potentially unconstrained type parameters weren't evaluated on `{:?}`", - impl_self_ty, - )); + tcx.sess.delay_span_bug( + tcx.def_span(impl_def_id), + "potentially unconstrained type parameters weren't evaluated", + ); return; } let impl_generics = tcx.generics_of(impl_def_id); From 925a766bc0d34f8808e9902c47bea54b09540774 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 28 Aug 2019 20:28:42 -0700 Subject: [PATCH 064/462] Add Yaah to clippy toolstain notification list --- src/tools/publish_toolstate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 1411f4c0b05a2..2e2505b7f0246 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -22,7 +22,7 @@ # List of people to ping when the status of a tool or a book changed. MAINTAINERS = { 'miri': '@oli-obk @RalfJung @eddyb', - 'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk @phansch @flip1995', + 'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk @phansch @flip1995 @yaahc', 'rls': '@Xanewok', 'rustfmt': '@topecongiro', 'book': '@carols10cents @steveklabnik', From 98bd8fd88c3750cfc33b6ae56a0ff1078940bdc6 Mon Sep 17 00:00:00 2001 From: Dario Gonzalez Date: Fri, 26 Apr 2019 13:52:56 -0700 Subject: [PATCH 065/462] Added ability to crosscompile doctests --- src/librustdoc/config.rs | 10 ++++++ src/librustdoc/html/markdown.rs | 34 +++++++++++++++++---- src/librustdoc/html/markdown/tests.rs | 44 ++++++++++++++------------- src/librustdoc/lib.rs | 12 ++++++++ src/librustdoc/test.rs | 42 +++++++++++++++++++++---- 5 files changed, 109 insertions(+), 33 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index d261408fc148a..6d1258fe3a390 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -77,6 +77,10 @@ pub struct Options { /// Optional path to persist the doctest executables to, defaults to a /// temporary directory if not set. pub persist_doctests: Option, + /// Runtool to run doctests with + pub runtool: Option, + /// Arguments to pass to the runtool + pub runtool_args: Vec, // Options that affect the documentation process @@ -140,6 +144,8 @@ impl fmt::Debug for Options { .field("show_coverage", &self.show_coverage) .field("crate_version", &self.crate_version) .field("render_options", &self.render_options) + .field("runtool", &self.runtool) + .field("runtool_args", &self.runtool_args) .finish() } } @@ -466,6 +472,8 @@ impl Options { let codegen_options_strs = matches.opt_strs("C"); let lib_strs = matches.opt_strs("L"); let extern_strs = matches.opt_strs("extern"); + let runtool = matches.opt_str("runtool"); + let runtool_args = matches.opt_strs("runtool-arg"); let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); @@ -496,6 +504,8 @@ impl Options { show_coverage, crate_version, persist_doctests, + runtool, + runtool_args, render_options: RenderOptions { output, external_html, diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 74413a7f905d4..45f2efd411fae 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -272,7 +272,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { )) }); - let tooltip = if ignore { + let tooltip = if ignore != Ignore::None { Some(("This example is not tested".to_owned(), "ignore")) } else if compile_fail { Some(("This example deliberately fails to compile".to_owned(), "compile_fail")) @@ -286,7 +286,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { s.push_str(&highlight::render_with_highlighting( &text, Some(&format!("rust-example-rendered{}", - if ignore { " ignore" } + if ignore != Ignore::None { " ignore" } else if compile_fail { " compile_fail" } else if explicit_edition { " edition " } else { "" })), @@ -297,7 +297,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { s.push_str(&highlight::render_with_highlighting( &text, Some(&format!("rust-example-rendered{}", - if ignore { " ignore" } + if ignore != Ignore::None { " ignore" } else if compile_fail { " compile_fail" } else if explicit_edition { " edition " } else { "" })), @@ -607,7 +607,7 @@ pub struct LangString { original: String, pub should_panic: bool, pub no_run: bool, - pub ignore: bool, + pub ignore: Ignore, pub rust: bool, pub test_harness: bool, pub compile_fail: bool, @@ -616,13 +616,20 @@ pub struct LangString { pub edition: Option } +#[derive(Eq, PartialEq, Clone, Debug)] +pub enum Ignore { + All, + None, + Some(Vec), +} + impl LangString { fn all_false() -> LangString { LangString { original: String::new(), should_panic: false, no_run: false, - ignore: false, + ignore: Ignore::None, rust: true, // NB This used to be `notrust = false` test_harness: false, compile_fail: false, @@ -637,6 +644,7 @@ impl LangString { let mut seen_rust_tags = false; let mut seen_other_tags = false; let mut data = LangString::all_false(); + let mut ignores = vec![]; data.original = string.to_owned(); let tokens = string.split(|c: char| @@ -651,7 +659,11 @@ impl LangString { seen_rust_tags = seen_other_tags == false; } "no_run" => { data.no_run = true; seen_rust_tags = !seen_other_tags; } - "ignore" => { data.ignore = true; seen_rust_tags = !seen_other_tags; } + "ignore" => { data.ignore = Ignore::All; seen_rust_tags = !seen_other_tags; } + x if x.starts_with("ignore-") => { + ignores.push(x.trim_start_matches("ignore-").to_owned()); + seen_rust_tags = !seen_other_tags; + } "allow_fail" => { data.allow_fail = true; seen_rust_tags = !seen_other_tags; } "rust" => { data.rust = true; seen_rust_tags = true; } "test_harness" => { @@ -680,6 +692,16 @@ impl LangString { } } + match data.ignore { + Ignore::All => {}, + Ignore::None => { + if !ignores.is_empty() { + data.ignore = Ignore::Some(ignores); + } + }, + _ => unreachable!(), + } + data.rust &= !seen_other_tags || seen_rust_tags; data diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index a95c29038d46f..5d6811a29a3eb 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -1,4 +1,4 @@ -use super::{ErrorCodes, LangString, Markdown, MarkdownHtml, IdMap}; +use super::{ErrorCodes, LangString, Markdown, MarkdownHtml, IdMap, Ignore}; use super::plain_summary_line; use std::cell::RefCell; use syntax::edition::{Edition, DEFAULT_EDITION}; @@ -26,10 +26,10 @@ fn test_unique_id() { #[test] fn test_lang_string_parse() { fn t(s: &str, - should_panic: bool, no_run: bool, ignore: bool, rust: bool, test_harness: bool, + should_panic: bool, no_run: bool, ignore: Ignore, rust: bool, test_harness: bool, compile_fail: bool, allow_fail: bool, error_codes: Vec, - edition: Option) { - assert_eq!(LangString::parse(s, ErrorCodes::Yes), LangString { + edition: Option) { + assert_eq!(LangString::parse(s, ErrorCodes::Yes, true), LangString { should_panic, no_run, ignore, @@ -42,6 +42,7 @@ fn test_lang_string_parse() { edition, }) } + let ignore_foo = Ignore::Some(vec!("foo".to_string())); fn v() -> Vec { Vec::new() @@ -50,23 +51,24 @@ fn test_lang_string_parse() { // ignore-tidy-linelength // marker | should_panic | no_run | ignore | rust | test_harness // | compile_fail | allow_fail | error_codes | edition - t("", false, false, false, true, false, false, false, v(), None); - t("rust", false, false, false, true, false, false, false, v(), None); - t("sh", false, false, false, false, false, false, false, v(), None); - t("ignore", false, false, true, true, false, false, false, v(), None); - t("should_panic", true, false, false, true, false, false, false, v(), None); - t("no_run", false, true, false, true, false, false, false, v(), None); - t("test_harness", false, false, false, true, true, false, false, v(), None); - t("compile_fail", false, true, false, true, false, true, false, v(), None); - t("allow_fail", false, false, false, true, false, false, true, v(), None); - t("{.no_run .example}", false, true, false, true, false, false, false, v(), None); - t("{.sh .should_panic}", true, false, false, false, false, false, false, v(), None); - t("{.example .rust}", false, false, false, true, false, false, false, v(), None); - t("{.test_harness .rust}", false, false, false, true, true, false, false, v(), None); - t("text, no_run", false, true, false, false, false, false, false, v(), None); - t("text,no_run", false, true, false, false, false, false, false, v(), None); - t("edition2015", false, false, false, true, false, false, false, v(), Some(Edition::Edition2015)); - t("edition2018", false, false, false, true, false, false, false, v(), Some(Edition::Edition2018)); + t("", false, false, Ignore::None, true, false, false, false, v(), None); + t("rust", false, false, Ignore::None, true, false, false, false, v(), None); + t("sh", false, false, Ignore::None, false, false, false, false, v(), None); + t("ignore", false, false, Ignore::All, true, false, false, false, v(), None); + t("ignore-foo", false, false, ignore_foo, true, false, false, false, v(), None); + t("should_panic", true, false, Ignore::None, true, false, false, false, v(), None); + t("no_run", false, true, Ignore::None, true, false, false, false, v(), None); + t("test_harness", false, false, Ignore::None, true, true, false, false, v(), None); + t("compile_fail", false, true, Ignore::None, true, false, true, false, v(), None); + t("allow_fail", false, false, Ignore::None, true, false, false, true, v(), None); + t("{.no_run .example}", false, true, Ignore::None, true, false, false, false, v(), None); + t("{.sh .should_panic}", true, false, Ignore::None, false, false, false, false, v(), None); + t("{.example .rust}", false, false, Ignore::None, true, false, false, false, v(), None); + t("{.test_harness .rust}", false, false, Ignore::None, true, true, false, false, v(), None); + t("text, no_run", false, true, Ignore::None, false, false, false, false, v(), None); + t("text,no_run", false, true, Ignore::None, false, false, false, false, v(), None); + t("edition2015", false, false, Ignore::None, true, false, false, false, v(), Some(Edition::Edition2015)); + t("edition2018", false, false, Ignore::None, true, false, false, false, v(), Some(Edition::Edition2018)); } #[test] diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index dfa0db0d23b74..c5ac2440f6791 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -355,6 +355,18 @@ fn opts() -> Vec { "show-coverage", "calculate percentage of public items with documentation") }), + unstable("runtool", |o| { + o.optopt("", + "runtool", + "", + "The tool to run tests with when building for a different target than host") + }), + unstable("runtool-arg", |o| { + o.optmulti("", + "runtool-arg", + "", + "One (of possibly many) arguments to pass to the runtool") + }), ] } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index adcc9930b6c33..2c9e530b9e6b1 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -1,5 +1,6 @@ use rustc_data_structures::sync::Lrc; use rustc_interface::interface; +use rustc_target::spec::TargetTriple; use rustc::hir; use rustc::hir::intravisit; use rustc::session::{self, config, DiagnosticOutput}; @@ -22,7 +23,7 @@ use testing; use crate::clean::Attributes; use crate::config::Options; -use crate::html::markdown::{self, ErrorCodes, LangString}; +use crate::html::markdown::{self, ErrorCodes, LangString, Ignore}; #[derive(Clone, Default)] pub struct TestOptions { @@ -44,7 +45,7 @@ pub fn run(options: Options) -> i32 { vec![config::CrateType::Dylib] }; - let sessopts = config::Options { + let mut sessopts = config::Options { maybe_sysroot: options.maybe_sysroot.clone(), search_paths: options.libs.clone(), crate_types, @@ -59,7 +60,7 @@ pub fn run(options: Options) -> i32 { edition: options.edition, ..config::Options::default() }; - + options.target.as_ref().map(|t| { sessopts.target_triple = t.clone() }); let config = interface::Config { opts: sessopts, crate_cfg: config::parse_cfgspecs(options.cfgs.clone()), @@ -181,6 +182,9 @@ fn run_test( should_panic: bool, no_run: bool, as_test_harness: bool, + runtool: Option, + runtool_args: Vec, + target: Option, compile_fail: bool, mut error_codes: Vec, opts: &TestOptions, @@ -315,7 +319,15 @@ fn run_test( } // Run the code! - let mut cmd = Command::new(output_file); + let mut cmd; + + if let Some(tool) = runtool { + cmd = Command::new(tool); + cmd.arg(output_file); + cmd.args(runtool_args); + }else{ + cmd = Command::new(output_file); + } match cmd.output() { Err(e) => return Err(TestFailure::ExecutionError(e)), @@ -661,12 +673,27 @@ impl Tester for Collector { let opts = self.opts.clone(); let edition = config.edition.unwrap_or(self.options.edition.clone()); let options = self.options.clone(); + let maybe_sysroot = self.maybe_sysroot.clone(); + let linker = self.linker.clone(); + let edition = config.edition.unwrap_or(self.edition); + let persist_doctests = self.persist_doctests.clone(); + let runtool = self.runtool.clone(); + let runtool_args = self.runtool_args.clone(); + let target = self.target.clone(); + let target_str = target.as_ref().map(|t| t.to_string()); debug!("creating test {}: {}", name, test); self.tests.push(testing::TestDescAndFn { desc: testing::TestDesc { - name: testing::DynTestName(name), - ignore: config.ignore, + name: testing::DynTestName(name.clone()), + ignore: match config.ignore { + Ignore::All => true, + Ignore::None => false, + Ignore::Some(ref ignores) => { + target_str.map_or(false, + |s| ignores.iter().any(|t| s.contains(t))) + }, + }, // compiler failures are test failures should_panic: testing::ShouldPanic::No, allow_fail: config.allow_fail, @@ -681,6 +708,9 @@ impl Tester for Collector { config.should_panic, config.no_run, config.test_harness, + runtool, + runtool_args, + target, config.compile_fail, config.error_codes, &opts, From 3f7640884128c6d2acaa9aee3b582cc372044b6d Mon Sep 17 00:00:00 2001 From: Dario Gonzalez Date: Thu, 6 Jun 2019 16:01:53 -0700 Subject: [PATCH 066/462] added feature gate enable-per-target-ignores updated and augmented tests in html/markdown.rs --- src/librustdoc/config.rs | 7 +++++++ src/librustdoc/html/markdown.rs | 17 +++++++++++------ src/librustdoc/lib.rs | 5 +++++ src/librustdoc/markdown.rs | 2 +- src/librustdoc/passes/mod.rs | 2 +- src/librustdoc/test.rs | 7 +++++-- 6 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 6d1258fe3a390..d8fe8d6c8a362 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -81,6 +81,10 @@ pub struct Options { pub runtool: Option, /// Arguments to pass to the runtool pub runtool_args: Vec, + /// Whether to allow ignoring doctests on a per-target basis + /// For example, using ignore-foo to ignore running the doctest on any target that + /// contains "foo" as a substring + pub enable_per_target_ignores: bool, // Options that affect the documentation process @@ -146,6 +150,7 @@ impl fmt::Debug for Options { .field("render_options", &self.render_options) .field("runtool", &self.runtool) .field("runtool_args", &self.runtool_args) + .field("enable-per-target-ignores", &self.enable_per_target_ignores) .finish() } } @@ -474,6 +479,7 @@ impl Options { let extern_strs = matches.opt_strs("extern"); let runtool = matches.opt_str("runtool"); let runtool_args = matches.opt_strs("runtool-arg"); + let enable_per_target_ignores = matches.opt_present("enable-per-target-ignores"); let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); @@ -506,6 +512,7 @@ impl Options { persist_doctests, runtool, runtool_args, + enable_per_target_ignores, render_options: RenderOptions { output, external_html, diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 45f2efd411fae..cdc6d4eda4006 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -199,7 +199,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { let ignore; let edition; if let Some(Event::Start(Tag::CodeBlock(lang))) = event { - let parse_result = LangString::parse(&lang, self.check_error_codes); + let parse_result = LangString::parse(&lang, self.check_error_codes, false); if !parse_result.rust { return Some(Event::Start(Tag::CodeBlock(lang))); } @@ -551,7 +551,8 @@ impl<'a, I: Iterator>> Iterator for Footnotes<'a, I> { } } -pub fn find_testable_code(doc: &str, tests: &mut T, error_codes: ErrorCodes) { +pub fn find_testable_code(doc: &str, tests: &mut T, error_codes: ErrorCodes, + enable_per_target_ignores: bool) { let mut parser = Parser::new(doc); let mut prev_offset = 0; let mut nb_lines = 0; @@ -564,7 +565,7 @@ pub fn find_testable_code(doc: &str, tests: &mut T, error_codes let block_info = if s.is_empty() { LangString::all_false() } else { - LangString::parse(&*s, error_codes) + LangString::parse(&*s, error_codes, enable_per_target_ignores) }; if !block_info.rust { continue; @@ -639,7 +640,11 @@ impl LangString { } } - fn parse(string: &str, allow_error_code_check: ErrorCodes) -> LangString { + fn parse( + string: &str, + allow_error_code_check: ErrorCodes, + enable_per_target_ignores: bool + ) -> LangString { let allow_error_code_check = allow_error_code_check.as_bool(); let mut seen_rust_tags = false; let mut seen_other_tags = false; @@ -660,7 +665,7 @@ impl LangString { } "no_run" => { data.no_run = true; seen_rust_tags = !seen_other_tags; } "ignore" => { data.ignore = Ignore::All; seen_rust_tags = !seen_other_tags; } - x if x.starts_with("ignore-") => { + x if enable_per_target_ignores && x.starts_with("ignore-") => { ignores.push(x.trim_start_matches("ignore-").to_owned()); seen_rust_tags = !seen_other_tags; } @@ -941,7 +946,7 @@ crate fn rust_code_blocks(md: &str) -> Vec { let lang_string = if syntax.is_empty() { LangString::all_false() } else { - LangString::parse(&*syntax, ErrorCodes::Yes) + LangString::parse(&*syntax, ErrorCodes::Yes, false) }; if lang_string.rust { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index c5ac2440f6791..8f6067da08335 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -355,6 +355,11 @@ fn opts() -> Vec { "show-coverage", "calculate percentage of public items with documentation") }), + unstable("enable-per-target-ignores", |o| { + o.optflag("", + "enable-per-target-ignores", + "parse ignore-foo for ignoring doctests on a per-target basis") + }), unstable("runtool", |o| { o.optopt("", "runtool", diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index a30fc05f36acd..67faec6bd3d0c 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -147,7 +147,7 @@ pub fn test(mut options: Options, diag: &errors::Handler) -> i32 { collector.set_position(DUMMY_SP); let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()); - find_testable_code(&input_str, &mut collector, codes); + find_testable_code(&input_str, &mut collector, codes, options.enable_per_target_ignores); options.test_args.insert(0, "rustdoctest".to_string()); testing::test_main(&options.test_args, collector.tests, diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 641a6df221446..3bb1d0deca78d 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -336,7 +336,7 @@ pub fn look_for_tests<'tcx>( found_tests: 0, }; - find_testable_code(&dox, &mut tests, ErrorCodes::No); + find_testable_code(&dox, &mut tests, ErrorCodes::No, false); if check_missing_code == true && tests.found_tests == 0 { let sp = span_of_attrs(&item.attrs).substitute_dummy(item.source.span()); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 2c9e530b9e6b1..a30ac1a512893 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -325,7 +325,7 @@ fn run_test( cmd = Command::new(tool); cmd.arg(output_file); cmd.args(runtool_args); - }else{ + } else { cmd = Command::new(output_file); } @@ -857,7 +857,10 @@ impl<'a, 'hir> HirCollector<'a, 'hir> { // anything else, this will combine them for us. if let Some(doc) = attrs.collapsed_doc_value() { self.collector.set_position(attrs.span.unwrap_or(DUMMY_SP)); - markdown::find_testable_code(&doc, self.collector, self.codes); + markdown::find_testable_code(&doc, + self.collector, + self.codes, + self.collector.enable_per_target_ignores); } nested(self); From 657e24c56b11a45ee1cc019eb0763838f4437475 Mon Sep 17 00:00:00 2001 From: Dario Gonzalez Date: Tue, 11 Jun 2019 11:06:34 -0700 Subject: [PATCH 067/462] changed target from option to plain target, populated with host triple at argument parsing time if no --target arguments --- src/librustdoc/config.rs | 8 +++++--- src/librustdoc/core.rs | 3 +-- src/librustdoc/test.rs | 8 +++----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index d8fe8d6c8a362..995a340143f78 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -9,7 +9,7 @@ use rustc::session; use rustc::session::config::{CrateType, parse_crate_types_from_list}; use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs}; use rustc::session::config::{nightly_options, build_codegen_options, build_debugging_options, - get_cmd_lint_options, ExternEntry}; + get_cmd_lint_options, host_triple, ExternEntry}; use rustc::session::search_paths::SearchPath; use rustc_driver; use rustc_target::spec::TargetTriple; @@ -54,7 +54,7 @@ pub struct Options { /// Debugging (`-Z`) options to pass to the compiler. pub debugging_options: DebuggingOptions, /// The target used to compile the crate against. - pub target: Option, + pub target: TargetTriple, /// Edition used when reading the crate. Defaults to "2015". Also used by default when /// compiling doctests from the crate. pub edition: Edition, @@ -425,7 +425,9 @@ impl Options { } } - let target = matches.opt_str("target").map(|target| { + let target = matches.opt_str("target").map_or( + TargetTriple::from_triple(host_triple()), + |target| { if target.ends_with(".json") { TargetTriple::TargetPath(PathBuf::from(target)) } else { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 9cfcad4271966..66a32c73e0f16 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -13,7 +13,6 @@ use rustc_interface::interface; use rustc_driver::abort_on_err; use rustc_resolve as resolve; use rustc_metadata::cstore::CStore; -use rustc_target::spec::TargetTriple; use syntax::source_map; use syntax::attr; @@ -313,7 +312,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt lint_cap: Some(lint_cap.unwrap_or_else(|| lint::Forbid)), cg: codegen_options, externs, - target_triple: target.unwrap_or(host_triple), + target_triple: target, // Ensure that rustdoc works even if rustc is feature-staged unstable_features: UnstableFeatures::Allow, actually_rustdoc: true, diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index a30ac1a512893..daec977810682 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -60,7 +60,6 @@ pub fn run(options: Options) -> i32 { edition: options.edition, ..config::Options::default() }; - options.target.as_ref().map(|t| { sessopts.target_triple = t.clone() }); let config = interface::Config { opts: sessopts, crate_cfg: config::parse_cfgspecs(options.cfgs.clone()), @@ -184,7 +183,7 @@ fn run_test( as_test_harness: bool, runtool: Option, runtool_args: Vec, - target: Option, + target: TargetTriple, compile_fail: bool, mut error_codes: Vec, opts: &TestOptions, @@ -680,7 +679,7 @@ impl Tester for Collector { let runtool = self.runtool.clone(); let runtool_args = self.runtool_args.clone(); let target = self.target.clone(); - let target_str = target.as_ref().map(|t| t.to_string()); + let target_str = target.to_string(); debug!("creating test {}: {}", name, test); self.tests.push(testing::TestDescAndFn { @@ -690,8 +689,7 @@ impl Tester for Collector { Ignore::All => true, Ignore::None => false, Ignore::Some(ref ignores) => { - target_str.map_or(false, - |s| ignores.iter().any(|t| s.contains(t))) + ignores.iter().any(|s| target_str.contains(s)) }, }, // compiler failures are test failures From 14110ebd936747eff905ec4e444a02a4a74f6e11 Mon Sep 17 00:00:00 2001 From: Dario Gonzalez Date: Wed, 12 Jun 2019 10:49:41 -0700 Subject: [PATCH 068/462] added rustdoc book documentation, improved behavior when unstable flag not present --- src/doc/rustdoc/src/unstable-features.md | 50 ++++++++++++++++++++++++ src/librustdoc/html/markdown.rs | 14 ++----- src/librustdoc/test.rs | 2 + 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 993fc8412836e..49d05b5038df7 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -471,3 +471,53 @@ Some methodology notes about what rustdoc counts in this metric: Public items that are not documented can be seen with the built-in `missing_docs` lint. Private items that are not documented can be seen with Clippy's `missing_docs_in_private_items` lint. + +### `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --enable-per-target-ignores +``` + +This flag allows you to tag doctests with compiltest style `ignore-foo` filters that prevent +rustdoc from running that test if the target triple string contains foo. For example: + +```rust +///```ignore-foo,ignore-bar +///assert!(2 == 2); +///``` +struct Foo; +``` + +This will not be run when the build target is `super-awesome-foo` or `less-bar-awesome`. +If the flag is not enabled, then rustdoc will consume the filter, but do nothing with it, and +the above example will be run for all targets. +If you want to preserve backwards compatibility for older versions of rustdoc, you can use + +```rust +///```ignore,ignore-foo +///assert!(2 == 2); +///``` +struct Foo; +``` + +In older versions, this will be ignored on all targets, but on newer versions `ignore-gnu` will +override `ignore`. + +### `--runtool`, `--runtool-arg`: program to run tests with; args to pass to it + +Using thses options looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --runtool runner --runtool-arg --do-thing --runtool-arg --do-other-thing +``` + +These options can be used to run the doctest under a program, and also pass arguments to +that program. For example, if you want to run your doctests under valgrind you might run + +```bash +$ rustdoc src/lib.rs -Z unstable-options --runtool valgrind +``` + +Another use case would be to run a test inside an emulator, or through a Virtual Machine. diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index cdc6d4eda4006..05e6c77256e7b 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -665,7 +665,7 @@ impl LangString { } "no_run" => { data.no_run = true; seen_rust_tags = !seen_other_tags; } "ignore" => { data.ignore = Ignore::All; seen_rust_tags = !seen_other_tags; } - x if enable_per_target_ignores && x.starts_with("ignore-") => { + x if x.starts_with("ignore-") => if enable_per_target_ignores { ignores.push(x.trim_start_matches("ignore-").to_owned()); seen_rust_tags = !seen_other_tags; } @@ -696,15 +696,9 @@ impl LangString { _ => { seen_other_tags = true } } } - - match data.ignore { - Ignore::All => {}, - Ignore::None => { - if !ignores.is_empty() { - data.ignore = Ignore::Some(ignores); - } - }, - _ => unreachable!(), + // ignore-foo overrides ignore + if !ignores.is_empty() { + data.ignore = Ignore::Some(ignores); } data.rust &= !seen_other_tags || seen_rust_tags; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index daec977810682..840eeda9ad7ca 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -58,8 +58,10 @@ pub fn run(options: Options) -> i32 { ..config::basic_debugging_options() }, edition: options.edition, + target_triple: options.target.clone(), ..config::Options::default() }; + let config = interface::Config { opts: sessopts, crate_cfg: config::parse_cfgspecs(options.cfgs.clone()), From 78908f2e0963ceed461e9961020226d3e12c5978 Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Tue, 3 Sep 2019 11:56:08 +0200 Subject: [PATCH 069/462] Override `StepBy::{try_fold, try_rfold}` --- src/libcore/iter/adapters/mod.rs | 44 +++++++++++++++++++++++++++++++- src/libcore/tests/iter.rs | 35 +++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index f50781890ab22..7c9dde81a48fb 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -5,7 +5,7 @@ use crate::usize; use crate::intrinsics; use super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen}; -use super::LoopState; +use super::{LoopState, from_fn}; mod chain; mod flatten; @@ -541,6 +541,26 @@ impl Iterator for StepBy where I: Iterator { self.iter.nth(nth - 1); } } + + fn try_fold(&mut self, mut acc: Acc, mut f: F) -> R + where + F: FnMut(Acc, Self::Item) -> R, + R: Try, + { + #[inline] + fn nth(iter: &mut I, step: usize) -> impl FnMut() -> Option + '_ { + move || iter.nth(step) + } + + if self.first_take { + self.first_take = false; + match self.iter.next() { + None => return Try::from_ok(acc), + Some(x) => acc = f(acc, x)?, + } + } + from_fn(nth(&mut self.iter, self.step)).try_fold(acc, f) + } } impl StepBy where I: ExactSizeIterator { @@ -574,6 +594,28 @@ impl DoubleEndedIterator for StepBy where I: DoubleEndedIterator + ExactSi .saturating_add(self.next_back_index()); self.iter.nth_back(n) } + + fn try_rfold(&mut self, init: Acc, mut f: F) -> R + where + F: FnMut(Acc, Self::Item) -> R, + R: Try, + { + #[inline] + fn nth_back( + iter: &mut I, + step: usize, + ) -> impl FnMut() -> Option + '_ { + move || iter.nth_back(step) + } + + match self.next_back() { + None => Try::from_ok(init), + Some(x) => { + let acc = f(init, x)?; + from_fn(nth_back(&mut self.iter, self.step)).try_fold(acc, f) + } + } + } } // StepBy can only make the iterator shorter, so the len will still fit. diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 3a4f76852a0d7..f52899b500a3a 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -329,6 +329,23 @@ fn test_iterator_step_by_nth_overflow() { assert_eq!(it.0, (usize::MAX as Bigger) * 1); } +#[test] +fn test_iterator_step_by_nth_try_fold() { + let mut it = (0..).step_by(10); + assert_eq!(it.try_fold(0, i8::checked_add), None); + assert_eq!(it.next(), Some(60)); + assert_eq!(it.try_fold(0, i8::checked_add), None); + assert_eq!(it.next(), Some(90)); + + let mut it = (100..).step_by(10); + assert_eq!(it.try_fold(50, i8::checked_add), None); + assert_eq!(it.next(), Some(110)); + + let mut it = (100..=100).step_by(10); + assert_eq!(it.next(), Some(100)); + assert_eq!(it.try_fold(0, i8::checked_add), Some(0)); +} + #[test] fn test_iterator_step_by_nth_back() { let mut it = (0..16).step_by(5); @@ -354,6 +371,24 @@ fn test_iterator_step_by_nth_back() { assert_eq!(it().nth_back(42), None); } +#[test] +fn test_iterator_step_by_nth_try_rfold() { + let mut it = (0..100).step_by(10); + assert_eq!(it.try_rfold(0, i8::checked_add), None); + assert_eq!(it.next_back(), Some(70)); + assert_eq!(it.next(), Some(0)); + assert_eq!(it.try_rfold(0, i8::checked_add), None); + assert_eq!(it.next_back(), Some(30)); + + let mut it = (0..100).step_by(10); + assert_eq!(it.try_rfold(50, i8::checked_add), None); + assert_eq!(it.next_back(), Some(80)); + + let mut it = (100..=100).step_by(10); + assert_eq!(it.next_back(), Some(100)); + assert_eq!(it.try_fold(0, i8::checked_add), Some(0)); +} + #[test] #[should_panic] fn test_iterator_step_by_zero() { From cb84aa4744c7a6120d8311806912240275d04960 Mon Sep 17 00:00:00 2001 From: Shiqing Date: Mon, 2 Sep 2019 21:03:35 +0800 Subject: [PATCH 070/462] Improve searching in rustdoc and add tests --- src/librustdoc/html/static/main.js | 16 ++---- src/test/rustdoc-js-std/vec-new.js | 1 + src/test/rustdoc-js/exact-match.js | 9 +++ src/test/rustdoc-js/exact-match.rs | 68 +++++++++++++++++++++++ src/test/rustdoc-js/module-substring.js | 9 +++ src/test/rustdoc-js/module-substring.rs | 68 +++++++++++++++++++++++ src/test/rustdoc-js/search-short-types.js | 2 + src/test/rustdoc-js/search-short-types.rs | 6 ++ 8 files changed, 169 insertions(+), 10 deletions(-) create mode 100644 src/test/rustdoc-js/exact-match.js create mode 100644 src/test/rustdoc-js/exact-match.rs create mode 100644 src/test/rustdoc-js/module-substring.js create mode 100644 src/test/rustdoc-js/module-substring.rs diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 637c6ef8e8e0b..5cb2456fefdb2 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -547,6 +547,11 @@ if (!DOMTokenList.prototype.remove) { results.sort(function(aaa, bbb) { var a, b; + // sort by exact match with regard to the last word (mismatch goes later) + a = (aaa.word !== val); + b = (bbb.word !== val); + if (a !== b) { return a - b; } + // Sort by non levenshtein results and then levenshtein results by the distance // (less changes required to match means higher rankings) a = (aaa.lev); @@ -558,11 +563,6 @@ if (!DOMTokenList.prototype.remove) { b = (bbb.item.crate !== window.currentCrate); if (a !== b) { return a - b; } - // sort by exact match (mismatch goes later) - a = (aaa.word !== valLower); - b = (bbb.word !== valLower); - if (a !== b) { return a - b; } - // sort by item name length (longer goes later) a = aaa.word.length; b = bbb.word.length; @@ -1028,7 +1028,7 @@ if (!DOMTokenList.prototype.remove) { if (lev > MAX_LEV_DISTANCE) { continue; } else if (lev > 0) { - lev_add = 1; + lev_add = lev / 10; } } @@ -1099,10 +1099,6 @@ if (!DOMTokenList.prototype.remove) { if (index !== -1 || lev <= MAX_LEV_DISTANCE) { if (index !== -1 && paths.length < 2) { lev = 0; - } else if (searchWords[j] === val) { - // Small trick to fix when you're looking for a one letter type - // and there are other short named types. - lev = -1; } if (results[fullId] === undefined) { results[fullId] = { diff --git a/src/test/rustdoc-js-std/vec-new.js b/src/test/rustdoc-js-std/vec-new.js index e4daa5065d233..e1a3256876bde 100644 --- a/src/test/rustdoc-js-std/vec-new.js +++ b/src/test/rustdoc-js-std/vec-new.js @@ -4,5 +4,6 @@ const EXPECTED = { 'others': [ { 'path': 'std::vec::Vec', 'name': 'new' }, { 'path': 'std::vec::Vec', 'name': 'ne' }, + { 'path': 'std::rc::Rc', 'name': 'ne' }, ], }; diff --git a/src/test/rustdoc-js/exact-match.js b/src/test/rustdoc-js/exact-match.js new file mode 100644 index 0000000000000..b0a411bee5829 --- /dev/null +++ b/src/test/rustdoc-js/exact-match.js @@ -0,0 +1,9 @@ +const QUERY = 'si::pc'; + +const EXPECTED = { + 'others': [ + { 'path': 'exact_match::Si', 'name': 'pc' }, + { 'path': 'exact_match::Psi', 'name': 'pc' }, + { 'path': 'exact_match::Si', 'name': 'pa' }, + ], +}; diff --git a/src/test/rustdoc-js/exact-match.rs b/src/test/rustdoc-js/exact-match.rs new file mode 100644 index 0000000000000..2eacc0a358284 --- /dev/null +++ b/src/test/rustdoc-js/exact-match.rs @@ -0,0 +1,68 @@ +macro_rules! imp { + ($name:ident) => { + pub struct $name { + pub op: usize, + } + impl $name { + pub fn op() {} + pub fn cmp() {} + pub fn map() {} + pub fn pop() {} + pub fn ptr() {} + pub fn rpo() {} + pub fn drop() {} + pub fn copy() {} + pub fn zip() {} + pub fn sup() {} + pub fn pa() {} + pub fn pb() {} + pub fn pc() {} + pub fn pd() {} + pub fn pe() {} + pub fn pf() {} + pub fn pg() {} + pub fn ph() {} + pub fn pi() {} + pub fn pj() {} + pub fn pk() {} + pub fn pl() {} + pub fn pm() {} + pub fn pn() {} + pub fn po() {} + } + }; + ($name:ident, $($names:ident),*) => { + imp!($name); + imp!($($names),*); + }; +} +macro_rules! en { + ($name:ident) => { + pub enum $name { + Ptr, + Rp, + Rpo, + Pt, + Drop, + Dr, + Dro, + Sup, + Op, + Cmp, + Map, + Mp, + } + }; + ($name:ident, $($names:ident),*) => { + en!($name); + en!($($names),*); + }; +} + +imp!(Ot, Foo, Cmp, Map, Loc, Lac, Toc, Si, Sig, Sip, Psy, Psi, Py, Pi, Pa, Pb, Pc, Pd); +imp!(Pe, Pf, Pg, Ph, Pj, Pk, Pl, Pm, Pn, Po, Pq, Pr, Ps, Pt, Pu, Pv, Pw, Px, Pz, Ap, Bp, Cp); +imp!(Dp, Ep, Fp, Gp, Hp, Ip, Jp, Kp, Lp, Mp, Np, Op, Pp, Qp, Rp, Sp, Tp, Up, Vp, Wp, Xp, Yp, Zp); + +en!(Place, Plac, Plae, Plce, Pace, Scalar, Scalr, Scaar, Sclar, Salar); + +pub struct P; diff --git a/src/test/rustdoc-js/module-substring.js b/src/test/rustdoc-js/module-substring.js new file mode 100644 index 0000000000000..a446c39ebad57 --- /dev/null +++ b/src/test/rustdoc-js/module-substring.js @@ -0,0 +1,9 @@ +const QUERY = 'ig::pc'; + +const EXPECTED = { + 'others': [ + { 'path': 'module_substring::Sig', 'name': 'pc' }, + { 'path': 'module_substring::Si', 'name': 'pc' }, + { 'path': 'module_substring::Si', 'name': 'pa' }, + ], +}; diff --git a/src/test/rustdoc-js/module-substring.rs b/src/test/rustdoc-js/module-substring.rs new file mode 100644 index 0000000000000..2eacc0a358284 --- /dev/null +++ b/src/test/rustdoc-js/module-substring.rs @@ -0,0 +1,68 @@ +macro_rules! imp { + ($name:ident) => { + pub struct $name { + pub op: usize, + } + impl $name { + pub fn op() {} + pub fn cmp() {} + pub fn map() {} + pub fn pop() {} + pub fn ptr() {} + pub fn rpo() {} + pub fn drop() {} + pub fn copy() {} + pub fn zip() {} + pub fn sup() {} + pub fn pa() {} + pub fn pb() {} + pub fn pc() {} + pub fn pd() {} + pub fn pe() {} + pub fn pf() {} + pub fn pg() {} + pub fn ph() {} + pub fn pi() {} + pub fn pj() {} + pub fn pk() {} + pub fn pl() {} + pub fn pm() {} + pub fn pn() {} + pub fn po() {} + } + }; + ($name:ident, $($names:ident),*) => { + imp!($name); + imp!($($names),*); + }; +} +macro_rules! en { + ($name:ident) => { + pub enum $name { + Ptr, + Rp, + Rpo, + Pt, + Drop, + Dr, + Dro, + Sup, + Op, + Cmp, + Map, + Mp, + } + }; + ($name:ident, $($names:ident),*) => { + en!($name); + en!($($names),*); + }; +} + +imp!(Ot, Foo, Cmp, Map, Loc, Lac, Toc, Si, Sig, Sip, Psy, Psi, Py, Pi, Pa, Pb, Pc, Pd); +imp!(Pe, Pf, Pg, Ph, Pj, Pk, Pl, Pm, Pn, Po, Pq, Pr, Ps, Pt, Pu, Pv, Pw, Px, Pz, Ap, Bp, Cp); +imp!(Dp, Ep, Fp, Gp, Hp, Ip, Jp, Kp, Lp, Mp, Np, Op, Pp, Qp, Rp, Sp, Tp, Up, Vp, Wp, Xp, Yp, Zp); + +en!(Place, Plac, Plae, Plce, Pace, Scalar, Scalr, Scaar, Sclar, Salar); + +pub struct P; diff --git a/src/test/rustdoc-js/search-short-types.js b/src/test/rustdoc-js/search-short-types.js index 0ebf4860cfa58..d14672af71fd6 100644 --- a/src/test/rustdoc-js/search-short-types.js +++ b/src/test/rustdoc-js/search-short-types.js @@ -3,6 +3,8 @@ const QUERY = 'P'; const EXPECTED = { 'others': [ { 'path': 'search_short_types', 'name': 'P' }, + { 'path': 'search_short_types::VeryLongTypeName', 'name': 'p' }, { 'path': 'search_short_types', 'name': 'Ap' }, + { 'path': 'search_short_types::VeryLongTypeName', 'name': 'ap' }, ], }; diff --git a/src/test/rustdoc-js/search-short-types.rs b/src/test/rustdoc-js/search-short-types.rs index 2eacc0a358284..a4083f9a76401 100644 --- a/src/test/rustdoc-js/search-short-types.rs +++ b/src/test/rustdoc-js/search-short-types.rs @@ -66,3 +66,9 @@ imp!(Dp, Ep, Fp, Gp, Hp, Ip, Jp, Kp, Lp, Mp, Np, Op, Pp, Qp, Rp, Sp, Tp, Up, Vp, en!(Place, Plac, Plae, Plce, Pace, Scalar, Scalr, Scaar, Sclar, Salar); pub struct P; + +pub struct VeryLongTypeName; +impl VeryLongTypeName { + pub fn p() {} + pub fn ap() {} +} From 4a2094c9f61836214d9e37fa042761948483c2d9 Mon Sep 17 00:00:00 2001 From: Dario Gonzalez Date: Tue, 27 Aug 2019 15:44:11 -0700 Subject: [PATCH 071/462] address rebase changes --- src/librustdoc/core.rs | 1 - src/librustdoc/markdown.rs | 3 ++- src/librustdoc/test.rs | 20 +++++++++++--------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 66a32c73e0f16..57b016a08c2fe 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -293,7 +293,6 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt } }).collect(); - let host_triple = TargetTriple::from_triple(config::host_triple()); let crate_types = if proc_macro_crate { vec![config::CrateType::ProcMacro] } else { diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index 67faec6bd3d0c..b06b368469fc1 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -143,7 +143,8 @@ pub fn test(mut options: Options, diag: &errors::Handler) -> i32 { opts.no_crate_inject = true; opts.display_warnings = options.display_warnings; let mut collector = Collector::new(options.input.display().to_string(), options.clone(), - true, opts, None, Some(options.input)); + true, opts, None, Some(options.input), + options.enable_per_target_ignores); collector.set_position(DUMMY_SP); let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 840eeda9ad7ca..aefe4d3ea3f43 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -45,7 +45,7 @@ pub fn run(options: Options) -> i32 { vec![config::CrateType::Dylib] }; - let mut sessopts = config::Options { + let sessopts = config::Options { maybe_sysroot: options.maybe_sysroot.clone(), search_paths: options.libs.clone(), crate_types, @@ -84,6 +84,7 @@ pub fn run(options: Options) -> i32 { let mut opts = scrape_test_config(lower_to_hir.peek().0.borrow().krate()); opts.display_warnings |= options.display_warnings; + let enable_per_target_ignores = options.enable_per_target_ignores; let mut collector = Collector::new( compiler.crate_name()?.peek().to_string(), options, @@ -91,6 +92,7 @@ pub fn run(options: Options) -> i32 { opts, Some(compiler.source_map().clone()), None, + enable_per_target_ignores, ); let mut global_ctxt = compiler.global_ctxt()?.take(); @@ -275,6 +277,7 @@ fn run_test( if no_run { compiler.arg("--emit=metadata"); } + compiler.arg("--target").arg(target.to_string()); compiler.arg("-"); compiler.stdin(Stdio::piped()); @@ -616,6 +619,7 @@ pub struct Collector { options: Options, use_headers: bool, + enable_per_target_ignores: bool, cratename: String, opts: TestOptions, position: Span, @@ -625,12 +629,14 @@ pub struct Collector { impl Collector { pub fn new(cratename: String, options: Options, use_headers: bool, opts: TestOptions, - source_map: Option>, filename: Option,) -> Collector { + source_map: Option>, filename: Option, + enable_per_target_ignores: bool) -> Collector { Collector { tests: Vec::new(), names: Vec::new(), options, use_headers, + enable_per_target_ignores, cratename, opts, position: DUMMY_SP, @@ -674,13 +680,9 @@ impl Tester for Collector { let opts = self.opts.clone(); let edition = config.edition.unwrap_or(self.options.edition.clone()); let options = self.options.clone(); - let maybe_sysroot = self.maybe_sysroot.clone(); - let linker = self.linker.clone(); - let edition = config.edition.unwrap_or(self.edition); - let persist_doctests = self.persist_doctests.clone(); - let runtool = self.runtool.clone(); - let runtool_args = self.runtool_args.clone(); - let target = self.target.clone(); + let runtool = self.options.runtool.clone(); + let runtool_args = self.options.runtool_args.clone(); + let target = self.options.target.clone(); let target_str = target.to_string(); debug!("creating test {}: {}", name, test); From c86ea34639b0962858f053e900fe7c7de1008c5f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 2 Sep 2019 14:23:41 -0400 Subject: [PATCH 072/462] Ensure all warnings are emitted even on warnings=warn --- src/bootstrap/bin/rustc.rs | 13 +++++++------ src/bootstrap/bootstrap.py | 3 ++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 8cb48df14bfef..84415baa3a140 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -119,17 +119,18 @@ fn main() { cmd.arg(format!("-Cdebuginfo={}", debuginfo_level)); } - if env::var_os("RUSTC_DENY_WARNINGS").is_some() && - env::var_os("RUSTC_EXTERNAL_TOOL").is_none() { + if env::var_os("RUSTC_EXTERNAL_TOOL").is_none() { // When extending this list, add the new lints to the RUSTFLAGS of the // build_bootstrap function of src/bootstrap/bootstrap.py as well as // some code doesn't go through this `rustc` wrapper. - cmd.arg("-Dwarnings"); - cmd.arg("-Drust_2018_idioms"); - cmd.arg("-Dunused_lifetimes"); + cmd.arg("-Wrust_2018_idioms"); + cmd.arg("-Wunused_lifetimes"); if use_internal_lints(crate_name) { cmd.arg("-Zunstable-options"); - cmd.arg("-Drustc::internal"); + cmd.arg("-Wrustc::internal"); + } + if env::var_os("RUSTC_DENY_WARNINGS").is_some() { + cmd.arg("-Dwarnings"); } } diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 4162fe1df5086..03f02ea217ddf 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -631,8 +631,9 @@ def build_bootstrap(self): target_linker = self.get_toml("linker", build_section) if target_linker is not None: env["RUSTFLAGS"] += "-C linker=" + target_linker + " " + env["RUSTFLAGS"] += " -Wrust_2018_idioms -Wunused_lifetimes " if self.get_toml("deny-warnings", "rust") != "false": - env["RUSTFLAGS"] += "-Dwarnings -Drust_2018_idioms -Dunused_lifetimes " + env["RUSTFLAGS"] += "-Dwarnings " env["PATH"] = os.path.join(self.bin_root(), "bin") + \ os.pathsep + env["PATH"] From fda251b966ec5a8d1c3c001242777861f15b95e2 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 2 Sep 2019 14:24:40 -0400 Subject: [PATCH 073/462] Rename --warnings=allow to --warnings=warn We never allowed the warnings, only made them not denied. --- src/bootstrap/flags.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 828865f10ffba..d9580b598155e 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -36,7 +36,7 @@ pub struct Flags { // This overrides the deny-warnings configuation option, // which passes -Dwarnings to the compiler invocations. // - // true => deny, false => allow + // true => deny, false => warn pub deny_warnings: Option, } @@ -556,10 +556,10 @@ fn split(s: &[String]) -> Vec { fn parse_deny_warnings(matches: &getopts::Matches) -> Option { match matches.opt_str("warnings").as_ref().map(|v| v.as_str()) { Some("deny") => Some(true), - Some("allow") => Some(false), + Some("warn") => Some(false), Some(value) => { eprintln!( - r#"invalid value for --warnings: {:?}, expected "allow" or "deny""#, + r#"invalid value for --warnings: {:?}, expected "warn" or "deny""#, value, ); process::exit(1); From 53fe76479aab03b1fbe5b7184f45484886f769b1 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 4 Sep 2019 16:02:31 -0700 Subject: [PATCH 074/462] Assume non-git LLVM is fresh if the stamp file exists Rustbuild usually writes the LLVM submodule commit in a stamp file, so we can avoid rebuilding it unnecessarily. However, for builds from a source tarball (non-git), we were assuming a rebuild is always needed. This can cause a lot of extra work if any environment like `CFLAGS` changed between steps like build and install, which are often separate in distro builds. Now we also write an empty stamp file if the git commit is unknown, and its presence is trusted to indicate that no rebuild is needed. An info message reports that this is happening, along with the stamp file path that can be deleted to force a rebuild anyway. --- src/bootstrap/native.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index f02def3e1b05d..7bf9ea2688f4c 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -81,26 +81,29 @@ impl Step for Llvm { (info, "src/llvm-project/llvm", builder.llvm_out(target), dir.join("bin")) }; - if !llvm_info.is_git() { - println!( - "git could not determine the LLVM submodule commit hash. \ - Assuming that an LLVM build is necessary.", - ); - } - let build_llvm_config = llvm_config_ret_dir .join(exe("llvm-config", &*builder.config.build)); let done_stamp = out_dir.join("llvm-finished-building"); - if let Some(llvm_commit) = llvm_info.sha() { - if done_stamp.exists() { + if done_stamp.exists() { + if let Some(llvm_commit) = llvm_info.sha() { let done_contents = t!(fs::read(&done_stamp)); // If LLVM was already built previously and the submodule's commit didn't change // from the previous build, then no action is required. if done_contents == llvm_commit.as_bytes() { - return build_llvm_config + return build_llvm_config; } + } else { + builder.info( + "Could not determine the LLVM submodule commit hash. \ + Assuming that an LLVM rebuild is not necessary.", + ); + builder.info(&format!( + "To force LLVM to rebuild, remove the file `{}`", + done_stamp.display() + )); + return build_llvm_config; } } @@ -303,9 +306,7 @@ impl Step for Llvm { cfg.build(); - if let Some(llvm_commit) = llvm_info.sha() { - t!(fs::write(&done_stamp, llvm_commit)); - } + t!(fs::write(&done_stamp, llvm_info.sha().unwrap_or(""))); build_llvm_config } From 290f5b22752f98071bbc25530fc10a7169e671a3 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Wed, 4 Sep 2019 12:14:34 -0700 Subject: [PATCH 075/462] Use backtrace formatting from the backtrace crate --- Cargo.lock | 4 +- src/libstd/Cargo.toml | 2 +- src/libstd/panicking.rs | 8 +- src/libstd/sys_common/backtrace.rs | 235 +++++++++++------------------ 4 files changed, 96 insertions(+), 153 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0d30647809a9..db83aacc69e45 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,9 +109,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.35" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1371048253fa3bac6704bfd6bbfc922ee9bdcee8881330d40f308b81cc5adc55" +checksum = "5180c5a20655b14a819b652fd2378fa5f1697b6c9ddad3e695c2f9cedf6df4e2" dependencies = [ "backtrace-sys", "cfg-if", diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 157faa0af9bca..02a54e9fa72c6 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -26,7 +26,7 @@ unwind = { path = "../libunwind" } hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] } [dependencies.backtrace] -version = "0.3.35" +version = "0.3.37" default-features = false # don't use coresymbolication on OSX features = [ "rustc-dep-of-std", # enable build support for integrating into libstd diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 952fd9ebfdf07..db4089c294812 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -158,7 +158,7 @@ pub fn take_hook() -> Box) + 'static + Sync + Send> { fn default_hook(info: &PanicInfo<'_>) { #[cfg(feature = "backtrace")] - use crate::sys_common::backtrace; + use crate::sys_common::{backtrace as backtrace_mod}; // If this is a double panic, make sure that we print a backtrace // for this panic. Otherwise only print it if logging is enabled. @@ -167,9 +167,9 @@ fn default_hook(info: &PanicInfo<'_>) { let panics = update_panic_count(0); if panics >= 2 { - Some(backtrace::PrintFormat::Full) + Some(backtrace::PrintFmt::Full) } else { - backtrace::log_enabled() + backtrace_mod::log_enabled() } }; @@ -197,7 +197,7 @@ fn default_hook(info: &PanicInfo<'_>) { static FIRST_PANIC: AtomicBool = AtomicBool::new(true); if let Some(format) = log_backtrace { - let _ = backtrace::print(err, format); + let _ = backtrace_mod::print(err, format); } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) { let _ = writeln!(err, "note: run with `RUST_BACKTRACE=1` \ environment variable to display a backtrace."); diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs index bf37ff7ddbd3a..f434b62aced67 100644 --- a/src/libstd/sys_common/backtrace.rs +++ b/src/libstd/sys_common/backtrace.rs @@ -2,23 +2,20 @@ /// supported platforms. use crate::env; +use crate::fmt; use crate::io; use crate::io::prelude::*; -use crate::mem; use crate::path::{self, Path}; -use crate::ptr; use crate::sync::atomic::{self, Ordering}; use crate::sys::mutex::Mutex; -use backtrace::{BytesOrWideString, Frame, Symbol}; - -pub const HEX_WIDTH: usize = 2 + 2 * mem::size_of::(); +use backtrace::{BacktraceFmt, BytesOrWideString, PrintFmt}; /// Max number of frames to print. const MAX_NB_FRAMES: usize = 100; /// Prints the current backtrace. -pub fn print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> { +pub fn print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> { static LOCK: Mutex = Mutex::new(); // There are issues currently linking libbacktrace into tests, and in @@ -39,26 +36,66 @@ pub fn print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> { } } -fn _print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> { - writeln!(w, "stack backtrace:")?; +fn _print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> { + struct DisplayBacktrace { + format: PrintFmt, + } + impl fmt::Display for DisplayBacktrace { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + _print_fmt(fmt, self.format) + } + } + write!(w, "{}", DisplayBacktrace { format }) +} - let mut printer = Printer::new(format, w); +fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::Result { + let mut print_path = move |fmt: &mut fmt::Formatter<'_>, bows: BytesOrWideString<'_>| { + output_filename(fmt, bows, print_fmt) + }; + let mut bt_fmt = BacktraceFmt::new(fmt, print_fmt, &mut print_path); + bt_fmt.add_context()?; + let mut skipped = false; unsafe { + let mut idx = 0; + let mut res = Ok(()); backtrace::trace_unsynchronized(|frame| { + if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES { + skipped = true; + return false; + } + let mut hit = false; + let mut stop = false; backtrace::resolve_frame_unsynchronized(frame, |symbol| { hit = true; - printer.output(frame, Some(symbol)); + if print_fmt == PrintFmt::Short { + if let Some(sym) = symbol.name().and_then(|s| s.as_str()) { + if sym.contains("__rust_begin_short_backtrace") { + skipped = true; + stop = true; + return; + } + } + } + + res = bt_fmt.frame().symbol(frame, symbol); }); + if stop { + return false; + } if !hit { - printer.output(frame, None); + res = bt_fmt.frame().print_raw(frame.ip(), None, None, None); } - !printer.done + + idx += 1; + res.is_ok() }); + res?; } - if printer.skipped { + bt_fmt.finish()?; + if skipped { writeln!( - w, + fmt, "note: Some details are omitted, \ run with `RUST_BACKTRACE=full` for a verbose backtrace." )?; @@ -77,33 +114,24 @@ where f() } -/// Controls how the backtrace should be formatted. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub enum PrintFormat { - /// Show only relevant data from the backtrace. - Short = 2, - /// Show all the frames with absolute path for files. - Full = 3, -} - // For now logging is turned off by default, and this function checks to see // whether the magical environment variable is present to see if it's turned on. -pub fn log_enabled() -> Option { +pub fn log_enabled() -> Option { static ENABLED: atomic::AtomicIsize = atomic::AtomicIsize::new(0); match ENABLED.load(Ordering::SeqCst) { 0 => {} 1 => return None, - 2 => return Some(PrintFormat::Short), - _ => return Some(PrintFormat::Full), + 2 => return Some(PrintFmt::Short), + _ => return Some(PrintFmt::Full), } let val = env::var_os("RUST_BACKTRACE").and_then(|x| { if &x == "0" { None } else if &x == "full" { - Some(PrintFormat::Full) + Some(PrintFmt::Full) } else { - Some(PrintFormat::Short) + Some(PrintFmt::Short) } }); ENABLED.store( @@ -116,130 +144,45 @@ pub fn log_enabled() -> Option { val } -struct Printer<'a, 'b> { - format: PrintFormat, - done: bool, - skipped: bool, - idx: usize, - out: &'a mut (dyn Write + 'b), -} - -impl<'a, 'b> Printer<'a, 'b> { - fn new(format: PrintFormat, out: &'a mut (dyn Write + 'b)) -> Printer<'a, 'b> { - Printer { format, done: false, skipped: false, idx: 0, out } - } - - /// Prints the symbol of the backtrace frame. - /// - /// These output functions should now be used everywhere to ensure consistency. - /// You may want to also use `output_fileline`. - fn output(&mut self, frame: &Frame, symbol: Option<&Symbol>) { - if self.idx > MAX_NB_FRAMES { - self.done = true; - self.skipped = true; - return; - } - if self._output(frame, symbol).is_err() { - self.done = true; - } - self.idx += 1; - } - - fn _output(&mut self, frame: &Frame, symbol: Option<&Symbol>) -> io::Result<()> { - if self.format == PrintFormat::Short { - if let Some(sym) = symbol.and_then(|s| s.name()).and_then(|s| s.as_str()) { - if sym.contains("__rust_begin_short_backtrace") { - self.skipped = true; - self.done = true; - return Ok(()); - } - } - - // Remove the `17: 0x0 - ` line. - if self.format == PrintFormat::Short && frame.ip() == ptr::null_mut() { - self.skipped = true; - return Ok(()); - } - } - - match self.format { - PrintFormat::Full => { - write!(self.out, " {:2}: {:2$?} - ", self.idx, frame.ip(), HEX_WIDTH)? - } - PrintFormat::Short => write!(self.out, " {:2}: ", self.idx)?, - } - - match symbol.and_then(|s| s.name()) { - Some(symbol) => { - match self.format { - PrintFormat::Full => write!(self.out, "{}", symbol)?, - // Strip the trailing hash if short mode. - PrintFormat::Short => write!(self.out, "{:#}", symbol)?, - } - } - None => self.out.write_all(b"")?, +/// Prints the filename of the backtrace frame. +/// +/// See also `output`. +fn output_filename( + fmt: &mut fmt::Formatter<'_>, + bows: BytesOrWideString<'_>, + print_fmt: PrintFmt, +) -> fmt::Result { + #[cfg(windows)] + let path_buf; + let file = match bows { + #[cfg(unix)] + BytesOrWideString::Bytes(bytes) => { + use crate::os::unix::prelude::*; + Path::new(crate::ffi::OsStr::from_bytes(bytes)) } - self.out.write_all(b"\n")?; - if let Some(sym) = symbol { - self.output_fileline(sym)?; + #[cfg(not(unix))] + BytesOrWideString::Bytes(bytes) => { + Path::new(crate::str::from_utf8(bytes).unwrap_or("")) } - Ok(()) - } - - /// Prints the filename and line number of the backtrace frame. - /// - /// See also `output`. - fn output_fileline(&mut self, symbol: &Symbol) -> io::Result<()> { #[cfg(windows)] - let path_buf; - let file = match symbol.filename_raw() { - #[cfg(unix)] - Some(BytesOrWideString::Bytes(bytes)) => { - use crate::os::unix::prelude::*; - Path::new(crate::ffi::OsStr::from_bytes(bytes)) - } - #[cfg(not(unix))] - Some(BytesOrWideString::Bytes(bytes)) => { - Path::new(crate::str::from_utf8(bytes).unwrap_or("")) - } - #[cfg(windows)] - Some(BytesOrWideString::Wide(wide)) => { - use crate::os::windows::prelude::*; - path_buf = crate::ffi::OsString::from_wide(wide); - Path::new(&path_buf) - } - #[cfg(not(windows))] - Some(BytesOrWideString::Wide(_wide)) => { - Path::new("") - } - None => return Ok(()), - }; - let line = match symbol.lineno() { - Some(line) => line, - None => return Ok(()), - }; - // prior line: " ##: {:2$} - func" - self.out.write_all(b"")?; - match self.format { - PrintFormat::Full => write!(self.out, " {:1$}", "", HEX_WIDTH)?, - PrintFormat::Short => write!(self.out, " ")?, + BytesOrWideString::Wide(wide) => { + use crate::os::windows::prelude::*; + path_buf = crate::ffi::OsString::from_wide(wide); + Path::new(&path_buf) } - - let mut already_printed = false; - if self.format == PrintFormat::Short && file.is_absolute() { - if let Ok(cwd) = env::current_dir() { - if let Ok(stripped) = file.strip_prefix(&cwd) { - if let Some(s) = stripped.to_str() { - write!(self.out, " at .{}{}:{}", path::MAIN_SEPARATOR, s, line)?; - already_printed = true; - } + #[cfg(not(windows))] + BytesOrWideString::Wide(_wide) => { + Path::new("") + } + }; + if print_fmt == PrintFmt::Short && file.is_absolute() { + if let Ok(cwd) = env::current_dir() { + if let Ok(stripped) = file.strip_prefix(&cwd) { + if let Some(s) = stripped.to_str() { + return write!(fmt, ".{}{}", path::MAIN_SEPARATOR, s); } } } - if !already_printed { - write!(self.out, " at {}:{}", file.display(), line)?; - } - - self.out.write_all(b"\n") } + fmt::Display::fmt(&file.display(), fmt) } From 21e7e3f1e903f6d6f2e6eacbbe5848fcd894db9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 4 Sep 2019 19:04:26 -0700 Subject: [PATCH 076/462] Point at variant on pattern field count mismatch --- src/librustc_typeck/check/pat.rs | 2 ++ src/test/ui/error-codes/E0023.stderr | 9 +++++++++ src/test/ui/match/match-pattern-field-mismatch.stderr | 3 +++ src/test/ui/pattern/pat-tuple-overfield.stderr | 6 ++++++ src/test/ui/pattern/pattern-error-continue.stderr | 3 +++ 5 files changed, 23 insertions(+) diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 4cf0df308fb4c..9a3f5e9e1b5d8 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -677,12 +677,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { let subpats_ending = if subpats.len() == 1 { "" } else { "s" }; let fields_ending = if variant.fields.len() == 1 { "" } else { "s" }; + let span = tcx.def_span(res.def_id()); struct_span_err!(tcx.sess, pat.span, E0023, "this pattern has {} field{}, but the corresponding {} has {} field{}", subpats.len(), subpats_ending, res.descr(), variant.fields.len(), fields_ending) .span_label(pat.span, format!("expected {} field{}, found {}", variant.fields.len(), fields_ending, subpats.len())) + .span_label(span, format!("{} defined here", res.descr())) .emit(); on_error(); return tcx.types.err; diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr index 1bc90a995fe30..d04e494c2585c 100644 --- a/src/test/ui/error-codes/E0023.stderr +++ b/src/test/ui/error-codes/E0023.stderr @@ -1,18 +1,27 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields --> $DIR/E0023.rs:10:9 | +LL | Apple(String, String), + | --------------------- tuple variant defined here +... LL | Fruit::Apple(a) => {}, | ^^^^^^^^^^^^^^^ expected 2 fields, found 1 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields --> $DIR/E0023.rs:11:9 | +LL | Apple(String, String), + | --------------------- tuple variant defined here +... LL | Fruit::Apple(a, b, c) => {}, | ^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field --> $DIR/E0023.rs:12:9 | +LL | Pear(u32), + | --------- tuple variant defined here +... LL | Fruit::Pear(1, 2) => {}, | ^^^^^^^^^^^^^^^^^ expected 1 field, found 2 diff --git a/src/test/ui/match/match-pattern-field-mismatch.stderr b/src/test/ui/match/match-pattern-field-mismatch.stderr index 663cd2cd24d56..c2298d6fbbf02 100644 --- a/src/test/ui/match/match-pattern-field-mismatch.stderr +++ b/src/test/ui/match/match-pattern-field-mismatch.stderr @@ -1,6 +1,9 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields --> $DIR/match-pattern-field-mismatch.rs:10:11 | +LL | Rgb(usize, usize, usize), + | ------------------------ tuple variant defined here +... LL | Color::Rgb(_, _) => { } | ^^^^^^^^^^^^^^^^ expected 3 fields, found 2 diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr index 0430897510b85..e64b6efb08da8 100644 --- a/src/test/ui/pattern/pat-tuple-overfield.stderr +++ b/src/test/ui/pattern/pat-tuple-overfield.stderr @@ -19,12 +19,18 @@ LL | (1, 2, .., 3, 4) => {} error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields --> $DIR/pat-tuple-overfield.rs:10:9 | +LL | struct S(u8, u8, u8); + | --------------------- tuple struct defined here +... LL | S(1, 2, 3, 4) => {} | ^^^^^^^^^^^^^ expected 3 fields, found 4 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields --> $DIR/pat-tuple-overfield.rs:12:9 | +LL | struct S(u8, u8, u8); + | --------------------- tuple struct defined here +... LL | S(1, 2, .., 3, 4) => {} | ^^^^^^^^^^^^^^^^^ expected 3 fields, found 4 diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr index a581f07496e6c..4fbc630644baa 100644 --- a/src/test/ui/pattern/pattern-error-continue.stderr +++ b/src/test/ui/pattern/pattern-error-continue.stderr @@ -15,6 +15,9 @@ LL | A::D(_) => (), error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields --> $DIR/pattern-error-continue.rs:17:9 | +LL | B(isize, isize), + | --------------- tuple variant defined here +... LL | A::B(_, _, _) => (), | ^^^^^^^^^^^^^ expected 2 fields, found 3 From af06bfb84c47add51a41153f6f71fc07d4c60a8d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 28 Aug 2019 07:20:54 +0200 Subject: [PATCH 077/462] resolve: extract `resolve_params`. --- src/librustc_resolve/late.rs | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index e15d02a9f7ec7..4595b1ff3f1cb 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -425,14 +425,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { self.label_ribs.push(Rib::new(rib_kind)); // Add each argument to the rib. - let mut bindings_list = FxHashMap::default(); - for argument in &declaration.inputs { - self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list); - - self.visit_ty(&argument.ty); + self.resolve_params(&declaration.inputs); - debug!("(resolving function) recorded argument"); - } visit::walk_fn_ret_ty(self, &declaration.output); // Resolve the function body, potentially inside the body of an async closure @@ -1135,6 +1129,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { } } + fn resolve_params(&mut self, params: &[Arg]) { + let mut bindings_list = FxHashMap::default(); + for param in params { + self.resolve_pattern(¶m.pat, PatternSource::FnParam, &mut bindings_list); + self.visit_ty(¶m.ty); + debug!("(resolving function / closure) recorded parameter"); + } + } + fn resolve_local(&mut self, local: &Local) { // Resolve the type. walk_list!(self, visit_ty, &local.ty); @@ -1860,20 +1863,12 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { // `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to // resolve the arguments within the proper scopes so that usages of them inside the // closure are detected as upvars rather than normal closure arg usages. - ExprKind::Closure( - _, IsAsync::Async { .. }, _, - ref fn_decl, ref body, _span, - ) => { - let rib_kind = NormalRibKind; - self.ribs[ValueNS].push(Rib::new(rib_kind)); + ExprKind::Closure(_, IsAsync::Async { .. }, _, ref fn_decl, ref body, _span) => { + self.ribs[ValueNS].push(Rib::new(NormalRibKind)); // Resolve arguments: - let mut bindings_list = FxHashMap::default(); - for argument in &fn_decl.inputs { - self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list); - self.visit_ty(&argument.ty); - } - // No need to resolve return type-- the outer closure return type is - // FunctionRetTy::Default + self.resolve_params(&fn_decl.inputs); + // No need to resolve return type -- + // the outer closure return type is `FunctionRetTy::Default`. // Now resolve the inner closure { From f8835eeaf898430dcf056791a210facfc60e9980 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 28 Aug 2019 08:48:10 +0200 Subject: [PATCH 078/462] resolve: cleanup using `with_rib`, etc. --- src/librustc_resolve/late.rs | 263 ++++++++++++++++------------------- 1 file changed, 118 insertions(+), 145 deletions(-) diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 4595b1ff3f1cb..5029d61d6e4e1 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -406,44 +406,32 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { visit::walk_foreign_item(this, foreign_item); }); } - fn visit_fn(&mut self, - function_kind: FnKind<'tcx>, - declaration: &'tcx FnDecl, - _: Span, - _: NodeId) - { + fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, declaration: &'tcx FnDecl, _: Span, _: NodeId) { debug!("(resolving function) entering function"); - let rib_kind = match function_kind { + let rib_kind = match fn_kind { FnKind::ItemFn(..) => FnItemRibKind, FnKind::Method(..) | FnKind::Closure(_) => NormalRibKind, }; // Create a value rib for the function. - self.ribs[ValueNS].push(Rib::new(rib_kind)); - - // Create a label rib for the function. - self.label_ribs.push(Rib::new(rib_kind)); - - // Add each argument to the rib. - self.resolve_params(&declaration.inputs); - - visit::walk_fn_ret_ty(self, &declaration.output); - - // Resolve the function body, potentially inside the body of an async closure - match function_kind { - FnKind::ItemFn(.., body) | - FnKind::Method(.., body) => { - self.visit_block(body); - } - FnKind::Closure(body) => { - self.visit_expr(body); - } - }; - - debug!("(resolving function) leaving function"); - - self.label_ribs.pop(); - self.ribs[ValueNS].pop(); + self.with_rib(ValueNS, rib_kind, |this| { + // Create a label rib for the function. + this.with_label_rib(rib_kind, |this| { + // Add each argument to the rib. + this.resolve_params(&declaration.inputs); + + visit::walk_fn_ret_ty(this, &declaration.output); + + // Resolve the function body, potentially inside the body of an async closure + match fn_kind { + FnKind::ItemFn(.., body) | + FnKind::Method(.., body) => this.visit_block(body), + FnKind::Closure(body) => this.visit_expr(body), + }; + + debug!("(resolving function) leaving function"); + }) + }); } fn visit_generics(&mut self, generics: &'tcx Generics) { @@ -522,13 +510,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { // although it may be useful to track other components as well for diagnostics. let graph_root = resolver.graph_root; let parent_scope = ParentScope::module(graph_root); + let start_rib_kind = ModuleRibKind(graph_root); LateResolutionVisitor { r: resolver, parent_scope, ribs: PerNS { - value_ns: vec![Rib::new(ModuleRibKind(graph_root))], - type_ns: vec![Rib::new(ModuleRibKind(graph_root))], - macro_ns: vec![Rib::new(ModuleRibKind(graph_root))], + value_ns: vec![Rib::new(start_rib_kind)], + type_ns: vec![Rib::new(start_rib_kind)], + macro_ns: vec![Rib::new(start_rib_kind)], }, label_ribs: Vec::new(), current_trait_ref: None, @@ -582,23 +571,32 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { // generate a fake "implementation scope" containing all the // implementations thus found, for compatibility with old resolve pass. - fn with_scope(&mut self, id: NodeId, f: F) -> T - where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T - { + /// Do some `work` within a new innermost rib of the given `kind` in the given namespace (`ns`). + fn with_rib( + &mut self, + ns: Namespace, + kind: RibKind<'a>, + work: impl FnOnce(&mut Self) -> T, + ) -> T { + self.ribs[ns].push(Rib::new(kind)); + let ret = work(self); + self.ribs[ns].pop(); + ret + } + + fn with_scope(&mut self, id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T { let id = self.r.definitions.local_def_id(id); let module = self.r.module_map.get(&id).cloned(); // clones a reference if let Some(module) = module { // Move down in the graph. let orig_module = replace(&mut self.parent_scope.module, module); - self.ribs[ValueNS].push(Rib::new(ModuleRibKind(module))); - self.ribs[TypeNS].push(Rib::new(ModuleRibKind(module))); - - let ret = f(self); - - self.parent_scope.module = orig_module; - self.ribs[ValueNS].pop(); - self.ribs[TypeNS].pop(); - ret + self.with_rib(ValueNS, ModuleRibKind(module), |this| { + this.with_rib(TypeNS, ModuleRibKind(module), |this| { + let ret = f(this); + this.parent_scope.module = orig_module; + ret + }) + }) } else { f(self) } @@ -802,7 +800,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { } fn with_generic_param_rib<'c, F>(&'c mut self, generic_params: GenericParameters<'a, 'c>, f: F) - where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) + where F: FnOnce(&mut Self) { debug!("with_generic_param_rib"); match generic_params { @@ -888,38 +886,24 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { } } - fn with_label_rib(&mut self, f: F) - where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) - { - self.label_ribs.push(Rib::new(NormalRibKind)); + fn with_label_rib(&mut self, kind: RibKind<'a>, f: impl FnOnce(&mut Self)) { + self.label_ribs.push(Rib::new(kind)); f(self); self.label_ribs.pop(); } - fn with_item_rib(&mut self, f: F) - where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) - { - self.ribs[ValueNS].push(Rib::new(ItemRibKind)); - self.ribs[TypeNS].push(Rib::new(ItemRibKind)); - f(self); - self.ribs[TypeNS].pop(); - self.ribs[ValueNS].pop(); + fn with_item_rib(&mut self, f: impl FnOnce(&mut Self)) { + self.with_rib(ValueNS, ItemRibKind, |this| this.with_rib(TypeNS, ItemRibKind, f)) } - fn with_constant_rib(&mut self, f: F) - where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) - { + fn with_constant_rib(&mut self, f: impl FnOnce(&mut Self)) { debug!("with_constant_rib"); - self.ribs[ValueNS].push(Rib::new(ConstantItemRibKind)); - self.label_ribs.push(Rib::new(ConstantItemRibKind)); - f(self); - self.label_ribs.pop(); - self.ribs[ValueNS].pop(); + self.with_rib(ValueNS, ConstantItemRibKind, |this| { + this.with_label_rib(ConstantItemRibKind, f); + }); } - fn with_current_self_type(&mut self, self_type: &Ty, f: F) -> T - where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T - { + fn with_current_self_type(&mut self, self_type: &Ty, f: impl FnOnce(&mut Self) -> T) -> T { // Handle nested impls (inside fn bodies) let previous_value = replace(&mut self.current_self_type, Some(self_type.clone())); let result = f(self); @@ -927,9 +911,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { result } - fn with_current_self_item(&mut self, self_item: &Item, f: F) -> T - where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T - { + fn with_current_self_item(&mut self, self_item: &Item, f: impl FnOnce(&mut Self) -> T) -> T { let previous_value = replace(&mut self.current_self_item, Some(self_item.id)); let result = f(self); self.current_self_item = previous_value; @@ -937,9 +919,11 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { } /// When evaluating a `trait` use its associated types' idents for suggestionsa in E0412. - fn with_trait_items(&mut self, trait_items: &Vec, f: F) -> T - where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T - { + fn with_trait_items( + &mut self, + trait_items: &Vec, + f: impl FnOnce(&mut Self) -> T, + ) -> T { let trait_assoc_types = replace( &mut self.current_trait_assoc_types, trait_items.iter().filter_map(|item| match &item.node { @@ -953,9 +937,11 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { } /// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`). - fn with_optional_trait_ref(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T - where F: FnOnce(&mut LateResolutionVisitor<'_, '_>, Option) -> T - { + fn with_optional_trait_ref( + &mut self, + opt_trait_ref: Option<&TraitRef>, + f: impl FnOnce(&mut Self, Option) -> T + ) -> T { let mut new_val = None; let mut new_id = None; if let Some(trait_ref) = opt_trait_ref { @@ -990,27 +976,18 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { result } - fn with_self_rib(&mut self, self_res: Res, f: F) - where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) - { + fn with_self_rib_ns(&mut self, ns: Namespace, self_res: Res, f: impl FnOnce(&mut Self)) { let mut self_type_rib = Rib::new(NormalRibKind); // Plain insert (no renaming, since types are not currently hygienic) self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res); - self.ribs[TypeNS].push(self_type_rib); + self.ribs[ns].push(self_type_rib); f(self); - self.ribs[TypeNS].pop(); + self.ribs[ns].pop(); } - fn with_self_struct_ctor_rib(&mut self, impl_id: DefId, f: F) - where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) - { - let self_res = Res::SelfCtor(impl_id); - let mut self_type_rib = Rib::new(NormalRibKind); - self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res); - self.ribs[ValueNS].push(self_type_rib); - f(self); - self.ribs[ValueNS].pop(); + fn with_self_rib(&mut self, self_res: Res, f: impl FnOnce(&mut Self)) { + self.with_self_rib_ns(TypeNS, self_res, f) } fn resolve_implementation(&mut self, @@ -1038,8 +1015,8 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { this.visit_generics(generics); // Resolve the items within the impl. this.with_current_self_type(self_type, |this| { - this.with_self_struct_ctor_rib(item_def_id, |this| { - debug!("resolve_implementation with_self_struct_ctor_rib"); + this.with_self_rib_ns(ValueNS, Res::SelfCtor(item_def_id), |this| { + debug!("resolve_implementation with_self_rib_ns(ValueNS, ...)"); for impl_item in impl_items { // We also need a new scope for the impl item type parameters. let generic_params = HasGenericParams(&impl_item.generics, @@ -1231,16 +1208,13 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { } fn resolve_arm(&mut self, arm: &Arm) { - self.ribs[ValueNS].push(Rib::new(NormalRibKind)); - - self.resolve_pats(&arm.pats, PatternSource::Match); - - if let Some(ref expr) = arm.guard { - self.visit_expr(expr) - } - self.visit_expr(&arm.body); - - self.ribs[ValueNS].pop(); + self.with_rib(ValueNS, NormalRibKind, |this| { + this.resolve_pats(&arm.pats, PatternSource::Match); + if let Some(ref expr) = arm.guard { + this.visit_expr(expr) + } + this.visit_expr(&arm.body); + }); } /// Arising from `source`, resolve a sequence of patterns (top level or-patterns). @@ -1333,7 +1307,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { pat_src == PatternSource::Let => { // `Variant1(a) | Variant2(a)`, ok // Reuse definition from the first `a`. - res = self.ribs[ValueNS].last_mut().unwrap().bindings[&ident]; + res = self.innermost_rib_bindings(ValueNS)[&ident]; } Some(..) => { span_bug!(ident.span, "two bindings with the same name from \ @@ -1343,7 +1317,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { // A completely fresh binding, add to the lists if it's valid. if ident.name != kw::Invalid { bindings.insert(ident, outer_pat_id); - self.ribs[ValueNS].last_mut().unwrap().bindings.insert(ident, res); + self.innermost_rib_bindings(ValueNS).insert(ident, res); } } } @@ -1351,6 +1325,10 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { res } + fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut FxHashMap { + &mut self.ribs[ns].last_mut().unwrap().bindings + } + fn resolve_pattern(&mut self, pat: &Pat, pat_src: PatternSource, @@ -1726,12 +1704,10 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { Some(result) } - fn with_resolved_label(&mut self, label: Option