From cf8347ba6bc82c41de2ad9bf561af593a89cbe45 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 28 Feb 2019 10:25:54 +0100 Subject: fs::copy() set file mode early A convenience method like fs::copy() should try to prevent pitfalls a normal user doesn't think about. In case of an empty umask, setting the file mode early prevents temporarily world readable or even writeable files, because the default mode is 0o666. In case the target is a named pipe or special device node, setting the file mode can lead to unwanted side effects, like setting permissons on `/dev/stdout` or for root setting permissions on `/dev/null`. copy_file_range() returns EINVAL, if the destination is a FIFO/pipe or a device like "/dev/null", so fallback to io::copy, too. Use `fcopyfile` on MacOS instead of `copyfile`. Fixes: https://github.com/rust-lang/rust/issues/26933 Fixed: https://github.com/rust-lang/rust/issues/37885 --- src/libstd/sys/unix/fs.rs | 129 ++++++++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 55 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 7ff098bc9e1..c73f7983146 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -827,30 +827,54 @@ pub fn canonicalize(p: &Path) -> io::Result { Ok(PathBuf::from(OsString::from_vec(buf))) } +fn open_and_set_permissions( + from: &Path, + to: &Path, +) -> io::Result<(crate::fs::File, crate::fs::File, u64, crate::fs::Metadata)> { + use crate::fs::{File, OpenOptions}; + use crate::os::unix::fs::{OpenOptionsExt, PermissionsExt}; + + let reader = File::open(from)?; + let (perm, len) = { + let metadata = reader.metadata()?; + if !metadata.is_file() { + return Err(Error::new( + ErrorKind::InvalidInput, + "the source path is not an existing regular file", + )); + } + (metadata.permissions(), metadata.len()) + }; + let writer = OpenOptions::new() + // create the file with the correct mode right away + .mode(perm.mode()) + .write(true) + .create(true) + .truncate(true) + .open(to)?; + let writer_metadata = writer.metadata()?; + if writer_metadata.is_file() { + // Set the correct file permissions, in case the file already existed. + // Don't set the permissions on already existing non-files like + // pipes/FIFOs or device nodes. + writer.set_permissions(perm)?; + } + Ok((reader, writer, len, writer_metadata)) +} + #[cfg(not(any(target_os = "linux", target_os = "android", target_os = "macos", target_os = "ios")))] pub fn copy(from: &Path, to: &Path) -> io::Result { - use crate::fs::File; - if !from.is_file() { - return Err(Error::new(ErrorKind::InvalidInput, - "the source path is not an existing regular file")) - } + let (mut reader, mut writer, _, _) = open_and_set_permissions(from, to)?; - let mut reader = File::open(from)?; - let mut writer = File::create(to)?; - let perm = reader.metadata()?.permissions(); - - let ret = io::copy(&mut reader, &mut writer)?; - writer.set_permissions(perm)?; - Ok(ret) + io::copy(&mut reader, &mut writer) } #[cfg(any(target_os = "linux", target_os = "android"))] pub fn copy(from: &Path, to: &Path) -> io::Result { use crate::cmp; - use crate::fs::File; use crate::sync::atomic::{AtomicBool, Ordering}; // Kernel prior to 4.5 don't have copy_file_range @@ -876,17 +900,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { ) } - if !from.is_file() { - return Err(Error::new(ErrorKind::InvalidInput, - "the source path is not an existing regular file")) - } - - let mut reader = File::open(from)?; - let mut writer = File::create(to)?; - let (perm, len) = { - let metadata = reader.metadata()?; - (metadata.permissions(), metadata.size()) - }; + let (mut reader, mut writer, len, _) = open_and_set_permissions(from, to)?; let has_copy_file_range = HAS_COPY_FILE_RANGE.load(Ordering::Relaxed); let mut written = 0u64; @@ -896,13 +910,14 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { let copy_result = unsafe { // We actually don't have to adjust the offsets, // because copy_file_range adjusts the file offset automatically - cvt(copy_file_range(reader.as_raw_fd(), - ptr::null_mut(), - writer.as_raw_fd(), - ptr::null_mut(), - bytes_to_copy, - 0) - ) + cvt(copy_file_range( + reader.as_raw_fd(), + ptr::null_mut(), + writer.as_raw_fd(), + ptr::null_mut(), + bytes_to_copy, + 0, + )) }; if let Err(ref copy_err) = copy_result { match copy_err.raw_os_error() { @@ -920,24 +935,25 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { Ok(ret) => written += ret as u64, Err(err) => { match err.raw_os_error() { - Some(os_err) if os_err == libc::ENOSYS - || os_err == libc::EXDEV - || os_err == libc::EPERM => { - // Try fallback io::copy if either: - // - Kernel version is < 4.5 (ENOSYS) - // - Files are mounted on different fs (EXDEV) - // - copy_file_range is disallowed, for example by seccomp (EPERM) - assert_eq!(written, 0); - let ret = io::copy(&mut reader, &mut writer)?; - writer.set_permissions(perm)?; - return Ok(ret) - }, + Some(os_err) + if os_err == libc::ENOSYS + || os_err == libc::EXDEV + || os_err == libc::EINVAL + || os_err == libc::EPERM => + { + // Try fallback io::copy if either: + // - Kernel version is < 4.5 (ENOSYS) + // - Files are mounted on different fs (EXDEV) + // - copy_file_range is disallowed, for example by seccomp (EPERM) + // - copy_file_range cannot be used with pipes or device nodes (EINVAL) + assert_eq!(written, 0); + return io::copy(&mut reader, &mut writer); + } _ => return Err(err), } } } } - writer.set_permissions(perm)?; Ok(written) } @@ -960,9 +976,9 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { type copyfile_flags_t = u32; extern "C" { - fn copyfile( - from: *const libc::c_char, - to: *const libc::c_char, + fn fcopyfile( + from: libc::c_int, + to: libc::c_int, state: copyfile_state_t, flags: copyfile_flags_t, ) -> libc::c_int; @@ -988,10 +1004,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { } } - if !from.is_file() { - return Err(Error::new(ErrorKind::InvalidInput, - "the source path is not an existing regular file")) - } + let (reader, writer, _, writer_metadata) = open_and_set_permissions(from, to)?; // We ensure that `FreeOnDrop` never contains a null pointer so it is // always safe to call `copyfile_state_free` @@ -1003,12 +1016,18 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { FreeOnDrop(state) }; + let flags = if writer_metadata.is_file() { + COPYFILE_ALL + } else { + COPYFILE_DATA + }; + cvt(unsafe { - copyfile( - cstr(from)?.as_ptr(), - cstr(to)?.as_ptr(), + fcopyfile( + reader.as_raw_fd(), + writer.as_raw_fd(), state.0, - COPYFILE_ALL, + flags, ) })?; -- cgit 1.4.1-3-g733a5 From d339b89644b6461636a8604849121bbc7824b859 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Tue, 26 Mar 2019 18:22:25 -0400 Subject: Use consistent phrasing for all macro summaries --- src/libcore/macros.rs | 45 +++++++++++++++++++++++---------------------- src/libstd/macros.rs | 45 +++++++++++++++++++++++---------------------- 2 files changed, 46 insertions(+), 44 deletions(-) (limited to 'src/libstd') diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index d77936c7ddd..cd4e9243943 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -1,4 +1,6 @@ -/// Entry point of thread panic. For details, see `std::macros`. +/// Panics the current thread. +/// +/// For details, see `std::macros`. #[macro_export] #[allow_internal_unstable(core_panic, __rust_unstable_column)] #[stable(feature = "core", since = "1.6.0")] @@ -132,7 +134,7 @@ macro_rules! assert_ne { }); } -/// Ensure that a boolean expression is `true` at runtime. +/// Asserts that a boolean expression is `true` at runtime. /// /// This will invoke the [`panic!`] macro if the provided expression cannot be /// evaluated to `true` at runtime. @@ -236,8 +238,7 @@ macro_rules! debug_assert_ne { ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_ne!($($arg)*); }) } -/// Helper macro for reducing boilerplate code for matching `Result` together -/// with converting downstream errors. +/// Unwraps a result or propagates its error. /// /// The `?` operator was added to replace `try!` and should be used instead. /// Furthermore, `try` is a reserved word in Rust 2018, so if you must use @@ -312,7 +313,7 @@ macro_rules! r#try { ($expr:expr,) => (r#try!($expr)); } -/// Write formatted data into a buffer. +/// Writes formatted data into a buffer. /// /// This macro accepts a format string, a list of arguments, and a 'writer'. Arguments will be /// formatted according to the specified format string and the result will be passed to the writer. @@ -434,7 +435,7 @@ macro_rules! writeln { ); } -/// A utility macro for indicating unreachable code. +/// Indicates unreachable code. /// /// This is useful any time that the compiler can't determine that some code is unreachable. For /// example: @@ -502,7 +503,7 @@ macro_rules! unreachable { }); } -/// A standardized placeholder for marking unfinished code. +/// Indicates unfinished code. /// /// This can be useful if you are prototyping and are just looking to have your /// code type-check, or if you're implementing a trait that requires multiple @@ -559,10 +560,10 @@ macro_rules! unimplemented { ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*))); } -/// A standardized placeholder for marking unfinished code. +/// Indicates unfinished code. /// /// This can be useful if you are prototyping and are just looking to have your -/// code typecheck. `todo!` works exactly like `unimplemented!`, there only +/// code typecheck. `todo!` works exactly like `unimplemented!`. The only /// difference between the two macros is the name. /// /// # Panics @@ -618,7 +619,7 @@ macro_rules! todo { ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*))); } -/// A macro to create an array of [`MaybeUninit`] +/// Creates an array of [`MaybeUninit`]. /// /// This macro constructs an uninitialized array of the type `[MaybeUninit; N]`. /// @@ -645,7 +646,7 @@ macro_rules! uninitialized_array { #[cfg(rustdoc)] mod builtin { - /// Unconditionally causes compilation to fail with the given error message when encountered. + /// Causes compilation to fail with the given error message when encountered. /// /// For more information, see the documentation for [`std::compile_error!`]. /// @@ -657,7 +658,7 @@ mod builtin { ($msg:expr,) => ({ /* compiler built-in */ }); } - /// The core macro for formatted string creation & output. + /// Constructs parameters for the other string-formatting macros. /// /// For more information, see the documentation for [`std::format_args!`]. /// @@ -669,7 +670,7 @@ mod builtin { ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }); } - /// Inspect an environment variable at compile time. + /// Inspects an environment variable at compile time. /// /// For more information, see the documentation for [`std::env!`]. /// @@ -681,7 +682,7 @@ mod builtin { ($name:expr,) => ({ /* compiler built-in */ }); } - /// Optionally inspect an environment variable at compile time. + /// Optionally inspects an environment variable at compile time. /// /// For more information, see the documentation for [`std::option_env!`]. /// @@ -693,7 +694,7 @@ mod builtin { ($name:expr,) => ({ /* compiler built-in */ }); } - /// Concatenate identifiers into one identifier. + /// Concatenates identifiers into one identifier. /// /// For more information, see the documentation for [`std::concat_idents!`]. /// @@ -717,7 +718,7 @@ mod builtin { ($($e:expr,)*) => ({ /* compiler built-in */ }); } - /// A macro which expands to the line number on which it was invoked. + /// Expands to the line number on which it was invoked. /// /// For more information, see the documentation for [`std::line!`]. /// @@ -726,7 +727,7 @@ mod builtin { #[rustc_doc_only_macro] macro_rules! line { () => ({ /* compiler built-in */ }) } - /// A macro which expands to the column number on which it was invoked. + /// Expands to the column number on which it was invoked. /// /// For more information, see the documentation for [`std::column!`]. /// @@ -735,7 +736,7 @@ mod builtin { #[rustc_doc_only_macro] macro_rules! column { () => ({ /* compiler built-in */ }) } - /// A macro which expands to the file name from which it was invoked. + /// Expands to the file name from which it was invoked. /// /// For more information, see the documentation for [`std::file!`]. /// @@ -744,7 +745,7 @@ mod builtin { #[rustc_doc_only_macro] macro_rules! file { () => ({ /* compiler built-in */ }) } - /// A macro which stringifies its arguments. + /// Stringifies its arguments. /// /// For more information, see the documentation for [`std::stringify!`]. /// @@ -786,7 +787,7 @@ mod builtin { #[rustc_doc_only_macro] macro_rules! module_path { () => ({ /* compiler built-in */ }) } - /// Boolean evaluation of configuration flags, at compile-time. + /// Evaluates boolean combinations of configuration flags, at compile-time. /// /// For more information, see the documentation for [`std::cfg!`]. /// @@ -795,7 +796,7 @@ mod builtin { #[rustc_doc_only_macro] macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) } - /// Parse a file as an expression or an item according to the context. + /// Parses a file as an expression or an item according to the context. /// /// For more information, see the documentation for [`std::include!`]. /// @@ -807,7 +808,7 @@ mod builtin { ($file:expr,) => ({ /* compiler built-in */ }); } - /// Ensure that a boolean expression is `true` at runtime. + /// Asserts that a boolean expression is `true` at runtime. /// /// For more information, see the documentation for [`std::assert!`]. /// diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index d5dc5f7c4f0..f618ba45582 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -4,7 +4,7 @@ //! library. Each macro is available for use when linking against the standard //! library. -/// The entry point for panic of Rust threads. +/// Panics the current thread. /// /// This allows a program to terminate immediately and provide feedback /// to the caller of the program. `panic!` should be used when a program reaches @@ -70,7 +70,7 @@ macro_rules! panic { }); } -/// Macro for printing to the standard output. +/// Prints to the standard output. /// /// Equivalent to the [`println!`] macro except that a newline is not printed at /// the end of the message. @@ -116,7 +116,7 @@ macro_rules! print { ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*))); } -/// Macro for printing to the standard output, with a newline. +/// Prints to the standard output, with a newline. /// /// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone /// (no additional CARRIAGE RETURN (`\r`/`U+000D`). @@ -151,7 +151,7 @@ macro_rules! println { }) } -/// Macro for printing to the standard error. +/// Prints to the standard error. /// /// Equivalent to the [`print!`] macro, except that output goes to /// [`io::stderr`] instead of `io::stdout`. See [`print!`] for @@ -179,7 +179,7 @@ macro_rules! eprint { ($($arg:tt)*) => ($crate::io::_eprint(format_args!($($arg)*))); } -/// Macro for printing to the standard error, with a newline. +/// Prints to the standard error, with a newline. /// /// Equivalent to the [`println!`] macro, except that output goes to /// [`io::stderr`] instead of `io::stdout`. See [`println!`] for @@ -210,8 +210,9 @@ macro_rules! eprintln { }) } -/// A macro for quick and dirty debugging with which you can inspect -/// the value of a given expression. An example: +/// Prints the value of a given expression for quick and dirty debugging. +/// +/// An example: /// /// ```rust /// let a = 2; @@ -328,7 +329,7 @@ macro_rules! dbg { } } -/// A macro to await on an async call. +/// Awaits the completion of an async call. #[macro_export] #[unstable(feature = "await_macro", issue = "50547")] #[allow_internal_unstable(gen_future, generators)] @@ -351,7 +352,7 @@ macro_rules! r#await { } } } -/// A macro to select an event from a number of receivers. +/// Selects the first successful receive event from a number of receivers. /// /// This macro is used to wait for the first event to occur on a number of /// receivers. It places no restrictions on the types of receivers given to @@ -423,7 +424,7 @@ macro_rules! assert_approx_eq { #[cfg(rustdoc)] mod builtin { - /// Unconditionally causes compilation to fail with the given error message when encountered. + /// Causes compilation to fail with the given error message when encountered. /// /// This macro should be used when a crate uses a conditional compilation strategy to provide /// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`], @@ -465,7 +466,7 @@ mod builtin { ($msg:expr,) => ({ /* compiler built-in */ }); } - /// The core macro for formatted string creation & output. + /// Constructs parameters for the other string-formatting macros. /// /// This macro functions by taking a formatting string literal containing /// `{}` for each additional argument passed. `format_args!` prepares the @@ -517,7 +518,7 @@ mod builtin { ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }); } - /// Inspect an environment variable at compile time. + /// Inspects an environment variable at compile time. /// /// This macro will expand to the value of the named environment variable at /// compile time, yielding an expression of type `&'static str`. @@ -555,7 +556,7 @@ mod builtin { ($name:expr,) => ({ /* compiler built-in */ }); } - /// Optionally inspect an environment variable at compile time. + /// Optionally inspects an environment variable at compile time. /// /// If the named environment variable is present at compile time, this will /// expand into an expression of type `Option<&'static str>` whose value is @@ -581,7 +582,7 @@ mod builtin { ($name:expr,) => ({ /* compiler built-in */ }); } - /// Concatenate identifiers into one identifier. + /// Concatenates identifiers into one identifier. /// /// This macro takes any number of comma-separated identifiers, and /// concatenates them all into one, yielding an expression which is a new @@ -634,7 +635,7 @@ mod builtin { ($($e:expr,)*) => ({ /* compiler built-in */ }); } - /// A macro which expands to the line number on which it was invoked. + /// Expands to the line number on which it was invoked. /// /// With [`column!`] and [`file!`], these macros provide debugging information for /// developers about the location within the source. @@ -659,7 +660,7 @@ mod builtin { #[rustc_doc_only_macro] macro_rules! line { () => ({ /* compiler built-in */ }) } - /// A macro which expands to the column number on which it was invoked. + /// Expands to the column number at which it was invoked. /// /// With [`line!`] and [`file!`], these macros provide debugging information for /// developers about the location within the source. @@ -684,7 +685,7 @@ mod builtin { #[rustc_doc_only_macro] macro_rules! column { () => ({ /* compiler built-in */ }) } - /// A macro which expands to the file name from which it was invoked. + /// Expands to the file name in which it was invoked. /// /// With [`line!`] and [`column!`], these macros provide debugging information for /// developers about the location within the source. @@ -708,7 +709,7 @@ mod builtin { #[rustc_doc_only_macro] macro_rules! file { () => ({ /* compiler built-in */ }) } - /// A macro which stringifies its arguments. + /// Stringifies its arguments. /// /// This macro will yield an expression of type `&'static str` which is the /// stringification of all the tokens passed to the macro. No restrictions @@ -822,7 +823,7 @@ mod builtin { #[rustc_doc_only_macro] macro_rules! module_path { () => ({ /* compiler built-in */ }) } - /// Boolean evaluation of configuration flags, at compile-time. + /// Evaluates boolean combinations of configuration flags at compile-time. /// /// In addition to the `#[cfg]` attribute, this macro is provided to allow /// boolean expression evaluation of configuration flags. This frequently @@ -844,7 +845,7 @@ mod builtin { #[rustc_doc_only_macro] macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) } - /// Parse a file as an expression or an item according to the context. + /// Parses a file as an expression or an item according to the context. /// /// The file is located relative to the current file (similarly to how /// modules are found). @@ -890,7 +891,7 @@ mod builtin { ($file:expr,) => ({ /* compiler built-in */ }); } - /// Ensure that a boolean expression is `true` at runtime. + /// Asserts that a boolean expression is `true` at runtime. /// /// This will invoke the [`panic!`] macro if the provided expression cannot be /// evaluated to `true` at runtime. @@ -944,7 +945,7 @@ mod builtin { } } -/// A macro for defining `#[cfg]` if-else statements. +/// Defines `#[cfg]` if-else statements. /// /// This is similar to the `if/elif` C preprocessor macro by allowing definition /// of a cascade of `#[cfg]` cases, emitting the implementation which matches -- cgit 1.4.1-3-g733a5 From a68a0e33d1d6660ad594ae7be3c6c1cca7c1752c Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Wed, 27 Mar 2019 01:22:23 -0400 Subject: Add documentation about `for` used as higher ranked trait bounds Resolves #55416 --- src/libstd/keyword_docs.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index bef6bc92661..94751cec416 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -286,11 +286,13 @@ mod fn_keyword { } // /// The `for` keyword. /// -/// `for` is primarily used in for-in-loops, but it has a few other pieces of syntactic uses such as -/// `impl Trait for Type` (see [`impl`] for more info on that). for-in-loops, or to be more -/// precise, iterator loops, are a simple syntactic sugar over an exceedingly common practice -/// within Rust, which is to loop over an iterator until that iterator returns `None` (or `break` -/// is called). +/// `for` is primarily used in for-in-loops, but it has a few other pieces of syntactic +/// uses. `for` is used when implementing traits as in `impl Trait for Type` (see +/// [`impl`] for more info on that). `for` is also used for [higher-ranked trait bounds] +/// as in `for<'a> &'a T: PartialEq`. for-in-loops, or to be more precise, iterator +/// loops, are a simple syntactic sugar over an exceedingly common practice within Rust, +/// which is to loop over an iterator until that iterator returns `None` (or `break` is +/// called). /// /// ```rust /// for i in 0..5 { -- cgit 1.4.1-3-g733a5 From 65b5e572266ace8d9dc817ab5f8c54b675614110 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Wed, 27 Mar 2019 01:52:55 -0400 Subject: Make into itemized list and fix some wording --- src/libstd/keyword_docs.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index 94751cec416..3eec5468c7d 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -286,13 +286,16 @@ mod fn_keyword { } // /// The `for` keyword. /// -/// `for` is primarily used in for-in-loops, but it has a few other pieces of syntactic -/// uses. `for` is used when implementing traits as in `impl Trait for Type` (see -/// [`impl`] for more info on that). `for` is also used for [higher-ranked trait bounds] -/// as in `for<'a> &'a T: PartialEq`. for-in-loops, or to be more precise, iterator -/// loops, are a simple syntactic sugar over an exceedingly common practice within Rust, -/// which is to loop over an iterator until that iterator returns `None` (or `break` is -/// called). +/// The `for` keyword is used in many syntactic locations: +/// +/// * `for` is used in for-in-loops (see below). +/// * `for` is used when implementing traits as in `impl Trait for Type` (see [`impl`] for more info +/// on that). +/// * `for` is also used for [higher-ranked trait bounds] as in `for<'a> &'a T: PartialEq`. +/// +/// for-in-loops, or to be more precise, iterator loops, are a simple syntactic sugar over a common +/// practice within Rust, which is to loop over an iterator until that iterator returns `None` (or +/// `break` is called). /// /// ```rust /// for i in 0..5 { -- cgit 1.4.1-3-g733a5 From 3e0db7cecd77dc7f780de0983beffd0d2f8caea7 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Wed, 27 Mar 2019 11:22:55 -0400 Subject: Clarify behavior of dbg macro --- src/libstd/macros.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/libstd') diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index f618ba45582..d5afd069d7f 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -210,7 +210,8 @@ macro_rules! eprintln { }) } -/// Prints the value of a given expression for quick and dirty debugging. +/// Prints and returns the value of a given expression for quick and dirty +/// debugging. /// /// An example: /// -- cgit 1.4.1-3-g733a5 From f0a76107248ab2366ab5dd2d63cd0ec489e5d8b4 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Wed, 27 Mar 2019 12:03:14 -0400 Subject: Add higher-ranked trait bounds link --- src/libstd/keyword_docs.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libstd') diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index 3eec5468c7d..7223eb3bf0e 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -352,6 +352,7 @@ mod fn_keyword { } /// For more information on for-loops, see the [Rust book] or the [Reference]. /// /// [`impl`]: keyword.impl.html +/// [higher-ranked trait bounds]: https://doc.rust-lang.org/nightly/reference/trait-bounds.html#higher-ranked-trait-bounds /// [`IntoIterator`]: iter/trait.IntoIterator.html /// [Rust book]: /// https://doc.rust-lang.org/book/2018-edition/ch03-05-control-flow.html#looping-through-a-collection-with-for -- cgit 1.4.1-3-g733a5 From 25452501ee53c60445b9774fa69e2dc2134ddc44 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Wed, 27 Mar 2019 21:46:25 -0400 Subject: Move link to rust book to next line to pass 100 column limit --- src/libstd/keyword_docs.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/libstd') diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index 7223eb3bf0e..7b0d1549e06 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -352,7 +352,8 @@ mod fn_keyword { } /// For more information on for-loops, see the [Rust book] or the [Reference]. /// /// [`impl`]: keyword.impl.html -/// [higher-ranked trait bounds]: https://doc.rust-lang.org/nightly/reference/trait-bounds.html#higher-ranked-trait-bounds +/// [higher-ranked trait bounds]: +/// https://doc.rust-lang.org/nightly/reference/trait-bounds.html#higher-ranked-trait-bounds /// [`IntoIterator`]: iter/trait.IntoIterator.html /// [Rust book]: /// https://doc.rust-lang.org/book/2018-edition/ch03-05-control-flow.html#looping-through-a-collection-with-for -- cgit 1.4.1-3-g733a5 From ffaa5c904e6de9cf15c44adfa43a56f046c28c42 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Wed, 27 Mar 2019 22:11:13 -0400 Subject: Document that `std::io::BufReader` discards contents on drop Resolves #55546 --- src/libstd/io/buffered.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 4668e3ec7ea..487706b05bb 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -21,6 +21,10 @@ use crate::memchr; /// times. It also provides no advantage when reading from a source that is /// already in memory, like a `Vec`. /// +/// When the `BufReader` is dropped, the contents of its buffer will be +/// discarded. Creating multiple instances of a `BufReader` on the same +/// stream can cause data loss. +/// /// [`Read`]: ../../std/io/trait.Read.html /// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read /// [`TcpStream`]: ../../std/net/struct.TcpStream.html -- cgit 1.4.1-3-g733a5 From e1e0e53f1624489afd8f086017a599afbef21058 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Wed, 27 Mar 2019 23:01:24 -0400 Subject: Fix link capitalization in documentation of std::io::BufWriter. --- src/libstd/io/buffered.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 4668e3ec7ea..232afcd518c 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -350,7 +350,7 @@ impl Seek for BufReader { /// /// It can be excessively inefficient to work directly with something that /// implements [`Write`]. For example, every call to -/// [`write`][`Tcpstream::write`] on [`TcpStream`] results in a system call. A +/// [`write`][`TcpStream::write`] on [`TcpStream`] results in a system call. A /// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying /// writer in large, infrequent batches. /// @@ -401,7 +401,7 @@ impl Seek for BufReader { /// the `stream` is dropped. /// /// [`Write`]: ../../std/io/trait.Write.html -/// [`Tcpstream::write`]: ../../std/net/struct.TcpStream.html#method.write +/// [`TcpStream::write`]: ../../std/net/struct.TcpStream.html#method.write /// [`TcpStream`]: ../../std/net/struct.TcpStream.html /// [`flush`]: #method.flush #[stable(feature = "rust1", since = "1.0.0")] -- cgit 1.4.1-3-g733a5