diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 207359ed6968f..024594517d988 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -4,16 +4,6 @@ //! heap allocation in Rust. Boxes provide ownership for this allocation, and //! drop their contents when they go out of scope. //! -//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for -//! its allocation. It is valid to convert both ways between a [`Box`] and a -//! raw pointer allocated with the [`Global`] allocator, given that the -//! [`Layout`] used with the allocator is correct for the type. More precisely, -//! a `value: *mut T` that has been allocated with the [`Global`] allocator -//! with `Layout::for_value(&*value)` may be converted into a box using -//! `Box::::from_raw(value)`. Conversely, the memory backing a `value: *mut -//! T` obtained from `Box::::into_raw` may be deallocated using the -//! [`Global`] allocator with `Layout::for_value(&*value)`. -//! //! # Examples //! //! Move a value from the stack to the heap by creating a [`Box`]: @@ -61,6 +51,19 @@ //! for a `Cons`. By introducing a `Box`, which has a defined size, we know how //! big `Cons` needs to be. //! +//! # Memory layout +//! +//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for +//! its allocation. It is valid to convert both ways between a [`Box`] and a +//! raw pointer allocated with the [`Global`] allocator, given that the +//! [`Layout`] used with the allocator is correct for the type. More precisely, +//! a `value: *mut T` that has been allocated with the [`Global`] allocator +//! with `Layout::for_value(&*value)` may be converted into a box using +//! `Box::::from_raw(value)`. Conversely, the memory backing a `value: *mut +//! T` obtained from `Box::::into_raw` may be deallocated using the +//! [`Global`] allocator with `Layout::for_value(&*value)`. +//! +//! //! [dereferencing]: ../../std/ops/trait.Deref.html //! [`Box`]: struct.Box.html //! [`Global`]: ../alloc/struct.Global.html @@ -127,24 +130,38 @@ impl Box { /// /// After calling this function, the raw pointer is owned by the /// resulting `Box`. Specifically, the `Box` destructor will call - /// the destructor of `T` and free the allocated memory. Since the - /// way `Box` allocates and releases memory is unspecified, the - /// only valid pointer to pass to this function is the one taken - /// from another `Box` via the [`Box::into_raw`] function. + /// the destructor of `T` and free the allocated memory. For this + /// to be safe, the memory must have been allocated in accordance + /// with the [memory layout] used by `Box` . + /// + /// # Safety /// /// This function is unsafe because improper use may lead to /// memory problems. For example, a double-free may occur if the /// function is called twice on the same raw pointer. /// - /// [`Box::into_raw`]: struct.Box.html#method.into_raw - /// /// # Examples - /// + /// Recreate a `Box` which was previously converted to a raw pointer + /// using [`Box::into_raw`]: /// ``` /// let x = Box::new(5); /// let ptr = Box::into_raw(x); /// let x = unsafe { Box::from_raw(ptr) }; /// ``` + /// Manually create a `Box` from scratch by using the global allocator: + /// ``` + /// use std::alloc::{alloc, Layout}; + /// + /// unsafe { + /// let ptr = alloc(Layout::new::()) as *mut i32; + /// *ptr = 5; + /// let x = Box::from_raw(ptr); + /// } + /// ``` + /// + /// [memory layout]: index.html#memory-layout + /// [`Layout`]: ../alloc/struct.Layout.html + /// [`Box::into_raw`]: struct.Box.html#method.into_raw #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub unsafe fn from_raw(raw: *mut T) -> Self { @@ -157,22 +174,40 @@ impl Box { /// /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the - /// caller should properly destroy `T` and release the memory. The - /// proper way to do so is to convert the raw pointer back into a - /// `Box` with the [`Box::from_raw`] function. + /// caller should properly destroy `T` and release the memory, taking + /// into account the [memory layout] used by `Box`. The easiest way to + /// do this is to convert the raw pointer back into a `Box` with the + /// [`Box::from_raw`] function, allowing the `Box` destructor to perform + /// the cleanup. /// /// Note: this is an associated function, which means that you have /// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This /// is so that there is no conflict with a method on the inner type. /// - /// [`Box::from_raw`]: struct.Box.html#method.from_raw - /// /// # Examples - /// + /// Converting the raw pointer back into a `Box` with [`Box::from_raw`] + /// for automatic cleanup: /// ``` - /// let x = Box::new(5); + /// let x = Box::new(String::from("Hello")); /// let ptr = Box::into_raw(x); + /// let x = unsafe { Box::from_raw(ptr) }; + /// ``` + /// Manual cleanup by explicitly running the destructor and deallocating + /// the memory: /// ``` + /// use std::alloc::{dealloc, Layout}; + /// use std::ptr; + /// + /// let x = Box::new(String::from("Hello")); + /// let p = Box::into_raw(x); + /// unsafe { + /// ptr::drop_in_place(p); + /// dealloc(p as *mut u8, Layout::new::()); + /// } + /// ``` + /// + /// [memory layout]: index.html#memory-layout + /// [`Box::from_raw`]: struct.Box.html#method.from_raw #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub fn into_raw(b: Box) -> *mut T { @@ -184,7 +219,7 @@ impl Box { /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the /// caller should properly destroy `T` and release the memory. The - /// proper way to do so is to convert the `NonNull` pointer + /// easiest way to do so is to convert the `NonNull` pointer /// into a raw pointer and back into a `Box` with the [`Box::from_raw`] /// function. /// @@ -203,6 +238,10 @@ impl Box { /// fn main() { /// let x = Box::new(5); /// let ptr = Box::into_raw_non_null(x); + /// + /// // Clean up the memory by converting the NonNull pointer back + /// // into a Box and letting the Box be dropped. + /// let x = unsafe { Box::from_raw(ptr.as_ptr()) }; /// } /// ``` #[unstable(feature = "box_into_raw_non_null", issue = "47336")] diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 24bee6355a7cc..56869f38a4f6b 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -466,7 +466,7 @@ pub unsafe fn zeroed() -> T { /// [`MaybeUninit`]: union.MaybeUninit.html /// [inv]: union.MaybeUninit.html#initialization-invariant #[inline] -#[rustc_deprecated(since = "1.40.0", reason = "use `mem::MaybeUninit` instead")] +#[rustc_deprecated(since = "1.38.0", reason = "use `mem::MaybeUninit` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn uninitialized() -> T { intrinsics::panic_if_uninhabited::(); diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 9bdce37b8baec..e7f54f6609d29 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -38,6 +38,7 @@ use rustc_data_structures::small_c_str::SmallCStr; use rustc_target::abi::HasDataLayout; use libc::{c_uint, c_longlong}; +use std::collections::hash_map::Entry; use std::ffi::CString; use std::fmt::{self, Write}; use std::hash::{Hash, Hasher}; @@ -45,7 +46,7 @@ use std::iter; use std::ptr; use std::path::{Path, PathBuf}; use syntax::ast; -use syntax::symbol::{Interner, InternedString, Symbol}; +use syntax::symbol::{Interner, InternedString}; use syntax_pos::{self, Span, FileName}; impl PartialEq for llvm::Metadata { @@ -787,49 +788,48 @@ pub fn file_metadata(cx: &CodegenCx<'ll, '_>, file_name, defining_crate); - let file_name = &file_name.to_string(); - let file_name_symbol = Symbol::intern(file_name); - if defining_crate == LOCAL_CRATE { - let directory = &cx.sess().working_dir.0.to_string_lossy(); - file_metadata_raw(cx, file_name, Some(file_name_symbol), - directory, Some(Symbol::intern(directory))) + let file_name = Some(file_name.to_string()); + let directory = if defining_crate == LOCAL_CRATE { + Some(cx.sess().working_dir.0.to_string_lossy().to_string()) } else { // If the path comes from an upstream crate we assume it has been made // independent of the compiler's working directory one way or another. - file_metadata_raw(cx, file_name, Some(file_name_symbol), "", None) - } + None + }; + file_metadata_raw(cx, file_name, directory) } pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile { - file_metadata_raw(cx, "", None, "", None) + file_metadata_raw(cx, None, None) } fn file_metadata_raw(cx: &CodegenCx<'ll, '_>, - file_name: &str, - file_name_symbol: Option, - directory: &str, - directory_symbol: Option) + file_name: Option, + directory: Option) -> &'ll DIFile { - let key = (file_name_symbol, directory_symbol); + let key = (file_name, directory); + + match debug_context(cx).created_files.borrow_mut().entry(key) { + Entry::Occupied(o) => return o.get(), + Entry::Vacant(v) => { + let (file_name, directory) = v.key(); + debug!("file_metadata: file_name: {:?}, directory: {:?}", file_name, directory); + + let file_name = SmallCStr::new( + if let Some(file_name) = file_name { &file_name } else { "" }); + let directory = SmallCStr::new( + if let Some(directory) = directory { &directory } else { "" }); + + let file_metadata = unsafe { + llvm::LLVMRustDIBuilderCreateFile(DIB(cx), + file_name.as_ptr(), + directory.as_ptr()) + }; - if let Some(file_metadata) = debug_context(cx).created_files.borrow().get(&key) { - return *file_metadata; + v.insert(file_metadata); + file_metadata + } } - - debug!("file_metadata: file_name: {}, directory: {}", file_name, directory); - - let file_name = SmallCStr::new(file_name); - let directory = SmallCStr::new(directory); - - let file_metadata = unsafe { - llvm::LLVMRustDIBuilderCreateFile(DIB(cx), - file_name.as_ptr(), - directory.as_ptr()) - }; - - let mut created_files = debug_context(cx).created_files.borrow_mut(); - created_files.insert(key, file_metadata); - file_metadata } fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType { diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index f3070a03b4ed5..527290392fff4 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -37,7 +37,7 @@ use std::ffi::CString; use syntax_pos::{self, Span, Pos}; use syntax::ast; -use syntax::symbol::{Symbol, InternedString}; +use syntax::symbol::InternedString; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt}; use rustc_codegen_ssa::traits::*; @@ -63,7 +63,7 @@ pub struct CrateDebugContext<'a, 'tcx> { llcontext: &'a llvm::Context, llmod: &'a llvm::Module, builder: &'a mut DIBuilder<'a>, - created_files: RefCell, Option), &'a DIFile>>, + created_files: RefCell, Option), &'a DIFile>>, created_enum_disr_types: RefCell>, type_map: RefCell>, diff --git a/src/librustc_data_structures/macros.rs b/src/librustc_data_structures/macros.rs index 7fc23999284a7..b851263aaf9c4 100644 --- a/src/librustc_data_structures/macros.rs +++ b/src/librustc_data_structures/macros.rs @@ -1,13 +1,12 @@ -/// A simple static assertion macro. The first argument should be a unique -/// ALL_CAPS identifier that describes the condition. +/// A simple static assertion macro. #[macro_export] -#[allow_internal_unstable(type_ascription)] +#[allow_internal_unstable(type_ascription, underscore_const_names)] macro_rules! static_assert { - ($name:ident: $test:expr) => { + ($test:expr) => { // Use the bool to access an array such that if the bool is false, the access // is out-of-bounds. #[allow(dead_code)] - static $name: () = [()][!($test: bool) as usize]; + const _: () = [()][!($test: bool) as usize]; } } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 087256a971056..e6710d668dc3c 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -355,20 +355,20 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { return; } - let child = child.res.def_id(); - - match visible_parent_map.entry(child) { - Entry::Occupied(mut entry) => { - // If `child` is defined in crate `cnum`, ensure - // that it is mapped to a parent in `cnum`. - if child.krate == cnum && entry.get().krate != cnum { + if let Some(child) = child.res.opt_def_id() { + match visible_parent_map.entry(child) { + Entry::Occupied(mut entry) => { + // If `child` is defined in crate `cnum`, ensure + // that it is mapped to a parent in `cnum`. + if child.krate == cnum && entry.get().krate != cnum { + entry.insert(parent); + } + } + Entry::Vacant(entry) => { entry.insert(parent); + bfs_queue.push_back(child); } } - Entry::Vacant(entry) => { - entry.insert(parent); - bfs_queue.push_back(child); - } } }; diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index d2da1e6e3ac9d..780b3c9686b6a 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -212,8 +212,8 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> { // Create a statement which reads the discriminant into a temporary fn get_discr(&self, mir: &mut Mir<'tcx>) -> (Statement<'tcx>, Place<'tcx>) { let temp_decl = LocalDecl::new_internal(self.tcx.types.isize, mir.span); - let temp = Place::Base(PlaceBase::Local(Local::new(mir.local_decls.len()))); - mir.local_decls.push(temp_decl); + let local_decls_len = mir.local_decls.push(temp_decl); + let temp = Place::Base(PlaceBase::Local(local_decls_len)); let self_place = Place::Base(PlaceBase::Local(self_arg())); let assign = Statement { diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 579f75ba51657..84e2caec68e1c 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -544,14 +544,14 @@ impl Qualif for IsNotImplicitlyPromotable { // Ensure the `IDX` values are sequential (`0..QUALIF_COUNT`). macro_rules! static_assert_seq_qualifs { ($i:expr => $first:ident $(, $rest:ident)*) => { - static_assert!(SEQ_QUALIFS: { + static_assert!({ static_assert_seq_qualifs!($i + 1 => $($rest),*); $first::IDX == $i }); }; ($i:expr =>) => { - static_assert!(SEQ_QUALIFS: QUALIF_COUNT == $i); + static_assert!(QUALIF_COUNT == $i); }; } static_assert_seq_qualifs!( diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs index 8e6f50773abfe..2a553b2c93bd3 100644 --- a/src/libstd/sys/redox/process.rs +++ b/src/libstd/sys/redox/process.rs @@ -150,7 +150,7 @@ impl Command { match cvt(syscall::clone(0))? { 0 => { drop(input); - let err = self.do_exec(theirs); + let Err(err) = self.do_exec(theirs); let errno = err.raw_os_error().unwrap_or(syscall::EINVAL) as u32; let bytes = [ (errno >> 24) as u8, @@ -218,7 +218,10 @@ impl Command { } match self.setup_io(default, true) { - Ok((_, theirs)) => unsafe { self.do_exec(theirs) }, + Ok((_, theirs)) => unsafe { + let Err(e) = self.do_exec(theirs); + e + }, Err(e) => e, } } @@ -253,45 +256,38 @@ impl Command { // allocation). Instead we just close it manually. This will never // have the drop glue anyway because this code never returns (the // child will either exec() or invoke syscall::exit) - unsafe fn do_exec(&mut self, stdio: ChildPipes) -> io::Error { - macro_rules! t { - ($e:expr) => (match $e { - Ok(e) => e, - Err(e) => return e, - }) - } - + unsafe fn do_exec(&mut self, stdio: ChildPipes) -> Result { if let Some(fd) = stdio.stderr.fd() { - t!(cvt(syscall::dup2(fd, 2, &[]))); - let mut flags = t!(cvt(syscall::fcntl(2, syscall::F_GETFD, 0))); + cvt(syscall::dup2(fd, 2, &[]))?; + let mut flags = cvt(syscall::fcntl(2, syscall::F_GETFD, 0))?; flags &= ! syscall::O_CLOEXEC; - t!(cvt(syscall::fcntl(2, syscall::F_SETFD, flags))); + cvt(syscall::fcntl(2, syscall::F_SETFD, flags))?; } if let Some(fd) = stdio.stdout.fd() { - t!(cvt(syscall::dup2(fd, 1, &[]))); - let mut flags = t!(cvt(syscall::fcntl(1, syscall::F_GETFD, 0))); + cvt(syscall::dup2(fd, 1, &[]))?; + let mut flags = cvt(syscall::fcntl(1, syscall::F_GETFD, 0))?; flags &= ! syscall::O_CLOEXEC; - t!(cvt(syscall::fcntl(1, syscall::F_SETFD, flags))); + cvt(syscall::fcntl(1, syscall::F_SETFD, flags))?; } if let Some(fd) = stdio.stdin.fd() { - t!(cvt(syscall::dup2(fd, 0, &[]))); - let mut flags = t!(cvt(syscall::fcntl(0, syscall::F_GETFD, 0))); + cvt(syscall::dup2(fd, 0, &[]))?; + let mut flags = cvt(syscall::fcntl(0, syscall::F_GETFD, 0))?; flags &= ! syscall::O_CLOEXEC; - t!(cvt(syscall::fcntl(0, syscall::F_SETFD, flags))); + cvt(syscall::fcntl(0, syscall::F_SETFD, flags))?; } if let Some(g) = self.gid { - t!(cvt(syscall::setregid(g as usize, g as usize))); + cvt(syscall::setregid(g as usize, g as usize))?; } if let Some(u) = self.uid { - t!(cvt(syscall::setreuid(u as usize, u as usize))); + cvt(syscall::setreuid(u as usize, u as usize))?; } if let Some(ref cwd) = self.cwd { - t!(cvt(syscall::chdir(cwd))); + cvt(syscall::chdir(cwd))?; } for callback in self.closures.iter_mut() { - t!(callback()); + callback()?; } self.env.apply(); @@ -313,9 +309,9 @@ impl Command { }; let mut file = if let Some(program) = program { - t!(File::open(program.as_os_str())) + File::open(program.as_os_str())? } else { - return io::Error::from_raw_os_error(syscall::ENOENT); + return Err(io::Error::from_raw_os_error(syscall::ENOENT)); }; // Push all the arguments @@ -327,7 +323,7 @@ impl Command { let mut shebang = [0; 2]; let mut read = 0; loop { - match t!(reader.read(&mut shebang[read..])) { + match reader.read(&mut shebang[read..])? { 0 => break, n => read += n, } @@ -338,9 +334,9 @@ impl Command { // First of all, since we'll be passing another file to // fexec(), we need to manually check that we have permission // to execute this file: - let uid = t!(cvt(syscall::getuid())); - let gid = t!(cvt(syscall::getgid())); - let meta = t!(file.metadata()); + let uid = cvt(syscall::getuid())?; + let gid = cvt(syscall::getgid())?; + let meta = file.metadata()?; let mode = if uid == meta.uid() as usize { meta.mode() >> 3*2 & 0o7 @@ -350,12 +346,12 @@ impl Command { meta.mode() & 0o7 }; if mode & 1 == 0 { - return io::Error::from_raw_os_error(syscall::EPERM); + return Err(io::Error::from_raw_os_error(syscall::EPERM)); } // Second of all, we need to actually read which interpreter it wants let mut interpreter = Vec::new(); - t!(reader.read_until(b'\n', &mut interpreter)); + reader.read_until(b'\n', &mut interpreter)?; // Pop one trailing newline, if any if interpreter.ends_with(&[b'\n']) { interpreter.pop().unwrap(); @@ -373,11 +369,11 @@ impl Command { }; if let Some(ref interpreter) = interpreter { let path: &OsStr = OsStr::from_bytes(&interpreter); - file = t!(File::open(path)); + file = File::open(path)?; args.push([interpreter.as_ptr() as usize, interpreter.len()]); } else { - t!(file.seek(SeekFrom::Start(0))); + file.seek(SeekFrom::Start(0))?; } args.push([self.program.as_ptr() as usize, self.program.len()]); @@ -396,13 +392,12 @@ impl Command { } if let Err(err) = syscall::fexec(file.as_raw_fd(), &args, &vars) { - io::Error::from_raw_os_error(err.errno as i32) + Err(io::Error::from_raw_os_error(err.errno as i32)) } else { panic!("return from exec without err"); } } - fn setup_io(&self, default: Stdio, needs_stdin: bool) -> io::Result<(StdioPipes, ChildPipes)> { let null = Stdio::Null; diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 220b1fd453131..80fe763aecc88 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -47,7 +47,7 @@ impl Command { match result { 0 => { drop(input); - let err = self.do_exec(theirs, envp.as_ref()); + let Err(err) = self.do_exec(theirs, envp.as_ref()); let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32; let bytes = [ (errno >> 24) as u8, @@ -123,7 +123,8 @@ impl Command { // environment lock before we try to exec. let _lock = sys::os::env_lock(); - self.do_exec(theirs, envp.as_ref()) + let Err(e) = self.do_exec(theirs, envp.as_ref()); + e } } Err(e) => e, @@ -164,29 +165,22 @@ impl Command { &mut self, stdio: ChildPipes, maybe_envp: Option<&CStringArray> - ) -> io::Error { + ) -> Result { use crate::sys::{self, cvt_r}; - macro_rules! t { - ($e:expr) => (match $e { - Ok(e) => e, - Err(e) => return e, - }) - } - if let Some(fd) = stdio.stdin.fd() { - t!(cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))); + cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))?; } if let Some(fd) = stdio.stdout.fd() { - t!(cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))); + cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))?; } if let Some(fd) = stdio.stderr.fd() { - t!(cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))); + cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?; } if cfg!(not(any(target_os = "l4re"))) { if let Some(u) = self.get_gid() { - t!(cvt(libc::setgid(u as gid_t))); + cvt(libc::setgid(u as gid_t))?; } if let Some(u) = self.get_uid() { // When dropping privileges from root, the `setgroups` call @@ -198,11 +192,11 @@ impl Command { // privilege dropping function. let _ = libc::setgroups(0, ptr::null()); - t!(cvt(libc::setuid(u as uid_t))); + cvt(libc::setuid(u as uid_t))?; } } if let Some(ref cwd) = *self.get_cwd() { - t!(cvt(libc::chdir(cwd.as_ptr()))); + cvt(libc::chdir(cwd.as_ptr()))?; } // emscripten has no signal support. @@ -225,18 +219,18 @@ impl Command { 0, mem::size_of::()); } else { - t!(cvt(libc::sigemptyset(&mut set))); + cvt(libc::sigemptyset(&mut set))?; } - t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, - ptr::null_mut()))); + cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, + ptr::null_mut()))?; let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL); if ret == libc::SIG_ERR { - return io::Error::last_os_error() + return Err(io::Error::last_os_error()) } } for callback in self.get_closures().iter_mut() { - t!(callback()); + callback()?; } // Although we're performing an exec here we may also return with an @@ -261,7 +255,7 @@ impl Command { } libc::execvp(self.get_argv()[0], self.get_argv().as_ptr()); - io::Error::last_os_error() + Err(io::Error::last_os_error()) } #[cfg(not(any(target_os = "macos", target_os = "freebsd", diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 0611c1d9b42a5..d0af1afd8fdbd 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -329,6 +329,23 @@ pub fn stream_to_parser(sess: &ParseSess, stream: TokenStream) -> Parser<'_> { Parser::new(sess, stream, None, true, false) } +/// Given stream, the `ParseSess` and the base directory, produces a parser. +/// +/// Use this function when you are creating a parser from the token stream +/// and also care about the current working directory of the parser (e.g., +/// you are trying to resolve modules defined inside a macro invocation). +/// +/// # Note +/// +/// The main usage of this function is outside of rustc, for those who uses +/// libsyntax as a library. Please do not remove this function while refactoring +/// just because it is not used in rustc codebase! +pub fn stream_to_parser_with_base_dir<'a>(sess: &'a ParseSess, + stream: TokenStream, + base_dir: Directory<'a>) -> Parser<'a> { + Parser::new(sess, stream, Some(base_dir), true, false) +} + /// A sequence separator. pub struct SeqSep { /// The seperator token.