about summary refs log tree commit diff
path: root/src/libstd/sys_common
diff options
context:
space:
mode:
authorSayan Nandan <17377258+sntdevco@users.noreply.github.com>2019-08-09 13:01:05 +0530
committerGitHub <noreply@github.com>2019-08-09 13:01:05 +0530
commitfb3a01354ffecc41d7a189e4dd225d706387a522 (patch)
tree41492dfe93f1dccba847dadb56ac6aa079edaaa9 /src/libstd/sys_common
parent33445aea509cadcd715009c79795d289268daa7c (diff)
parent5aa3d9a7b5d3a46a7f158e8881146331a6bc9243 (diff)
downloadrust-fb3a01354ffecc41d7a189e4dd225d706387a522.tar.gz
rust-fb3a01354ffecc41d7a189e4dd225d706387a522.zip
Merge pull request #1 from rust-lang/master
Merge recent changes into master
Diffstat (limited to 'src/libstd/sys_common')
-rw-r--r--src/libstd/sys_common/alloc.rs3
-rw-r--r--src/libstd/sys_common/at_exit_imp.rs5
-rw-r--r--src/libstd/sys_common/backtrace.rs305
-rw-r--r--src/libstd/sys_common/bytestring.rs6
-rw-r--r--src/libstd/sys_common/fs.rs41
-rw-r--r--src/libstd/sys_common/gnu/libbacktrace.rs175
-rw-r--r--src/libstd/sys_common/gnu/mod.rs5
-rw-r--r--src/libstd/sys_common/io.rs2
-rw-r--r--src/libstd/sys_common/mod.rs28
-rw-r--r--src/libstd/sys_common/mutex.rs2
-rw-r--r--src/libstd/sys_common/net.rs22
-rw-r--r--src/libstd/sys_common/os_str_bytes.rs247
-rw-r--r--src/libstd/sys_common/poison.rs8
-rw-r--r--src/libstd/sys_common/remutex.rs10
-rw-r--r--src/libstd/sys_common/thread.rs3
-rw-r--r--src/libstd/sys_common/util.rs4
-rw-r--r--src/libstd/sys_common/wtf8.rs28
17 files changed, 510 insertions, 384 deletions
diff --git a/src/libstd/sys_common/alloc.rs b/src/libstd/sys_common/alloc.rs
index 978a70bee09..1cfc7ed17f2 100644
--- a/src/libstd/sys_common/alloc.rs
+++ b/src/libstd/sys_common/alloc.rs
@@ -12,7 +12,8 @@ use crate::ptr;
               target_arch = "powerpc",
               target_arch = "powerpc64",
               target_arch = "asmjs",
-              target_arch = "wasm32")))]
+              target_arch = "wasm32",
+              target_arch = "hexagon")))]
 pub const MIN_ALIGN: usize = 8;
 #[cfg(all(any(target_arch = "x86_64",
               target_arch = "aarch64",
diff --git a/src/libstd/sys_common/at_exit_imp.rs b/src/libstd/sys_common/at_exit_imp.rs
index 1181b861611..cdb72ee872e 100644
--- a/src/libstd/sys_common/at_exit_imp.rs
+++ b/src/libstd/sys_common/at_exit_imp.rs
@@ -2,12 +2,11 @@
 //!
 //! Documentation can be found on the `rt::at_exit` function.
 
-use crate::boxed::FnBox;
 use crate::ptr;
 use crate::mem;
 use crate::sys_common::mutex::Mutex;
 
-type Queue = Vec<Box<dyn FnBox()>>;
+type Queue = Vec<Box<dyn FnOnce()>>;
 
 // NB these are specifically not types from `std::sync` as they currently rely
 // on poisoning and this module needs to operate at a lower level than requiring
@@ -61,7 +60,7 @@ pub fn cleanup() {
     }
 }
 
-pub fn push(f: Box<dyn FnBox()>) -> bool {
+pub fn push(f: Box<dyn FnOnce()>) -> bool {
     unsafe {
         let _guard = LOCK.lock();
         if init() {
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index 1a80908779e..bf37ff7ddbd 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -2,40 +2,17 @@
 /// supported platforms.
 
 use crate::env;
-use crate::io::prelude::*;
 use crate::io;
+use crate::io::prelude::*;
+use crate::mem;
 use crate::path::{self, Path};
 use crate::ptr;
-use crate::str;
 use crate::sync::atomic::{self, Ordering};
 use crate::sys::mutex::Mutex;
 
-use rustc_demangle::demangle;
-
-pub use crate::sys::backtrace::{
-    unwind_backtrace,
-    resolve_symname,
-    foreach_symbol_fileline,
-    BacktraceContext
-};
-
-#[cfg(target_pointer_width = "64")]
-pub const HEX_WIDTH: usize = 18;
-
-#[cfg(target_pointer_width = "32")]
-pub const HEX_WIDTH: usize = 10;
-
-/// Represents an item in the backtrace list. See `unwind_backtrace` for how
-/// it is created.
-#[derive(Debug, Copy, Clone)]
-pub struct Frame {
-    /// Exact address of the call that failed.
-    pub exact_position: *const u8,
-    /// Address of the enclosing function.
-    pub symbol_addr: *const u8,
-    /// Which inlined function is this frame referring to
-    pub inline_context: u32,
-}
+use backtrace::{BytesOrWideString, Frame, Symbol};
+
+pub const HEX_WIDTH: usize = 2 + 2 * mem::size_of::<usize>();
 
 /// Max number of frames to print.
 const MAX_NB_FRAMES: usize = 100;
@@ -49,7 +26,7 @@ pub fn print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
     // test mode immediately return here to optimize away any references to the
     // libbacktrace symbols
     if cfg!(test) {
-        return Ok(())
+        return Ok(());
     }
 
     // Use a lock to prevent mixed output in multithreading context.
@@ -63,75 +40,39 @@ pub fn print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
 }
 
 fn _print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
-    let mut frames = [Frame {
-        exact_position: ptr::null(),
-        symbol_addr: ptr::null(),
-        inline_context: 0,
-    }; MAX_NB_FRAMES];
-    let (nb_frames, context) = unwind_backtrace(&mut frames)?;
-    let (skipped_before, skipped_after) =
-        filter_frames(&frames[..nb_frames], format, &context);
-    if skipped_before + skipped_after > 0 {
-        writeln!(w, "note: Some details are omitted, \
-                     run with `RUST_BACKTRACE=full` for a verbose backtrace.")?;
-    }
     writeln!(w, "stack backtrace:")?;
 
-    let filtered_frames = &frames[..nb_frames - skipped_after];
-    for (index, frame) in filtered_frames.iter().skip(skipped_before).enumerate() {
-        resolve_symname(*frame, |symname| {
-            output(w, index, *frame, symname, format)
-        }, &context)?;
-        let has_more_filenames = foreach_symbol_fileline(*frame, |file, line| {
-            output_fileline(w, file, line, format)
-        }, &context)?;
-        if has_more_filenames {
-            w.write_all(b" <... and possibly more>")?;
-        }
-    }
-
-    Ok(())
-}
-
-/// Returns a number of frames to remove at the beginning and at the end of the
-/// backtrace, according to the backtrace format.
-fn filter_frames(frames: &[Frame],
-                 format: PrintFormat,
-                 context: &BacktraceContext) -> (usize, usize)
-{
-    if format == PrintFormat::Full {
-        return (0, 0);
-    }
-
-    let skipped_before = 0;
-
-    let skipped_after = frames.len() - frames.iter().position(|frame| {
-        let mut is_marker = false;
-        let _ = resolve_symname(*frame, |symname| {
-            if let Some(mangled_symbol_name) = symname {
-                // Use grep to find the concerned functions
-                if mangled_symbol_name.contains("__rust_begin_short_backtrace") {
-                    is_marker = true;
-                }
+    let mut printer = Printer::new(format, w);
+    unsafe {
+        backtrace::trace_unsynchronized(|frame| {
+            let mut hit = false;
+            backtrace::resolve_frame_unsynchronized(frame, |symbol| {
+                hit = true;
+                printer.output(frame, Some(symbol));
+            });
+            if !hit {
+                printer.output(frame, None);
             }
-            Ok(())
-        }, context);
-        is_marker
-    }).unwrap_or(frames.len());
-
-    if skipped_before + skipped_after >= frames.len() {
-        // Avoid showing completely empty backtraces
-        return (0, 0);
+            !printer.done
+        });
     }
-
-    (skipped_before, skipped_after)
+    if printer.skipped {
+        writeln!(
+            w,
+            "note: Some details are omitted, \
+             run with `RUST_BACKTRACE=full` for a verbose backtrace."
+        )?;
+    }
+    Ok(())
 }
 
-
 /// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
 #[inline(never)]
 pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
-    where F: FnOnce() -> T, F: Send, T: Send
+where
+    F: FnOnce() -> T,
+    F: Send,
+    T: Send,
 {
     f()
 }
@@ -156,7 +97,7 @@ pub fn log_enabled() -> Option<PrintFormat> {
         _ => return Some(PrintFormat::Full),
     }
 
-    let val = env::var_os("RUST_BACKTRACE").and_then(|x|
+    let val = env::var_os("RUST_BACKTRACE").and_then(|x| {
         if &x == "0" {
             None
         } else if &x == "full" {
@@ -164,81 +105,141 @@ pub fn log_enabled() -> Option<PrintFormat> {
         } else {
             Some(PrintFormat::Short)
         }
+    });
+    ENABLED.store(
+        match val {
+            Some(v) => v as isize,
+            None => 1,
+        },
+        Ordering::SeqCst,
     );
-    ENABLED.store(match val {
-        Some(v) => v as isize,
-        None => 1,
-    }, Ordering::SeqCst);
     val
 }
 
-/// Prints the symbol of the backtrace frame.
-///
-/// These output functions should now be used everywhere to ensure consistency.
-/// You may want to also use `output_fileline`.
-fn output(w: &mut dyn Write, idx: usize, frame: Frame,
-              s: Option<&str>, format: PrintFormat) -> io::Result<()> {
-    // Remove the `17: 0x0 - <unknown>` line.
-    if format == PrintFormat::Short && frame.exact_position == ptr::null() {
-        return Ok(());
+struct Printer<'a, 'b> {
+    format: PrintFormat,
+    done: bool,
+    skipped: bool,
+    idx: usize,
+    out: &'a mut (dyn Write + 'b),
+}
+
+impl<'a, 'b> Printer<'a, 'b> {
+    fn new(format: PrintFormat, out: &'a mut (dyn Write + 'b)) -> Printer<'a, 'b> {
+        Printer { format, done: false, skipped: false, idx: 0, out }
     }
-    match format {
-        PrintFormat::Full => write!(w,
-                                    "  {:2}: {:2$?} - ",
-                                    idx,
-                                    frame.exact_position,
-                                    HEX_WIDTH)?,
-        PrintFormat::Short => write!(w, "  {:2}: ", idx)?,
+
+    /// Prints the symbol of the backtrace frame.
+    ///
+    /// These output functions should now be used everywhere to ensure consistency.
+    /// You may want to also use `output_fileline`.
+    fn output(&mut self, frame: &Frame, symbol: Option<&Symbol>) {
+        if self.idx > MAX_NB_FRAMES {
+            self.done = true;
+            self.skipped = true;
+            return;
+        }
+        if self._output(frame, symbol).is_err() {
+            self.done = true;
+        }
+        self.idx += 1;
     }
-    match s {
-        Some(string) => {
-            let symbol = demangle(string);
-            match format {
-                PrintFormat::Full => write!(w, "{}", symbol)?,
-                // strip the trailing hash if short mode
-                PrintFormat::Short => write!(w, "{:#}", symbol)?,
+
+    fn _output(&mut self, frame: &Frame, symbol: Option<&Symbol>) -> io::Result<()> {
+        if self.format == PrintFormat::Short {
+            if let Some(sym) = symbol.and_then(|s| s.name()).and_then(|s| s.as_str()) {
+                if sym.contains("__rust_begin_short_backtrace") {
+                    self.skipped = true;
+                    self.done = true;
+                    return Ok(());
+                }
+            }
+
+            // Remove the `17: 0x0 - <unknown>` line.
+            if self.format == PrintFormat::Short && frame.ip() == ptr::null_mut() {
+                self.skipped = true;
+                return Ok(());
             }
         }
-        None => w.write_all(b"<unknown>")?,
-    }
-    w.write_all(b"\n")
-}
 
-/// Prints the filename and line number of the backtrace frame.
-///
-/// See also `output`.
-#[allow(dead_code)]
-fn output_fileline(w: &mut dyn Write,
-                   file: &[u8],
-                   line: u32,
-                   format: PrintFormat) -> io::Result<()> {
-    // prior line: "  ##: {:2$} - func"
-    w.write_all(b"")?;
-    match format {
-        PrintFormat::Full => write!(w,
-                                    "           {:1$}",
-                                    "",
-                                    HEX_WIDTH)?,
-        PrintFormat::Short => write!(w, "           ")?,
-    }
+        match self.format {
+            PrintFormat::Full => {
+                write!(self.out, "  {:2}: {:2$?} - ", self.idx, frame.ip(), HEX_WIDTH)?
+            }
+            PrintFormat::Short => write!(self.out, "  {:2}: ", self.idx)?,
+        }
 
-    let file = str::from_utf8(file).unwrap_or("<unknown>");
-    let file_path = Path::new(file);
-    let mut already_printed = false;
-    if format == PrintFormat::Short && file_path.is_absolute() {
-        if let Ok(cwd) = env::current_dir() {
-            if let Ok(stripped) = file_path.strip_prefix(&cwd) {
-                if let Some(s) = stripped.to_str() {
-                    write!(w, "  at .{}{}:{}", path::MAIN_SEPARATOR, s, line)?;
-                    already_printed = true;
+        match symbol.and_then(|s| s.name()) {
+            Some(symbol) => {
+                match self.format {
+                    PrintFormat::Full => write!(self.out, "{}", symbol)?,
+                    // Strip the trailing hash if short mode.
+                    PrintFormat::Short => write!(self.out, "{:#}", symbol)?,
                 }
             }
+            None => self.out.write_all(b"<unknown>")?,
         }
-    }
-    if !already_printed {
-        write!(w, "  at {}:{}", file, line)?;
+        self.out.write_all(b"\n")?;
+        if let Some(sym) = symbol {
+            self.output_fileline(sym)?;
+        }
+        Ok(())
     }
 
-    w.write_all(b"\n")
-}
+    /// Prints the filename and line number of the backtrace frame.
+    ///
+    /// See also `output`.
+    fn output_fileline(&mut self, symbol: &Symbol) -> io::Result<()> {
+        #[cfg(windows)]
+        let path_buf;
+        let file = match symbol.filename_raw() {
+            #[cfg(unix)]
+            Some(BytesOrWideString::Bytes(bytes)) => {
+                use crate::os::unix::prelude::*;
+                Path::new(crate::ffi::OsStr::from_bytes(bytes))
+            }
+            #[cfg(not(unix))]
+            Some(BytesOrWideString::Bytes(bytes)) => {
+                Path::new(crate::str::from_utf8(bytes).unwrap_or("<unknown>"))
+            }
+            #[cfg(windows)]
+            Some(BytesOrWideString::Wide(wide)) => {
+                use crate::os::windows::prelude::*;
+                path_buf = crate::ffi::OsString::from_wide(wide);
+                Path::new(&path_buf)
+            }
+            #[cfg(not(windows))]
+            Some(BytesOrWideString::Wide(_wide)) => {
+                Path::new("<unknown>")
+            }
+            None => return Ok(()),
+        };
+        let line = match symbol.lineno() {
+            Some(line) => line,
+            None => return Ok(()),
+        };
+        // prior line: "  ##: {:2$} - func"
+        self.out.write_all(b"")?;
+        match self.format {
+            PrintFormat::Full => write!(self.out, "           {:1$}", "", HEX_WIDTH)?,
+            PrintFormat::Short => write!(self.out, "           ")?,
+        }
 
+        let mut already_printed = false;
+        if self.format == PrintFormat::Short && file.is_absolute() {
+            if let Ok(cwd) = env::current_dir() {
+                if let Ok(stripped) = file.strip_prefix(&cwd) {
+                    if let Some(s) = stripped.to_str() {
+                        write!(self.out, "  at .{}{}:{}", path::MAIN_SEPARATOR, s, line)?;
+                        already_printed = true;
+                    }
+                }
+            }
+        }
+        if !already_printed {
+            write!(self.out, "  at {}:{}", file.display(), line)?;
+        }
+
+        self.out.write_all(b"\n")
+    }
+}
diff --git a/src/libstd/sys_common/bytestring.rs b/src/libstd/sys_common/bytestring.rs
index 273d586a5a0..429ecf6281b 100644
--- a/src/libstd/sys_common/bytestring.rs
+++ b/src/libstd/sys_common/bytestring.rs
@@ -3,9 +3,9 @@
 use crate::fmt::{Formatter, Result, Write};
 use core::str::lossy::{Utf8Lossy, Utf8LossyChunk};
 
-pub fn debug_fmt_bytestring(slice: &[u8], f: &mut Formatter) -> Result {
+pub fn debug_fmt_bytestring(slice: &[u8], f: &mut Formatter<'_>) -> Result {
     // Writes out a valid unicode string with the correct escape sequences
-    fn write_str_escaped(f: &mut Formatter, s: &str) -> Result {
+    fn write_str_escaped(f: &mut Formatter<'_>, s: &str) -> Result {
         for c in s.chars().flat_map(|c| c.escape_debug()) {
             f.write_char(c)?
         }
@@ -32,7 +32,7 @@ mod tests {
         struct Helper<'a>(&'a [u8]);
 
         impl Debug for Helper<'_> {
-            fn fmt(&self, f: &mut Formatter) -> Result {
+            fn fmt(&self, f: &mut Formatter<'_>) -> Result {
                 debug_fmt_bytestring(self.0, f)
             }
         }
diff --git a/src/libstd/sys_common/fs.rs b/src/libstd/sys_common/fs.rs
new file mode 100644
index 00000000000..7152fcd215c
--- /dev/null
+++ b/src/libstd/sys_common/fs.rs
@@ -0,0 +1,41 @@
+#![allow(dead_code)] // not used on all platforms
+
+use crate::path::Path;
+use crate::fs;
+use crate::io::{self, Error, ErrorKind};
+
+pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
+    if !from.is_file() {
+        return Err(Error::new(ErrorKind::InvalidInput,
+                              "the source path is not an existing regular file"))
+    }
+
+    let mut reader = fs::File::open(from)?;
+    let mut writer = fs::File::create(to)?;
+    let perm = reader.metadata()?.permissions();
+
+    let ret = io::copy(&mut reader, &mut writer)?;
+    fs::set_permissions(to, perm)?;
+    Ok(ret)
+}
+
+pub fn remove_dir_all(path: &Path) -> io::Result<()> {
+    let filetype = fs::symlink_metadata(path)?.file_type();
+    if filetype.is_symlink() {
+        fs::remove_file(path)
+    } else {
+        remove_dir_all_recursive(path)
+    }
+}
+
+fn remove_dir_all_recursive(path: &Path) -> io::Result<()> {
+    for child in fs::read_dir(path)? {
+        let child = child?;
+        if child.file_type()?.is_dir() {
+            remove_dir_all_recursive(&child.path())?;
+        } else {
+            fs::remove_file(&child.path())?;
+        }
+    }
+    fs::remove_dir(path)
+}
diff --git a/src/libstd/sys_common/gnu/libbacktrace.rs b/src/libstd/sys_common/gnu/libbacktrace.rs
deleted file mode 100644
index 6cd050242dd..00000000000
--- a/src/libstd/sys_common/gnu/libbacktrace.rs
+++ /dev/null
@@ -1,175 +0,0 @@
-use backtrace_sys::backtrace_state;
-
-use crate::ffi::CStr;
-use crate::io;
-use crate::mem;
-use crate::ptr;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-pub fn foreach_symbol_fileline<F>(frame: Frame,
-                                  mut f: F,
-                                  _: &BacktraceContext) -> io::Result<bool>
-where F: FnMut(&[u8], u32) -> io::Result<()>
-{
-    // pcinfo may return an arbitrary number of file:line pairs,
-    // in the order of stack trace (i.e., inlined calls first).
-    // in order to avoid allocation, we stack-allocate a fixed size of entries.
-    const FILELINE_SIZE: usize = 32;
-    let mut fileline_buf = [(ptr::null(), !0); FILELINE_SIZE];
-    let ret;
-    let fileline_count = {
-        let state = unsafe { init_state() };
-        if state.is_null() {
-            return Err(io::Error::new(
-                io::ErrorKind::Other,
-                "failed to allocate libbacktrace state")
-            )
-        }
-        let mut fileline_win: &mut [FileLine] = &mut fileline_buf;
-        let fileline_addr = &mut fileline_win as *mut &mut [FileLine];
-        ret = unsafe {
-            backtrace_sys::backtrace_pcinfo(
-                state,
-                frame.exact_position as libc::uintptr_t,
-                pcinfo_cb,
-                error_cb,
-                fileline_addr as *mut libc::c_void,
-            )
-        };
-        FILELINE_SIZE - fileline_win.len()
-    };
-    if ret == 0 {
-        for &(file, line) in &fileline_buf[..fileline_count] {
-            if file.is_null() { continue; } // just to be sure
-            let file = unsafe { CStr::from_ptr(file).to_bytes() };
-            f(file, line)?;
-        }
-        Ok(fileline_count == FILELINE_SIZE)
-    } else {
-        Ok(false)
-    }
-}
-
-/// Converts a pointer to symbol to its string value.
-pub fn resolve_symname<F>(frame: Frame,
-                          callback: F,
-                          _: &BacktraceContext) -> io::Result<()>
-    where F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    let symname = {
-        let state = unsafe { init_state() };
-        if state.is_null() {
-            return Err(io::Error::new(
-                io::ErrorKind::Other,
-                "failed to allocate libbacktrace state")
-            )
-        }
-        let mut data: *const libc::c_char = ptr::null();
-        let data_addr = &mut data as *mut *const libc::c_char;
-        let ret = unsafe {
-            backtrace_sys::backtrace_syminfo(
-                state,
-                frame.symbol_addr as libc::uintptr_t,
-                syminfo_cb,
-                error_cb,
-                data_addr as *mut libc::c_void,
-            )
-        };
-        if ret == 0 || data.is_null() {
-            None
-        } else {
-            unsafe {
-                CStr::from_ptr(data).to_str().ok()
-            }
-        }
-    };
-    callback(symname)
-}
-
-////////////////////////////////////////////////////////////////////////
-// helper callbacks
-////////////////////////////////////////////////////////////////////////
-
-type FileLine = (*const libc::c_char, u32);
-
-extern fn error_cb(_data: *mut libc::c_void, _msg: *const libc::c_char,
-                   _errnum: libc::c_int) {
-    // do nothing for now
-}
-extern fn syminfo_cb(data: *mut libc::c_void,
-                     _pc: libc::uintptr_t,
-                     symname: *const libc::c_char,
-                     _symval: libc::uintptr_t,
-                     _symsize: libc::uintptr_t) {
-    let slot = data as *mut *const libc::c_char;
-    unsafe { *slot = symname; }
-}
-extern fn pcinfo_cb(data: *mut libc::c_void,
-                    _pc: libc::uintptr_t,
-                    filename: *const libc::c_char,
-                    lineno: libc::c_int,
-                    _function: *const libc::c_char) -> libc::c_int {
-    if !filename.is_null() {
-        let slot = data as *mut &mut [FileLine];
-        let buffer = unsafe {ptr::read(slot)};
-
-        // if the buffer is not full, add file:line to the buffer
-        // and adjust the buffer for next possible calls to pcinfo_cb.
-        if !buffer.is_empty() {
-            buffer[0] = (filename, lineno as u32);
-            unsafe { ptr::write(slot, &mut buffer[1..]); }
-        }
-    }
-
-    0
-}
-
-// The libbacktrace API supports creating a state, but it does not
-// support destroying a state. I personally take this to mean that a
-// state is meant to be created and then live forever.
-//
-// I would love to register an at_exit() handler which cleans up this
-// state, but libbacktrace provides no way to do so.
-//
-// With these constraints, this function has a statically cached state
-// that is calculated the first time this is requested. Remember that
-// backtracing all happens serially (one global lock).
-//
-// Things don't work so well on not-Linux since libbacktrace can't track
-// down that executable this is. We at one point used env::current_exe but
-// it turns out that there are some serious security issues with that
-// approach.
-//
-// Specifically, on certain platforms like BSDs, a malicious actor can cause
-// an arbitrary file to be placed at the path returned by current_exe.
-// libbacktrace does not behave defensively in the presence of ill-formed
-// DWARF information, and has been demonstrated to segfault in at least one
-// case. There is no evidence at the moment to suggest that a more carefully
-// constructed file can't cause arbitrary code execution. As a result of all
-// of this, we don't hint libbacktrace with the path to the current process.
-unsafe fn init_state() -> *mut backtrace_state {
-    static mut STATE: *mut backtrace_state = ptr::null_mut();
-    if !STATE.is_null() { return STATE  }
-
-    let filename = match crate::sys::backtrace::gnu::get_executable_filename() {
-        Ok((filename, file)) => {
-            // filename is purposely leaked here since libbacktrace requires
-            // it to stay allocated permanently, file is also leaked so that
-            // the file stays locked
-            let filename_ptr = filename.as_ptr();
-            mem::forget(filename);
-            mem::forget(file);
-            filename_ptr
-        },
-        Err(_) => ptr::null(),
-    };
-
-    STATE = backtrace_sys::backtrace_create_state(
-        filename,
-        0,
-        error_cb,
-        ptr::null_mut(),
-    );
-    STATE
-}
diff --git a/src/libstd/sys_common/gnu/mod.rs b/src/libstd/sys_common/gnu/mod.rs
deleted file mode 100644
index d6959697f2a..00000000000
--- a/src/libstd/sys_common/gnu/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-#![allow(missing_docs)]
-#![allow(non_camel_case_types)]
-#![allow(non_snake_case)]
-
-pub mod libbacktrace;
diff --git a/src/libstd/sys_common/io.rs b/src/libstd/sys_common/io.rs
index 44b0963302d..8789abe55c3 100644
--- a/src/libstd/sys_common/io.rs
+++ b/src/libstd/sys_common/io.rs
@@ -16,7 +16,7 @@ pub mod test {
             p.join(path)
         }
 
-        pub fn path<'a>(&'a self) -> &'a Path {
+        pub fn path(&self) -> &Path {
             let TempDir(ref p) = *self;
             p
         }
diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs
index 1fc32365408..9190a3b0d5f 100644
--- a/src/libstd/sys_common/mod.rs
+++ b/src/libstd/sys_common/mod.rs
@@ -28,6 +28,17 @@ macro_rules! rtassert {
     })
 }
 
+#[allow(unused_macros)] // not used on all platforms
+macro_rules! rtunwrap {
+    ($ok:ident, $e:expr) => (match $e {
+        $ok(v) => v,
+        ref err => {
+            let err = err.as_ref().map(|_|()); // map Ok/Some which might not be Debug
+            rtabort!(concat!("unwrap failed: ", stringify!($e), " = {:?}"), err)
+        },
+    })
+}
+
 pub mod alloc;
 pub mod at_exit_imp;
 #[cfg(feature = "backtrace")]
@@ -35,6 +46,13 @@ pub mod backtrace;
 pub mod condvar;
 pub mod io;
 pub mod mutex;
+#[cfg(any(rustdoc, // see `mod os`, docs are generated for multiple platforms
+          unix,
+          target_os = "redox",
+          target_os = "cloudabi",
+          target_arch = "wasm32",
+          all(target_vendor = "fortanix", target_env = "sgx")))]
+pub mod os_str_bytes;
 pub mod poison;
 pub mod remutex;
 pub mod rwlock;
@@ -45,11 +63,11 @@ pub mod util;
 pub mod wtf8;
 pub mod bytestring;
 pub mod process;
+pub mod fs;
 
-cfg_if! {
+cfg_if::cfg_if! {
     if #[cfg(any(target_os = "cloudabi",
                  target_os = "l4re",
-                 target_os = "redox",
                  all(target_arch = "wasm32", not(target_os = "emscripten")),
                  all(target_vendor = "fortanix", target_env = "sgx")))] {
         pub use crate::sys::net;
@@ -58,12 +76,6 @@ cfg_if! {
     }
 }
 
-#[cfg(feature = "backtrace")]
-#[cfg(any(all(unix, not(target_os = "emscripten")),
-          all(windows, target_env = "gnu"),
-          target_os = "redox"))]
-pub mod gnu;
-
 // common error constructors
 
 /// A trait for viewing representations from std types
diff --git a/src/libstd/sys_common/mutex.rs b/src/libstd/sys_common/mutex.rs
index 4b58cac7941..28d85949ffa 100644
--- a/src/libstd/sys_common/mutex.rs
+++ b/src/libstd/sys_common/mutex.rs
@@ -38,7 +38,7 @@ impl Mutex {
     /// Calls raw_lock() and then returns an RAII guard to guarantee the mutex
     /// will be unlocked.
     #[inline]
-    pub unsafe fn lock(&self) -> MutexGuard {
+    pub unsafe fn lock(&self) -> MutexGuard<'_> {
         self.raw_lock();
         MutexGuard(&self.0)
     }
diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs
index b9505aaa69b..391f670346f 100644
--- a/src/libstd/sys_common/net.rs
+++ b/src/libstd/sys_common/net.rs
@@ -1,7 +1,7 @@
 use crate::cmp;
 use crate::ffi::CString;
 use crate::fmt;
-use crate::io::{self, Error, ErrorKind, IoVec, IoVecMut};
+use crate::io::{self, Error, ErrorKind, IoSlice, IoSliceMut};
 use crate::mem;
 use crate::net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr};
 use crate::ptr;
@@ -37,12 +37,12 @@ use crate::sys::net::netc::IPV6_DROP_MEMBERSHIP;
 #[cfg(any(target_os = "linux", target_os = "android",
           target_os = "dragonfly", target_os = "freebsd",
           target_os = "openbsd", target_os = "netbsd",
-          target_os = "haiku", target_os = "bitrig"))]
+          target_os = "haiku"))]
 use libc::MSG_NOSIGNAL;
 #[cfg(not(any(target_os = "linux", target_os = "android",
               target_os = "dragonfly", target_os = "freebsd",
               target_os = "openbsd", target_os = "netbsd",
-              target_os = "haiku", target_os = "bitrig")))]
+              target_os = "haiku")))]
 const MSG_NOSIGNAL: c_int = 0x0;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -256,7 +256,7 @@ impl TcpStream {
         self.inner.read(buf)
     }
 
-    pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         self.inner.read_vectored(bufs)
     }
 
@@ -271,7 +271,7 @@ impl TcpStream {
         Ok(ret as usize)
     }
 
-    pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
         self.inner.write_vectored(bufs)
     }
 
@@ -328,7 +328,7 @@ impl FromInner<Socket> for TcpStream {
 }
 
 impl fmt::Debug for TcpStream {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut res = f.debug_struct("TcpStream");
 
         if let Ok(addr) = self.socket_addr() {
@@ -435,7 +435,7 @@ impl FromInner<Socket> for TcpListener {
 }
 
 impl fmt::Debug for TcpListener {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut res = f.debug_struct("TcpListener");
 
         if let Ok(addr) = self.socket_addr() {
@@ -472,6 +472,12 @@ impl UdpSocket {
 
     pub fn into_socket(self) -> Socket { self.inner }
 
+    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+        sockname(|buf, len| unsafe {
+            c::getpeername(*self.inner.as_inner(), buf, len)
+        })
+    }
+
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
         sockname(|buf, len| unsafe {
             c::getsockname(*self.inner.as_inner(), buf, len)
@@ -638,7 +644,7 @@ impl FromInner<Socket> for UdpSocket {
 }
 
 impl fmt::Debug for UdpSocket {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut res = f.debug_struct("UdpSocket");
 
         if let Ok(addr) = self.socket_addr() {
diff --git a/src/libstd/sys_common/os_str_bytes.rs b/src/libstd/sys_common/os_str_bytes.rs
new file mode 100644
index 00000000000..a4961974d89
--- /dev/null
+++ b/src/libstd/sys_common/os_str_bytes.rs
@@ -0,0 +1,247 @@
+//! The underlying OsString/OsStr implementation on Unix and many other
+//! systems: just a `Vec<u8>`/`[u8]`.
+
+use crate::borrow::Cow;
+use crate::ffi::{OsStr, OsString};
+use crate::fmt;
+use crate::str;
+use crate::mem;
+use crate::rc::Rc;
+use crate::sync::Arc;
+use crate::sys_common::{FromInner, IntoInner, AsInner};
+use crate::sys_common::bytestring::debug_fmt_bytestring;
+
+use core::str::lossy::Utf8Lossy;
+
+#[derive(Clone, Hash)]
+pub(crate) struct Buf {
+    pub inner: Vec<u8>
+}
+
+pub(crate) struct Slice {
+    pub inner: [u8]
+}
+
+impl fmt::Debug for Slice {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        debug_fmt_bytestring(&self.inner, formatter)
+    }
+}
+
+impl fmt::Display for Slice {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
+    }
+}
+
+impl fmt::Debug for Buf {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Debug::fmt(self.as_slice(), formatter)
+    }
+}
+
+impl fmt::Display for Buf {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(self.as_slice(), formatter)
+    }
+}
+
+impl IntoInner<Vec<u8>> for Buf {
+    fn into_inner(self) -> Vec<u8> {
+        self.inner
+    }
+}
+
+impl AsInner<[u8]> for Buf {
+    fn as_inner(&self) -> &[u8] {
+        &self.inner
+    }
+}
+
+
+impl Buf {
+    pub fn from_string(s: String) -> Buf {
+        Buf { inner: s.into_bytes() }
+    }
+
+    #[inline]
+    pub fn with_capacity(capacity: usize) -> Buf {
+        Buf {
+            inner: Vec::with_capacity(capacity)
+        }
+    }
+
+    #[inline]
+    pub fn clear(&mut self) {
+        self.inner.clear()
+    }
+
+    #[inline]
+    pub fn capacity(&self) -> usize {
+        self.inner.capacity()
+    }
+
+    #[inline]
+    pub fn reserve(&mut self, additional: usize) {
+        self.inner.reserve(additional)
+    }
+
+    #[inline]
+    pub fn reserve_exact(&mut self, additional: usize) {
+        self.inner.reserve_exact(additional)
+    }
+
+    #[inline]
+    pub fn shrink_to_fit(&mut self) {
+        self.inner.shrink_to_fit()
+    }
+
+    #[inline]
+    pub fn shrink_to(&mut self, min_capacity: usize) {
+        self.inner.shrink_to(min_capacity)
+    }
+
+    pub fn as_slice(&self) -> &Slice {
+        unsafe { mem::transmute(&*self.inner) }
+    }
+
+    pub fn into_string(self) -> Result<String, Buf> {
+        String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() } )
+    }
+
+    pub fn push_slice(&mut self, s: &Slice) {
+        self.inner.extend_from_slice(&s.inner)
+    }
+
+    #[inline]
+    pub fn into_box(self) -> Box<Slice> {
+        unsafe { mem::transmute(self.inner.into_boxed_slice()) }
+    }
+
+    #[inline]
+    pub fn from_box(boxed: Box<Slice>) -> Buf {
+        let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
+        Buf { inner: inner.into_vec() }
+    }
+
+    #[inline]
+    pub fn into_arc(&self) -> Arc<Slice> {
+        self.as_slice().into_arc()
+    }
+
+    #[inline]
+    pub fn into_rc(&self) -> Rc<Slice> {
+        self.as_slice().into_rc()
+    }
+}
+
+impl Slice {
+    fn from_u8_slice(s: &[u8]) -> &Slice {
+        unsafe { mem::transmute(s) }
+    }
+
+    pub fn from_str(s: &str) -> &Slice {
+        Slice::from_u8_slice(s.as_bytes())
+    }
+
+    pub fn to_str(&self) -> Option<&str> {
+        str::from_utf8(&self.inner).ok()
+    }
+
+    pub fn to_string_lossy(&self) -> Cow<'_, str> {
+        String::from_utf8_lossy(&self.inner)
+    }
+
+    pub fn to_owned(&self) -> Buf {
+        Buf { inner: self.inner.to_vec() }
+    }
+
+    #[inline]
+    pub fn into_box(&self) -> Box<Slice> {
+        let boxed: Box<[u8]> = self.inner.into();
+        unsafe { mem::transmute(boxed) }
+    }
+
+    pub fn empty_box() -> Box<Slice> {
+        let boxed: Box<[u8]> = Default::default();
+        unsafe { mem::transmute(boxed) }
+    }
+
+    #[inline]
+    pub fn into_arc(&self) -> Arc<Slice> {
+        let arc: Arc<[u8]> = Arc::from(&self.inner);
+        unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
+    }
+
+    #[inline]
+    pub fn into_rc(&self) -> Rc<Slice> {
+        let rc: Rc<[u8]> = Rc::from(&self.inner);
+        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
+    }
+}
+
+/// Platform-specific extensions to [`OsString`].
+///
+/// [`OsString`]: ../../../../std/ffi/struct.OsString.html
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait OsStringExt {
+    /// Creates an [`OsString`] from a byte vector.
+    ///
+    /// See the module docmentation for an example.
+    ///
+    /// [`OsString`]: ../../../ffi/struct.OsString.html
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn from_vec(vec: Vec<u8>) -> Self;
+
+    /// Yields the underlying byte vector of this [`OsString`].
+    ///
+    /// See the module docmentation for an example.
+    ///
+    /// [`OsString`]: ../../../ffi/struct.OsString.html
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn into_vec(self) -> Vec<u8>;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl OsStringExt for OsString {
+    fn from_vec(vec: Vec<u8>) -> OsString {
+        FromInner::from_inner(Buf { inner: vec })
+    }
+    fn into_vec(self) -> Vec<u8> {
+        self.into_inner().inner
+    }
+}
+
+/// Platform-specific extensions to [`OsStr`].
+///
+/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait OsStrExt {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    /// Creates an [`OsStr`] from a byte slice.
+    ///
+    /// See the module docmentation for an example.
+    ///
+    /// [`OsStr`]: ../../../ffi/struct.OsStr.html
+    fn from_bytes(slice: &[u8]) -> &Self;
+
+    /// Gets the underlying byte view of the [`OsStr`] slice.
+    ///
+    /// See the module docmentation for an example.
+    ///
+    /// [`OsStr`]: ../../../ffi/struct.OsStr.html
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn as_bytes(&self) -> &[u8];
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl OsStrExt for OsStr {
+    #[inline]
+    fn from_bytes(slice: &[u8]) -> &OsStr {
+        unsafe { mem::transmute(slice) }
+    }
+    #[inline]
+    fn as_bytes(&self) -> &[u8] {
+        &self.as_inner().inner
+    }
+}
diff --git a/src/libstd/sys_common/poison.rs b/src/libstd/sys_common/poison.rs
index d2294235666..adac45f2d59 100644
--- a/src/libstd/sys_common/poison.rs
+++ b/src/libstd/sys_common/poison.rs
@@ -136,14 +136,14 @@ pub type TryLockResult<Guard> = Result<Guard, TryLockError<Guard>>;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> fmt::Debug for PoisonError<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         "PoisonError { inner: .. }".fmt(f)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> fmt::Display for PoisonError<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         "poisoned lock: another task failed inside".fmt(f)
     }
 }
@@ -214,7 +214,7 @@ impl<T> From<PoisonError<T>> for TryLockError<T> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> fmt::Debug for TryLockError<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
             TryLockError::Poisoned(..) => "Poisoned(..)".fmt(f),
             TryLockError::WouldBlock => "WouldBlock".fmt(f)
@@ -224,7 +224,7 @@ impl<T> fmt::Debug for TryLockError<T> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> fmt::Display for TryLockError<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
             TryLockError::Poisoned(..) => "poisoned lock: another task failed inside",
             TryLockError::WouldBlock => "try_lock failed because the operation would block"
diff --git a/src/libstd/sys_common/remutex.rs b/src/libstd/sys_common/remutex.rs
index 2aec361d7a4..f08b13c4aa2 100644
--- a/src/libstd/sys_common/remutex.rs
+++ b/src/libstd/sys_common/remutex.rs
@@ -72,7 +72,7 @@ impl<T> ReentrantMutex<T> {
     /// If another user of this mutex panicked while holding the mutex, then
     /// this call will return failure if the mutex would otherwise be
     /// acquired.
-    pub fn lock(&self) -> LockResult<ReentrantMutexGuard<T>> {
+    pub fn lock(&self) -> LockResult<ReentrantMutexGuard<'_, T>> {
         unsafe { self.inner.lock() }
         ReentrantMutexGuard::new(&self)
     }
@@ -89,7 +89,7 @@ impl<T> ReentrantMutex<T> {
     /// If another user of this mutex panicked while holding the mutex, then
     /// this call will return failure if the mutex would otherwise be
     /// acquired.
-    pub fn try_lock(&self) -> TryLockResult<ReentrantMutexGuard<T>> {
+    pub fn try_lock(&self) -> TryLockResult<ReentrantMutexGuard<'_, T>> {
         if unsafe { self.inner.try_lock() } {
             Ok(ReentrantMutexGuard::new(&self)?)
         } else {
@@ -108,7 +108,7 @@ impl<T> Drop for ReentrantMutex<T> {
 }
 
 impl<T: fmt::Debug + 'static> fmt::Debug for ReentrantMutex<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self.try_lock() {
             Ok(guard) => f.debug_struct("ReentrantMutex").field("data", &*guard).finish(),
             Err(TryLockError::Poisoned(err)) => {
@@ -117,7 +117,9 @@ impl<T: fmt::Debug + 'static> fmt::Debug for ReentrantMutex<T> {
             Err(TryLockError::WouldBlock) => {
                 struct LockedPlaceholder;
                 impl fmt::Debug for LockedPlaceholder {
-                    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("<locked>") }
+                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                        f.write_str("<locked>")
+                    }
                 }
 
                 f.debug_struct("ReentrantMutex").field("data", &LockedPlaceholder).finish()
diff --git a/src/libstd/sys_common/thread.rs b/src/libstd/sys_common/thread.rs
index b2142e75308..6ab0d5cbe9c 100644
--- a/src/libstd/sys_common/thread.rs
+++ b/src/libstd/sys_common/thread.rs
@@ -1,4 +1,3 @@
-use crate::boxed::FnBox;
 use crate::env;
 use crate::sync::atomic::{self, Ordering};
 use crate::sys::stack_overflow;
@@ -11,7 +10,7 @@ pub unsafe fn start_thread(main: *mut u8) {
     let _handler = stack_overflow::Handler::new();
 
     // Finally, let's run some code.
-    Box::from_raw(main as *mut Box<dyn FnBox()>)()
+    Box::from_raw(main as *mut Box<dyn FnOnce()>)()
 }
 
 pub fn min_stack() -> usize {
diff --git a/src/libstd/sys_common/util.rs b/src/libstd/sys_common/util.rs
index 206443a6736..7936dd35999 100644
--- a/src/libstd/sys_common/util.rs
+++ b/src/libstd/sys_common/util.rs
@@ -3,7 +3,7 @@ use crate::io::prelude::*;
 use crate::sys::stdio::panic_output;
 use crate::thread;
 
-pub fn dumb_print(args: fmt::Arguments) {
+pub fn dumb_print(args: fmt::Arguments<'_>) {
     if let Some(mut out) = panic_output() {
         let _ = out.write_fmt(args);
     }
@@ -14,7 +14,7 @@ pub fn dumb_print(args: fmt::Arguments) {
 // crate::intrinsics::abort() may be used instead.  The above implementations cover
 // all targets currently supported by libstd.
 
-pub fn abort(args: fmt::Arguments) -> ! {
+pub fn abort(args: fmt::Arguments<'_>) -> ! {
     dumb_print(format_args!("fatal runtime error: {}\n", args));
     unsafe { crate::sys::abort_internal(); }
 }
diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs
index b15239e8d87..81e606fc165 100644
--- a/src/libstd/sys_common/wtf8.rs
+++ b/src/libstd/sys_common/wtf8.rs
@@ -46,7 +46,7 @@ pub struct CodePoint {
 /// Example: `U+1F4A9`
 impl fmt::Debug for CodePoint {
     #[inline]
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(formatter, "U+{:04X}", self.value)
     }
 }
@@ -134,7 +134,7 @@ impl ops::DerefMut for Wtf8Buf {
 /// Example: `"a\u{D800}"` for a string with code points [U+0061, U+D800]
 impl fmt::Debug for Wtf8Buf {
     #[inline]
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Debug::fmt(&**self, formatter)
     }
 }
@@ -146,10 +146,10 @@ impl Wtf8Buf {
         Wtf8Buf { bytes: Vec::new() }
     }
 
-    /// Creates a new, empty WTF-8 string with pre-allocated capacity for `n` bytes.
+    /// Creates a new, empty WTF-8 string with pre-allocated capacity for `capacity` bytes.
     #[inline]
-    pub fn with_capacity(n: usize) -> Wtf8Buf {
-        Wtf8Buf { bytes: Vec::with_capacity(n) }
+    pub fn with_capacity(capacity: usize) -> Wtf8Buf {
+        Wtf8Buf { bytes: Vec::with_capacity(capacity) }
     }
 
     /// Creates a WTF-8 string from a UTF-8 `String`.
@@ -388,9 +388,7 @@ impl Extend<CodePoint> for Wtf8Buf {
         let (low, _high) = iterator.size_hint();
         // Lower bound of one byte per code point (ASCII only)
         self.bytes.reserve(low);
-        for code_point in iterator {
-            self.push(code_point);
-        }
+        iterator.for_each(move |code_point| self.push(code_point));
     }
 }
 
@@ -411,8 +409,8 @@ impl AsInner<[u8]> for Wtf8 {
 /// and surrogates as `\u` followed by four hexadecimal digits.
 /// Example: `"a\u{D800}"` for a slice with code points [U+0061, U+D800]
 impl fmt::Debug for Wtf8 {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-        fn write_str_escaped(f: &mut fmt::Formatter, s: &str) -> fmt::Result {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fn write_str_escaped(f: &mut fmt::Formatter<'_>, s: &str) -> fmt::Result {
             use crate::fmt::Write;
             for c in s.chars().flat_map(|c| c.escape_debug()) {
                 f.write_char(c)?
@@ -441,7 +439,7 @@ impl fmt::Debug for Wtf8 {
 }
 
 impl fmt::Display for Wtf8 {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
         let wtf8_bytes = &self.bytes;
         let mut pos = 0;
         loop {
@@ -522,7 +520,7 @@ impl Wtf8 {
 
     /// Returns an iterator for the string’s code points.
     #[inline]
-    pub fn code_points(&self) -> Wtf8CodePoints {
+    pub fn code_points(&self) -> Wtf8CodePoints<'_> {
         Wtf8CodePoints { bytes: self.bytes.iter() }
     }
 
@@ -547,7 +545,7 @@ impl Wtf8 {
     /// Surrogates are replaced with `"\u{FFFD}"` (the replacement character “�”).
     ///
     /// This only copies the data if necessary (if it contains any surrogate).
-    pub fn to_string_lossy(&self) -> Cow<str> {
+    pub fn to_string_lossy(&self) -> Cow<'_, str> {
         let surrogate_pos = match self.next_surrogate(0) {
             None => return Cow::Borrowed(unsafe { str::from_utf8_unchecked(&self.bytes) }),
             Some((pos, _)) => pos,
@@ -579,7 +577,7 @@ impl Wtf8 {
     /// calling `Wtf8Buf::from_ill_formed_utf16` on the resulting code units
     /// would always return the original WTF-8 string.
     #[inline]
-    pub fn encode_wide(&self) -> EncodeWide {
+    pub fn encode_wide(&self) -> EncodeWide<'_> {
         EncodeWide { code_points: self.code_points(), extra: 0 }
     }
 
@@ -1228,7 +1226,7 @@ mod tests {
         assert_eq!(Wtf8::from_str("aé 💩").to_string_lossy(), Cow::Borrowed("aé 💩"));
         let mut string = Wtf8Buf::from_str("aé 💩");
         string.push(CodePoint::from_u32(0xD800).unwrap());
-        let expected: Cow<str> = Cow::Owned(String::from("aé 💩�"));
+        let expected: Cow<'_, str> = Cow::Owned(String::from("aé 💩�"));
         assert_eq!(string.to_string_lossy(), expected);
     }