From 6896ed383dbd3a847ef39b713449fc0393292828 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 09:47:58 +0300 Subject: [PATCH 01/59] 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 02/59] 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 03/59] 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 04/59] 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 05/59] 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 06/59] 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 07/59] 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 08/59] 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 09/59] 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 10/59] 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 11/59] 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 12/59] 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 13/59] 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 14/59] 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 a47e3c077cd7f201dbbf12140c12663df0fcda6f Mon Sep 17 00:00:00 2001 From: newpavlov Date: Wed, 21 Aug 2019 17:57:22 +0300 Subject: [PATCH 15/59] 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 16/59] 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 6374b8458f0796a1ff3ee2caec41321e801c35d1 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Thu, 29 Aug 2019 20:13:15 +0300 Subject: [PATCH 17/59] 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 18/59] 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 127311b75efd47a6f54aca49523c050566fc9823 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 29 Aug 2019 18:08:13 +0000 Subject: [PATCH 19/59] 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 0a757dfc41a481be50233a0e3920bfb20688e022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 30 Aug 2019 11:50:01 +0200 Subject: [PATCH 20/59] Update libc to 0.2.62 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b294b22026ed..b6f73ee955213 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1582,9 +1582,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" [[package]] name = "libc" -version = "0.2.61" +version = "0.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665266eb592905e8503ba3403020f4b8794d26263f412ca33171600eca9a6fa" +checksum = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" dependencies = [ "rustc-std-workspace-core", ] From 9fd203a01e0fe6fb307809fdfdbfcd3bda350cfc Mon Sep 17 00:00:00 2001 From: newpavlov Date: Fri, 30 Aug 2019 17:30:33 +0300 Subject: [PATCH 21/59] 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 6ed50f4777b65f117648dc2f524d684424c2730d Mon Sep 17 00:00:00 2001 From: Joe Ranweiler Date: Sat, 31 Aug 2019 20:00:08 -0700 Subject: [PATCH 22/59] 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 991f4366336820a61dd7f22e849c57d4a64b41ea Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 2 Sep 2019 15:58:05 +0200 Subject: [PATCH 23/59] 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 0662fcf4f950ec2800f0b1e02254ef2389b55079 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 3 Sep 2019 14:37:53 +0000 Subject: [PATCH 24/59] 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 cb84aa4744c7a6120d8311806912240275d04960 Mon Sep 17 00:00:00 2001 From: Shiqing Date: Mon, 2 Sep 2019 21:03:35 +0800 Subject: [PATCH 25/59] 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 53fe76479aab03b1fbe5b7184f45484886f769b1 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 4 Sep 2019 16:02:31 -0700 Subject: [PATCH 26/59] 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 af06bfb84c47add51a41153f6f71fc07d4c60a8d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 28 Aug 2019 07:20:54 +0200 Subject: [PATCH 27/59] 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 28/59] 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