Commit graph

776 commits

Author SHA1 Message Date
DPC
6d35f8475f fix 2020-08-31 02:27:38 +02:00
CDirkx
12f4624f71 Update since to correct release
`const_ordering` will stabilize in version 1.48.0
2020-08-30 23:59:37 +02:00
CDirkx
89fc3fb93b Stabilize feature const_ordering 2020-08-30 23:48:54 +02:00
Sebastian Dröge
8d3cf9237d Improve documentation of slice::get_unchecked() / split_at_unchecked()
Thanks to Ivan Tham, who gave the majority of these suggestions during
their review.
2020-08-30 23:13:47 +03:00
Sebastian Dröge
d08996ac54 Get rid of bounds check in slice::chunks_exact() and related functions during construction
LLVM can't figure out in

    let rem = self.len() % chunk_size;
    let len = self.len() - rem;
    let (fst, snd) = self.split_at(len);

and

    let rem = self.len() % chunk_size;
    let (fst, snd) = self.split_at(rem);

that the index passed to split_at() is smaller than the slice length and
adds a bounds check plus panic for it.

Apart from removing the overhead of the bounds check this also allows
LLVM to optimize code around the ChunksExact iterator better.
2020-08-30 23:13:47 +03:00
Sebastian Dröge
30dc32b10e Add (non-public) slice::split_at_unchecked() and split_at_mut_unchecked()
These are unsafe variants of the non-unchecked functions and don't do
any bounds checking.

For the time being these are not public and only a preparation for the
following commit. Making it public and stabilization can follow later
and be discussed in https://github.com/rust-lang/rust/issues/76014 .
2020-08-30 23:13:46 +03:00
Lukas Kalbertodt
d7afe2a223
Fix tests using FixedSizeArray methods (which are now shadowed) 2020-08-30 21:08:18 +02:00
Lukas Kalbertodt
104a02301c
Add [T; N]::as_[mut_]slice
These methods are like the ones on `std::array::FixedSizeArray`
and in the crate `arraytools`.
2020-08-30 21:08:17 +02:00
Camelid
37ea97cc10
Explain why the 0 is a u32 2020-08-30 11:43:16 -07:00
Camelid
7e2548fe69
Import Debug instead of redefining it 2020-08-30 11:39:45 -07:00
CDirkx
5fac991bf6 Add unstable const_ordering feature, and some tests. 2020-08-30 19:40:00 +02:00
Andy Russell
98232ece14
fix broken trait method links 2020-08-30 12:04:43 -04:00
Prabakaran Kumaresshan
523fea4d14 revert Some(Item) link 2020-08-30 19:19:20 +05:30
Ivan Tham
1d017eb6a4
Fix env doc vars_os broken link 2020-08-30 21:19:21 +08:00
DPC
b3d7b7bdcb update fixmes 2020-08-30 14:43:52 +02:00
Prabakaran Kumaresshan
7ea4c28af2 add i32::MAX link 2020-08-30 17:07:50 +05:30
Amjad Alsharafi
300a0072a2 Fix intra-doc path resolution problem in library/alloc/src/slice.rs
`alloc::slice` uses `core::slice` functions, documentation are copied
from there and the links as well without resolution. `crate::ptr...`
cannot be resolved in `alloc::slice`, but `ptr` itself is imported in
both `alloc::slice` and `core::slice`, so we used that instead.
2020-08-30 15:22:27 +08:00
Camelid
bd3196282b
other branch -> else branch 2020-08-29 20:53:40 -07:00
Camelid
80dcad9e5b
Be more specific about polymorphic return types
I no longer say "polymorphic" since it's a bit ambiguous here.
2020-08-29 20:52:09 -07:00
Camelid
26eab6a0d5
Specify 0 of type u32 2020-08-29 20:48:53 -07:00
Camelid
0d9a2abe69
It's only an issue without an impl Trait for ! 2020-08-29 20:41:36 -07:00
Camelid
fd985e29dd
cannot have divergence -> cannot diverge 2020-08-29 20:35:58 -07:00
Ivan Tham
00cf550c2b Env use shorter intra-doc links in path
vars() rather than vars function

Co-authored-by: Joshua Nelson <joshua@yottadb.com>

Use [xxx()] rather than the [xxx] function

Co-authored-by: Joshua Nelson <joshua@yottadb.com>

Env text representation of function intra-doc link

Suggested by @jyn514

Link join_paths in env doc for parity

Change xxx to env::xxx for lib env doc

Add link requsted by @jyn514

Fix doc build with same link

Co-authored-by: Joshua Nelson <joshua@yottadb.com>

Fix missing intra-doc link

Fix added whitespace in doc

Co-authored-by: Joshua Nelson <joshua@yottadb.com>

Add brackets for `join_paths`

Co-authored-by: Joshua Nelson <joshua@yottadb.com>

Use unused link join_paths

Removed same link for join_paths

Co-authored-by: Joshua Nelson <joshua@yottadb.com>

Remove unsed link join_paths
2020-08-30 11:16:06 +08:00
Camelid
4aae781407 Add info about ! and impl Trait 2020-08-29 19:59:22 -07:00
Prabakaran Kumaresshan
01d95f241b resolve comments 2020-08-30 05:40:47 +05:30
Prabakaran Kumaresshan
8a92718b64 Switch to intra-doc links in core/src/{convert,iter}/mod.rs 2020-08-30 05:40:47 +05:30
Dylan DPC
11193ca202
Rollup merge of #76029 - denisvasilik:intra-doc-links-core-atomic, r=kennytm
Move to intra-doc links for library/core/src/sync/atomic.rs

Helps with #75080.

@rustbot modify labels: T-doc, A-intra-doc-links, T-rustdoc

Known issues:

* Link from core to std:

    [`Arc`]
	[`std:🧵:yield_now`]
	[`std:🧵:sleep`]
	[`std::sync::Mutex`]
2020-08-30 01:43:59 +02:00
Dylan DPC
96e0bc7b6b
Rollup merge of #75990 - rylev:arm-fastfail, r=alexcrichton
Add __fastfail for Windows on arm/aarch64

Fixes #73215
2020-08-30 01:43:54 +02:00
Dylan DPC
9225aabef4
Rollup merge of #75917 - poliorcetics:intra-doc-core-nonnull, r=jyn514
Move to intra doc links for core::ptr::non_null

Helps with #75080.

@rustbot modify labels: T-doc, A-intra-doc-links, T-rustdoc

r? @jyn514
2020-08-30 01:43:50 +02:00
Dylan DPC
75d6b109c2
Rollup merge of #75874 - pickfire:patch-3, r=jyn514
Shorten liballoc doc intra link while readable

r? @jyn514

Do you want to reviews these sort of pull requests in the future? I might send a few of them while reading vec code.
2020-08-30 01:43:41 +02:00
Dylan DPC
d17db64b8d
Rollup merge of #75852 - camelid:patch-3, r=jyn514
Switch to intra-doc links in `core::hash`

Part of #75080.

@rustbot modify labels: A-intra-doc-links T-doc T-rustdoc
2020-08-30 01:43:39 +02:00
Dylan DPC
027b2f1e06
Rollup merge of #75832 - kofls:intradoc-fix, r=jyn514
Move to intra-doc links for wasi/ext/fs.rs, os_str_bytes.rs…

…, primitive_docs.rs & poison.rs

Partial fix for #75080

r? @jyn514
2020-08-30 01:43:37 +02:00
Hanif Bin Ariffin
cc3b2f9e1d Add more examples to lexicographic cmp on Iterators.
The most important rule of lexicographical comparison is that two arrays
of equal length will be compared until the first difference occured.

The examples provided only focuses on the second rule that says that the
shorter array will be filled with some T2 that is less than every T.
Which is only possible because of the first rule.
2020-08-29 19:01:41 -04:00
DPC
ea800d529a fix tests 2020-08-29 17:25:14 +02:00
Ivan Tham
2d1ab83834
Remove empty vec assertion flow distrupt
Co-authored-by: Joshua Nelson <joshua@yottadb.com>
2020-08-29 23:07:40 +08:00
Ivan Tham
be8b5eb529
Reuse description from drain_filter
Co-authored-by: Joshua Nelson <joshua@yottadb.com>
2020-08-29 22:39:34 +08:00
Ivan Tham
237c5005d6
Use explicit intra-doc link in path for Vec resize 2020-08-29 20:40:05 +08:00
Ivan Tham
12b4cf8c6c
Use assertions on Vec doc
Clarify what the state of Vec after with_capacity on doc.
2020-08-29 18:38:18 +08:00
Ryan Levick
d931e97402 Explicitly look for 'thumb-mode' before using __fastfail on 'arm' 2020-08-29 12:30:49 +02:00
Ivan Tham
d727442f2d
Remove brackets in drain filter docs 2020-08-29 18:23:29 +08:00
Ivan Tham
d504d553f1
Keep doc standard for Vec DrainFilter 2020-08-29 18:21:47 +08:00
Ivan Tham
c7e428e862
Liballoc vec doc use associated function
Co-authored-by: Joshua Nelson <joshua@yottadb.com>
2020-08-29 16:13:05 +08:00
bors
360a372f2c Auto merge of #75877 - vigoux:master, r=Amanieu
Update compiler-builtins

Update the compiler-builtins dependency to include latest changes.

This allows for `aarch64-unknown-linux-musl` to pass all tests.

Fixes #57820 and fixes #46651
2020-08-29 01:48:40 +00:00
DPC
5e208efaa8 rename get_{ref, mut} to assume_init_{ref,mut} in Maybeuninit 2020-08-29 02:13:02 +02:00
bors
7b1dd61bda Auto merge of #72808 - Lucretiel:line-writer-reimpl, r=Amanieu
Substantial refactor to the design of LineWriter

# Preamble

This is the first in a series of pull requests designed to move forward with https://github.com/rust-lang/rust/issues/60673 (and the related [5 year old FIXME](ea7181b5f7/src/libstd/io/stdio.rs (L459-L461))), which calls for an update to `Stdout` such that it can be block-buffered rather than line-buffered under certain circumstances (such as a `tty`, or a user setting the mode with a function call). This pull request refactors the logic `LineWriter` into a `LineWriterShim`, which operates on a `BufWriter` by mutable reference, such that it is easy to invoke the line-writing logic on an existing `BufWriter` without having to construct a new `LineWriter`.

Additionally, fixes #72721

## A note on flushing

Because the word **flush** tends to be pretty overloaded in this discussion, I'm going to use the word **unbuffered** to refer to a `BufWriter` sending its data to the wrapped writer via `write`, without calling `flush` on it, and I'll be using **flushed** when referring to sending data via flush, which recursively writes the data all the way to the final sink.

For example, given a `T = BufWriter<BufWriter<File>>`, saying that `T` **unbuffers** its data means that it is sent to the inner `BufWriter`, but not necessarily to the `File`, whereas saying that `T` **flushes** its data means that causes it (via `Write::flush`) to be delivered all the way to `File`.

# Goals

Once it became clear (for reasons described below) that the best way to approach this would involve refactoring `LineWriter` to work more directly on `BufWriter`'s internals, I established the following design goals for the refactor:

- Do not duplicate logic with `BufWriter`. It's great at buffering and then unbuffering data, so use the existing logic as much as possible.
- Minimize superfluous copying of data into `BufWriter`'s buffer.
- Eliminate calls to `BufWriter::flush` and instead do the same thing as `BufWriter::write`, which is to only write to the wrapped writer (rather than flushing all the way down to the final data sink).
- Uphold the "at-most 1 write of new data" convention of `Write::write`
- Minimize or eliminate dropping errors (that is, eliminate the parts of the old design that threw away errors because `write` *must* report if any bytes were written)
- As much as possible, attempt to fully flush completed lines, and *not* flush partial lines. One of the advantages of this design is that, so long as we don't encounter lines larger than the `BufWriter`'s capacity, partial lines will never be unbuffered, while completed lines will *always* be unbuffered (with subsequent calls to `LineWriter::write` retrying failed writes before processing new data.

# Design

There are two major & related parts of the design.

First, a new internal stuct, `LineWriterShim`, is added. This struct implements all of the actual logic of line-writing in a `Write` implementation, but it only operates on an `&mut BufWriter`. This means that this shim can be constructed on-the-fly to apply line writing logic to an existing `BufWriter`. This is in fact how `LineWriter` has been updated to operate, and it is also how `Stdout` is being updated in my [development branch](https://github.com/Lucretiel/rust/tree/stdout-block-buffer) to switch which mode it wants to use at runtime.

[An example of how this looks in practice](f24f272df6/src/libstd/io/stdio.rs (L479-L484)
)

The second major part of the design that the line-buffering logic, implemented in `LineWriterShim`, has been updated to work slightly more directly on the internals of `BufWriter`. Mostly it makes us of the public interface—particularly `buffer()` and `get_mut()`—but it also controls the flushing of the buffer with `flush_buf` rather than `flush`, and it writes to the buffer infallibly with a new `write_to_buffer` method. This has several advantages:

- Data no longer has to round trip through the `BufWriter`'s buffer. If the user provides a complete line, that line is written directly to the inner writer (after ensuring the existing buffer is flushed).
- The conventional contract of `write`—that at-most 1 attempt to write new data is made—is much more cleanly upheld, because we don't have to perform fallible flushes and perform semi-complicated logic of trying to pretend errors at different stages didn't happen. Instead, after attempting to write lines directly to the buffer, we can infallibly add trailing data to the buffer without allowing any attempts to continue writing it to the `inner` writer.
- Perhaps most importantly, `LineWriter` *no longer performs a full flush on every line.* This makes its behavior much more consistent with `BufWriter`, which unbuffers data to its inner writer, without trying to flush it all the way to the final device. Previously, `LineWriter` had no choice but to use `flush` to ensure that the lines were unbuffered, but by writing directly to `inner` via `get_mut()` (when appropriate), we can use a more correct behavior.

## New(ish) line buffering logic

The logic for line writing has been cleaned up, as described above. It now follows this algorithm for `write`, with minor adjustments for `write_all` and `write_vectored`:

- Does our input data contain a newline?
    - If no:
        - simply use the regular `BufWriter::write` to write it; this will append it to the buffer and/or flush it as necessary based on how full the buffer is and how much input data there is.
        - additionally, if the current buffer ends with `'\n'`, attempt to immediately flush it with `flush_buf` before calling `BufWriter::write` This reproduces the old `needs_flush` behavior and ensures completed lines are flushed as soon as possible. The reason we only check if the buffer *ends* with `'\n'` is discussed later.
    - If yes:
        - First, `flush_buf`
        - Then use `bufwriter.get_mut().write()` to write the input data directly to the underlying writer, up to the last newline. Make at most one attempt at this.
        - If it errors, return the error
        - If it succeeds with a full write, add the remaining data (between the last newline and the end of the input) to the buffer. In order to uphold the "at-most 1 attempt to write new data" convention, no attempts are made to write this data to the inner writer (though obviously a subsequent write may immediately flush it, e.g., if it totally filled the buffer's capacity.
        - If it only partially succeeds, buffer the data only up to the last newline. We do this to try to avoid writing partial lines to the inner writer where possible (that is, whenever the lines are shorter than the total buffer capacity).

While it was not my intention for this behavior to diverge from this existing `LineWriter` algorithm, this updated design emerged very naturally once `LineWriter` wasn't burdened with having to only operate via `BufWriter::flush`. There essentially two main changes to observable behavior:

- `flush` is no longer used to unbuffer lines. The are only written to the writer wrapped by `LineWriter`; this inner writer might do its own buffering. This change makes `LineWriter` consistent with the behavior of `BufWriter`. This is probably the most obvious user-visible change; it's the one I most expect to provoke issue reports, if any are provoked.
- Unless a line exceeds the capacity of the buffer, partial lines are not unbuffered (without the user manually calling flush). This is a less surprising behavior, and is enabled because `LineWriter` now has more precise control of what data is buffered and when it is unbuffered. I'd be surprised if anyone is relying on `LineWriter` unbuffering or flushing *partial* lines that are shorter than the capacity, so I'm not worried about this one.

None of these changes are inconsistent with any published documentation of `LineWriter`. Nonetheless, like all changes with user-facing behavior changes, this design will obviously have to be very carefully scrutinized.

# Alternative designs and design rationalle

The initial goal of this project was to provide a way for the `LineWriter` logic to be operable directly on a `BufWriter`, so that the updated `Stdout` doesn't need to do something convoluted like `enum { BufWriter, LineWriter }` (which ends up being ~~impossible~~ difficult to transition between states after being constructed). The design went through several iterations before arriving at the current draft.

The major first version simply involved adding methods like `write_line_buffered` to `BufWriter`; these would contain the actual logic of line-buffered writing, and would additionally have the advantages (described above) of operating directly on the internals of `BufWriter`. The idea was that `LineWriter` would simply call these methods, and the updated `Stdout` would use either `BufWriter::write` or `BufWriter::write_line_buffered`, depending on what mode it was in.

The major issue with this design is that it loses the ability to take advantage of the `io::Write` trait, which provides several useful default implementations of the various io methods, such as `write_fmt` and `write_all`, just using the core methods. For this reason, the `write_line_buffered` design was retained, but moved into a separate struct called `LineWriterShim` which operates on an `&mut LineWriter`. As part of this move, the logic was lightly retooled to not touch the innards of `BufWriter` directly, but instead to make use of the unexported helper methods like `flush_buf`.

The other design evolutions were mostly related to answering questions like "how much data should be buffered", "how should partial line writes be handled", etc. As much as possible I tried to answer these by emulating the current `LineWriter` logic (which, for example, retries partial line writes on subsequent calls to `write`) while still meeting the refactor design goals.

# Next steps

~Currently, this design fails a few `LineWriter` tests, mostly because they expect `LineWriter` to *fully* flush its content. There are also some changes to the way that `LineWriter` buffers data *after* writing completed lines, aimed at ensuring that partial lines are not unbuffered prematurely. I want to make sure I fully understand the intent behind these tests before I either update the test or update this design so that they pass.~

However, in the meantime I wanted to get this published so that feedback could start to accumulate on it. There's a lot of errata around how I arrived at this design that didn't really fit in this overlong document, so please ask questions about anything that confusing or unclear and hopefully I can explain more of the rationale that led to it.

# Test updates

This design required some tests to be updated; I've research the intent behind these tests (mostly via `git blame`) and updated them appropriately. Those changes are cataloged here.

- `test_line_buffer_fail_flush`: This test was added as a regression test for #32085, and is intended to assure that an errors from `flush` aren't propagated when preceded by a successful `write`. Because type of issue is no longer possible, because `write` calls `buffer.get_mut().write()` instead of `buffer.write(); buffer.flush();`, I'm simply removing this test entirely. Other, similar error invariants related to errors during write-retrying are handled in other test cases.
- `erroneous_flush_retried`: This test was added as a regression test for #37807, and was intended to ensure that flush-retrying (via `needs_flush`) and error-ignoring were being handled correctly (ironically, this issue was caused by the flush-error-ignoring, above). Half of that issue is not possible by design with this refactor, because we no longer make fallible i/o calls that might produce errors we have to ignore after unbuffering lines. The `should_flush` behavior is captured by checking for a trailing newline in the `LineWriter` buffer; this test now checks that behavior.
- `line_vectored`: changes here were pretty minor, mostly related to when partial lines are or aren't written. The old implementation of `write_vectored` used very complicated logic to precisely determine the location of the last newline and precisely write up to that point; this required doing several consecutive fallible writes, with all the complex error handling or ignoring issues that come with it. The updated design does at-most one write of a subset of total buffers (that is, it doesn't split in the middle of a buffer), even if that means writing partial lines. One of the major advantages of the new design is that the underlying vectored write operation on the device can be taken advantage of, even with small writes, so long as they include a newline; previously these were unconditionally buffered then written.
- `line_vectored_partial_and_errors`: Pretty similiar to `line_vectored`, above; this test is for basic error recovery in `write_vectored` for vectored writes. As previously discussed, the mocked behavior being tested for (errors ignored under certain circumstances) no occurs, so I've simplified the test while doing my best to retain its spirit.
2020-08-28 23:41:57 +00:00
Camelid
7be129e53a
Add missing hyphen
reference counted pointer -> reference-counted pointer
2020-08-28 09:29:06 -07:00
Ryan Levick
9e2228d2d0 Back to opcode for 32 bit ARM __fastfail 2020-08-28 17:40:56 +02:00
Denis Vasilik
c7571e6040 Use intra-doc links for bool 2020-08-28 17:30:05 +02:00
Denis Vasilik
4bbed52320 Use intra-doc links 2020-08-28 17:24:47 +02:00
Ivan Tham
2d6ab122b7
Liballoc extend use intra doc link 2020-08-28 19:33:53 +08:00