From e2820ea06ceeb19cedb8ac38a4f1b7b6abb1fcfd Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 27 Aug 2017 10:51:05 -0600 Subject: [PATCH 1/7] Sync with upstream syscall library --- src/libstd/sys/redox/syscall/call.rs | 63 +++++++++++++++++----- src/libstd/sys/redox/syscall/data.rs | 72 ++++++++++++++++++++++++++ src/libstd/sys/redox/syscall/flag.rs | 17 ++++++ src/libstd/sys/redox/syscall/number.rs | 6 +++ 4 files changed, 146 insertions(+), 12 deletions(-) diff --git a/src/libstd/sys/redox/syscall/call.rs b/src/libstd/sys/redox/syscall/call.rs index 9fc809eb821d8..b0ff69dd6345c 100644 --- a/src/libstd/sys/redox/syscall/call.rs +++ b/src/libstd/sys/redox/syscall/call.rs @@ -9,11 +9,17 @@ // except according to those terms. use super::arch::*; -use super::data::{Stat, StatVfs, TimeSpec}; +use super::data::{SigAction, Stat, StatVfs, TimeSpec}; use super::error::Result; use super::number::*; -use core::mem; +use core::{mem, ptr}; + +// Signal restorer +extern "C" fn restorer() -> ! { + sigreturn().unwrap(); + unreachable!(); +} /// Set the end of the process's heap /// @@ -43,12 +49,12 @@ pub unsafe fn brk(addr: usize) -> Result { /// * `EIO` - an I/O error occurred /// * `ENOENT` - `path` does not exit /// * `ENOTDIR` - `path` is not a directory -pub fn chdir(path: &str) -> Result { - unsafe { syscall2(SYS_CHDIR, path.as_ptr() as usize, path.len()) } +pub fn chdir>(path: T) -> Result { + unsafe { syscall2(SYS_CHDIR, path.as_ref().as_ptr() as usize, path.as_ref().len()) } } -pub fn chmod(path: &str, mode: usize) -> Result { - unsafe { syscall3(SYS_CHMOD, path.as_ptr() as usize, path.len(), mode) } +pub fn chmod>(path: T, mode: usize) -> Result { + unsafe { syscall3(SYS_CHMOD, path.as_ref().as_ptr() as usize, path.as_ref().len(), mode) } } /// Produce a fork of the current process, or a new process thread @@ -132,6 +138,11 @@ pub fn ftruncate(fd: usize, len: usize) -> Result { unsafe { syscall2(SYS_FTRUNCATE, fd, len) } } +// Change modify and/or access times +pub fn futimens(fd: usize, times: &[TimeSpec]) -> Result { + unsafe { syscall3(SYS_FUTIMENS, fd, times.as_ptr() as usize, times.len() * mem::size_of::()) } +} + /// Fast userspace mutex pub unsafe fn futex(addr: *mut i32, op: usize, val: i32, val2: usize, addr2: *mut i32) -> Result { @@ -173,6 +184,16 @@ pub fn getpid() -> Result { unsafe { syscall0(SYS_GETPID) } } +/// Get the process group ID +pub fn getpgid(pid: usize) -> Result { + unsafe { syscall1(SYS_GETPGID, pid) } +} + +/// Get the parent process ID +pub fn getppid() -> Result { + unsafe { syscall0(SYS_GETPPID) } +} + /// Get the current user ID pub fn getuid() -> Result { unsafe { syscall0(SYS_GETUID) } @@ -210,8 +231,8 @@ pub fn nanosleep(req: &TimeSpec, rem: &mut TimeSpec) -> Result { } /// Open a file -pub fn open(path: &str, flags: usize) -> Result { - unsafe { syscall3(SYS_OPEN, path.as_ptr() as usize, path.len(), flags) } +pub fn open>(path: T, flags: usize) -> Result { + unsafe { syscall3(SYS_OPEN, path.as_ref().as_ptr() as usize, path.as_ref().len(), flags) } } /// Allocate pages, linearly in physical memory @@ -245,8 +266,13 @@ pub fn read(fd: usize, buf: &mut [u8]) -> Result { } /// Remove a directory -pub fn rmdir(path: &str) -> Result { - unsafe { syscall2(SYS_RMDIR, path.as_ptr() as usize, path.len()) } +pub fn rmdir>(path: T) -> Result { + unsafe { syscall2(SYS_RMDIR, path.as_ref().as_ptr() as usize, path.as_ref().len()) } +} + +/// Set the process group ID +pub fn setpgid(pid: usize, pgid: usize) -> Result { + unsafe { syscall2(SYS_SETPGID, pid, pgid) } } /// Set the current process group IDs @@ -264,9 +290,22 @@ pub fn setreuid(ruid: usize, euid: usize) -> Result { unsafe { syscall2(SYS_SETREUID, ruid, euid) } } +/// Set up a signal handler +pub fn sigaction(sig: usize, act: Option<&SigAction>, oldact: Option<&mut SigAction>) -> Result { + unsafe { syscall4(SYS_SIGACTION, sig, + act.map(|x| x as *const _).unwrap_or_else(ptr::null) as usize, + oldact.map(|x| x as *mut _).unwrap_or_else(ptr::null_mut) as usize, + restorer as usize) } +} + +// Return from signal handler +pub fn sigreturn() -> Result { + unsafe { syscall0(SYS_SIGRETURN) } +} + /// Remove a file -pub fn unlink(path: &str) -> Result { - unsafe { syscall2(SYS_UNLINK, path.as_ptr() as usize, path.len()) } +pub fn unlink>(path: T) -> Result { + unsafe { syscall2(SYS_UNLINK, path.as_ref().as_ptr() as usize, path.as_ref().len()) } } /// Convert a virtual address to a physical one diff --git a/src/libstd/sys/redox/syscall/data.rs b/src/libstd/sys/redox/syscall/data.rs index 0beb173477d90..3566d85d9b451 100644 --- a/src/libstd/sys/redox/syscall/data.rs +++ b/src/libstd/sys/redox/syscall/data.rs @@ -11,6 +11,78 @@ use core::ops::{Deref, DerefMut}; use core::{mem, slice}; +#[derive(Copy, Clone, Debug, Default)] +pub struct Event { + pub id: usize, + pub flags: usize, + pub data: usize +} + +impl Deref for Event { + type Target = [u8]; + fn deref(&self) -> &[u8] { + unsafe { + slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::()) as &[u8] + } + } +} + +impl DerefMut for Event { + fn deref_mut(&mut self) -> &mut [u8] { + unsafe { + slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::()) as &mut [u8] + } + } +} + +#[derive(Copy, Clone, Debug, Default)] +#[repr(C)] +pub struct Packet { + pub id: u64, + pub pid: usize, + pub uid: u32, + pub gid: u32, + pub a: usize, + pub b: usize, + pub c: usize, + pub d: usize +} + +impl Deref for Packet { + type Target = [u8]; + fn deref(&self) -> &[u8] { + unsafe { + slice::from_raw_parts(self as *const Packet as *const u8, mem::size_of::()) as &[u8] + } + } +} + +impl DerefMut for Packet { + fn deref_mut(&mut self) -> &mut [u8] { + unsafe { + slice::from_raw_parts_mut(self as *mut Packet as *mut u8, mem::size_of::()) as &mut [u8] + } + } +} + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct SigAction { + pub sa_handler: extern "C" fn(usize), + pub sa_mask: [u64; 2], + pub sa_flags: usize, +} + +impl Default for SigAction { + fn default() -> Self { + Self { + sa_handler: unsafe { mem::transmute(0usize) }, + sa_mask: [0; 2], + sa_flags: 0, + } + } +} + #[derive(Copy, Clone, Debug, Default)] #[repr(C)] pub struct Stat { diff --git a/src/libstd/sys/redox/syscall/flag.rs b/src/libstd/sys/redox/syscall/flag.rs index 892007df2b7c6..0f61b9fa77b52 100644 --- a/src/libstd/sys/redox/syscall/flag.rs +++ b/src/libstd/sys/redox/syscall/flag.rs @@ -11,7 +11,9 @@ pub const CLONE_VM: usize = 0x100; pub const CLONE_FS: usize = 0x200; pub const CLONE_FILES: usize = 0x400; +pub const CLONE_SIGHAND: usize = 0x800; pub const CLONE_VFORK: usize = 0x4000; +pub const CLONE_THREAD: usize = 0x10000; pub const CLOCK_REALTIME: usize = 1; pub const CLOCK_MONOTONIC: usize = 4; @@ -20,6 +22,7 @@ pub const EVENT_NONE: usize = 0; pub const EVENT_READ: usize = 1; pub const EVENT_WRITE: usize = 2; +pub const F_DUPFD: usize = 0; pub const F_GETFD: usize = 1; pub const F_SETFD: usize = 2; pub const F_GETFL: usize = 3; @@ -36,6 +39,8 @@ pub const MODE_TYPE: u16 = 0xF000; pub const MODE_DIR: u16 = 0x4000; pub const MODE_FILE: u16 = 0x8000; pub const MODE_SYMLINK: u16 = 0xA000; +pub const MODE_FIFO: u16 = 0x1000; +pub const MODE_CHR: u16 = 0x2000; pub const MODE_PERM: u16 = 0x0FFF; pub const MODE_SETUID: u16 = 0o4000; @@ -96,4 +101,16 @@ pub const SIGIO: usize = 29; pub const SIGPWR: usize = 30; pub const SIGSYS: usize = 31; +pub const SIG_DFL: usize = 0; +pub const SIG_IGN: usize = 1; + +pub const SA_NOCLDSTOP: usize = 0x00000001; +pub const SA_NOCLDWAIT: usize = 0x00000002; +pub const SA_SIGINFO: usize = 0x00000004; +pub const SA_RESTORER: usize = 0x04000000; +pub const SA_ONSTACK: usize = 0x08000000; +pub const SA_RESTART: usize = 0x10000000; +pub const SA_NODEFER: usize = 0x40000000; +pub const SA_RESETHAND: usize = 0x80000000; + pub const WNOHANG: usize = 1; diff --git a/src/libstd/sys/redox/syscall/number.rs b/src/libstd/sys/redox/syscall/number.rs index 98f8b73e4e1bb..07db91647ff68 100644 --- a/src/libstd/sys/redox/syscall/number.rs +++ b/src/libstd/sys/redox/syscall/number.rs @@ -41,6 +41,7 @@ pub const SYS_FSTAT: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 28; pub const SYS_FSTATVFS: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 100; pub const SYS_FSYNC: usize = SYS_CLASS_FILE | 118; pub const SYS_FTRUNCATE: usize =SYS_CLASS_FILE | 93; +pub const SYS_FUTIMENS: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 320; pub const SYS_BRK: usize = 45; pub const SYS_CHDIR: usize = 12; @@ -56,6 +57,8 @@ pub const SYS_GETEUID: usize = 201; pub const SYS_GETGID: usize = 200; pub const SYS_GETNS: usize = 950; pub const SYS_GETPID: usize = 20; +pub const SYS_GETPGID: usize = 132; +pub const SYS_GETPPID: usize = 64; pub const SYS_GETUID: usize = 199; pub const SYS_IOPL: usize = 110; pub const SYS_KILL: usize = 37; @@ -67,8 +70,11 @@ pub const SYS_PHYSMAP: usize = 947; pub const SYS_PHYSUNMAP: usize =948; pub const SYS_VIRTTOPHYS: usize=949; pub const SYS_PIPE2: usize = 331; +pub const SYS_SETPGID: usize = 57; pub const SYS_SETREGID: usize = 204; pub const SYS_SETRENS: usize = 952; pub const SYS_SETREUID: usize = 203; +pub const SYS_SIGACTION: usize =67; +pub const SYS_SIGRETURN: usize =119; pub const SYS_WAITPID: usize = 7; pub const SYS_YIELD: usize = 158; From 914853bbfa912c4a49379997c0dc938801aa9c4e Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 11 Sep 2017 19:46:18 -0600 Subject: [PATCH 2/7] Fix tidy checks --- src/libstd/sys/redox/syscall/call.rs | 6 ++- src/libstd/sys/redox/syscall/data.rs | 56 ++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/libstd/sys/redox/syscall/call.rs b/src/libstd/sys/redox/syscall/call.rs index b0ff69dd6345c..7770a2f3f1b5a 100644 --- a/src/libstd/sys/redox/syscall/call.rs +++ b/src/libstd/sys/redox/syscall/call.rs @@ -140,7 +140,8 @@ pub fn ftruncate(fd: usize, len: usize) -> Result { // Change modify and/or access times pub fn futimens(fd: usize, times: &[TimeSpec]) -> Result { - unsafe { syscall3(SYS_FUTIMENS, fd, times.as_ptr() as usize, times.len() * mem::size_of::()) } + unsafe { syscall3(SYS_FUTIMENS, fd, times.as_ptr() as usize, + times.len() * mem::size_of::()) } } /// Fast userspace mutex @@ -291,7 +292,8 @@ pub fn setreuid(ruid: usize, euid: usize) -> Result { } /// Set up a signal handler -pub fn sigaction(sig: usize, act: Option<&SigAction>, oldact: Option<&mut SigAction>) -> Result { +pub fn sigaction(sig: usize, act: Option<&SigAction>, oldact: Option<&mut SigAction>) +-> Result { unsafe { syscall4(SYS_SIGACTION, sig, act.map(|x| x as *const _).unwrap_or_else(ptr::null) as usize, oldact.map(|x| x as *mut _).unwrap_or_else(ptr::null_mut) as usize, diff --git a/src/libstd/sys/redox/syscall/data.rs b/src/libstd/sys/redox/syscall/data.rs index 3566d85d9b451..2e784ebc8a5c5 100644 --- a/src/libstd/sys/redox/syscall/data.rs +++ b/src/libstd/sys/redox/syscall/data.rs @@ -22,7 +22,10 @@ impl Deref for Event { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::()) as &[u8] + slice::from_raw_parts( + self as *const Event as *const u8, + mem::size_of::() + ) as &[u8] } } } @@ -30,7 +33,10 @@ impl Deref for Event { impl DerefMut for Event { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::()) as &mut [u8] + slice::from_raw_parts_mut( + self as *mut Event as *mut u8, + mem::size_of::() + ) as &mut [u8] } } } @@ -52,7 +58,10 @@ impl Deref for Packet { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const Packet as *const u8, mem::size_of::()) as &[u8] + slice::from_raw_parts( + self as *const Packet as *const u8, + mem::size_of::() + ) as &[u8] } } } @@ -60,7 +69,10 @@ impl Deref for Packet { impl DerefMut for Packet { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut Packet as *mut u8, mem::size_of::()) as &mut [u8] + slice::from_raw_parts_mut( + self as *mut Packet as *mut u8, + mem::size_of::() + ) as &mut [u8] } } } @@ -107,8 +119,10 @@ impl Deref for Stat { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const Stat as *const u8, - mem::size_of::()) as &[u8] + slice::from_raw_parts( + self as *const Stat as *const u8, + mem::size_of::() + ) as &[u8] } } } @@ -116,8 +130,10 @@ impl Deref for Stat { impl DerefMut for Stat { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut Stat as *mut u8, - mem::size_of::()) as &mut [u8] + slice::from_raw_parts_mut( + self as *mut Stat as *mut u8, + mem::size_of::() + ) as &mut [u8] } } } @@ -135,8 +151,10 @@ impl Deref for StatVfs { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const StatVfs as *const u8, - mem::size_of::()) as &[u8] + slice::from_raw_parts( + self as *const StatVfs as *const u8, + mem::size_of::() + ) as &[u8] } } } @@ -144,8 +162,10 @@ impl Deref for StatVfs { impl DerefMut for StatVfs { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut StatVfs as *mut u8, - mem::size_of::()) as &mut [u8] + slice::from_raw_parts_mut( + self as *mut StatVfs as *mut u8, + mem::size_of::() + ) as &mut [u8] } } } @@ -161,8 +181,10 @@ impl Deref for TimeSpec { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const TimeSpec as *const u8, - mem::size_of::()) as &[u8] + slice::from_raw_parts( + self as *const TimeSpec as *const u8, + mem::size_of::() + ) as &[u8] } } } @@ -170,8 +192,10 @@ impl Deref for TimeSpec { impl DerefMut for TimeSpec { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut TimeSpec as *mut u8, - mem::size_of::()) as &mut [u8] + slice::from_raw_parts_mut( + self as *mut TimeSpec as *mut u8, + mem::size_of::() + ) as &mut [u8] } } } From 995f0bdb9b999056667e6dff7ebc9712ac79cc5b Mon Sep 17 00:00:00 2001 From: MaulingMonkey Date: Sun, 10 Sep 2017 19:37:59 -0700 Subject: [PATCH 3/7] Skip passing /natvis to lld-link until supported. LLVM 5.0.0's lld-link frontend errors out if passed /natvis. LLVM 6 (maybe earlier?) should at least ignore the flag. Hopefully LLVM will eventually support the flag, at which point this workaround can perhaps be simply removed, if 6? is old enough. --- src/librustc_trans/back/linker.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 487d9e059458c..de2b5905d6f78 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -498,6 +498,18 @@ impl<'a> Linker for MsvcLinker<'a> { let sysroot = self.sess.sysroot(); let natvis_dir_path = sysroot.join("lib\\rustlib\\etc"); if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) { + // LLVM 5.0.0's lld-link frontend doesn't yet recognize, and chokes + // on, the /NATVIS:... flags. LLVM 6 (or earlier) should at worst ignore + // them, eventually mooting this workaround, per this landed patch: + // https://github.com/llvm-mirror/lld/commit/27b9c4285364d8d76bb43839daa100 + if let Some(ref linker_path) = self.sess.opts.cg.linker { + if let Some(linker_name) = Path::new(&linker_path).file_stem() { + if linker_name.to_str().unwrap().to_lowercase() == "lld-link" { + self.sess.warn("not embedding natvis: lld-link may not support the flag"); + return; + } + } + } for entry in natvis_dir { match entry { Ok(entry) => { From 00c7ea5f53765ed9c142d6ee300a5c6986f63613 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 16 Sep 2017 20:54:11 -0600 Subject: [PATCH 4/7] Fix network families --- src/libstd/sys/redox/net/netc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/redox/net/netc.rs b/src/libstd/sys/redox/net/netc.rs index 03e1c9fffa4d0..d443a4d68a170 100644 --- a/src/libstd/sys/redox/net/netc.rs +++ b/src/libstd/sys/redox/net/netc.rs @@ -14,8 +14,8 @@ pub type in_port_t = u16; pub type socklen_t = u32; pub type sa_family_t = u16; -pub const AF_INET: sa_family_t = 1; -pub const AF_INET6: sa_family_t = 2; +pub const AF_INET: sa_family_t = 2; +pub const AF_INET6: sa_family_t = 23; #[derive(Copy, Clone)] #[repr(C)] From 86a79c97104983503e2088b182bab77d1f243bde Mon Sep 17 00:00:00 2001 From: Behnam Esfahbod Date: Mon, 18 Sep 2017 19:27:08 -0700 Subject: [PATCH 5/7] [libstd_unicode] Expose UnicodeVersion type In , we added an uninstantiable type for the internal `UNICODE_VERSION` value, `UnicodeVersion`, but it was not made public to the outside of the crate, resulting in the value becoming less useful. Here we make the type accessible from the outside. Also add a run-pass test to make sure the type and value can be accessed as intended. --- src/libstd_unicode/char.rs | 2 +- src/test/run-pass/char_unicode.rs | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/char_unicode.rs diff --git a/src/libstd_unicode/char.rs b/src/libstd_unicode/char.rs index 5cf05bff8c5b1..5c0c7a4fbca35 100644 --- a/src/libstd_unicode/char.rs +++ b/src/libstd_unicode/char.rs @@ -47,7 +47,7 @@ pub use core::char::CharTryFromError; #[unstable(feature = "decode_utf8", issue = "33906")] pub use core::char::{DecodeUtf8, decode_utf8}; #[unstable(feature = "unicode", issue = "27783")] -pub use tables::UNICODE_VERSION; +pub use tables::{UnicodeVersion, UNICODE_VERSION}; /// Returns an iterator that yields the lowercase equivalent of a `char`. /// diff --git a/src/test/run-pass/char_unicode.rs b/src/test/run-pass/char_unicode.rs new file mode 100644 index 0000000000000..b4884acdd078f --- /dev/null +++ b/src/test/run-pass/char_unicode.rs @@ -0,0 +1,22 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +#![feature(unicode)] + + +/// Tests access to the internal Unicode Version type and value. +pub fn main() { + check(std::char::UNICODE_VERSION); +} + +pub fn check(unicode_version: std::char::UnicodeVersion) { + assert!(unicode_version.major >= 10); +} From 0c5311edebbdfddac1a322f1539c7c42b70be13a Mon Sep 17 00:00:00 2001 From: Bob Sun Date: Tue, 19 Sep 2017 00:12:37 -0700 Subject: [PATCH 6/7] Fix a typo in rustc help menu Change from native-static-deps to native-static-libs. --- src/librustc/session/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index e1107a9b97fce..1d490c8f27d85 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1332,7 +1332,7 @@ pub fn rustc_short_optgroups() -> Vec { print on stdout", "[crate-name|file-names|sysroot|cfg|target-list|\ target-cpus|target-features|relocation-models|\ - code-models|target-spec-json|native-static-deps]"), + code-models|target-spec-json|native-static-libs]"), opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"), opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"), opt::opt_s("o", "", "Write output to ", "FILENAME"), From ff457f012aef26f82c42c73783d7d3810d04d624 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 19 Sep 2017 18:10:38 +0200 Subject: [PATCH 7/7] Add some missing links in io docs --- src/libstd/io/util.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index 88f4214296d9c..e20f249d3ea58 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -69,16 +69,18 @@ pub fn copy(reader: &mut R, writer: &mut W) -> io::Result< /// A reader which is always at EOF. /// -/// This struct is generally created by calling [`empty`][empty]. Please see -/// the documentation of `empty()` for more details. +/// This struct is generally created by calling [`empty`]. Please see +/// the documentation of [`empty()`][`empty`] for more details. /// -/// [empty]: fn.empty.html +/// [`empty`]: fn.empty.html #[stable(feature = "rust1", since = "1.0.0")] pub struct Empty { _priv: () } /// Constructs a new handle to an empty reader. /// -/// All reads from the returned reader will return `Ok(0)`. +/// All reads from the returned reader will return [`Ok`]`(0)`. +/// +/// [`Ok`]: ../result/enum.Result.html#variant.Ok /// /// # Examples ///