-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Add std::io::Seek
instance for std::io::Take
#138023
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
library/std/src/io/mod.rs
Outdated
#[stable(feature = "seek_io_take", since = "CURRENT_RUSTC_VERSION")] | ||
pub fn position(&self) -> u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API needs to start out as unstable
where possible, the only exception is trait implementations because that part doesn't currently work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't just change it to unstable
because then the compiler complains that seek_io_take
is both stable and unstable. I see a few options:
- mark unstable the trait implementation
- I have another feature for position
- make position private (for now?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can just be a separate feature gate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed it to be unstable and put behind a different feature gate seek_io_take_position
.
It doesn't look like #97227 was ever accepted by libs-api. Could you file an API change proposal? This is an issue template at https://github.com/rust-lang/libs-team/issues. Please include the proposed The trait implementation is insta-stable so it will need FCP if accepted. |
library/std/src/io/mod.rs
Outdated
let offset_from_start = match pos { | ||
SeekFrom::Start(offset) => offset, | ||
SeekFrom::End(offset) => { | ||
if offset > 0 { |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's with the funny python-indexing-style logic?
ok, maybe your logic doesn't do that but it is written in a very confusing way with unsigned_abs
everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a hopefully easier to understand implementation:
(I also implemented some other Seek
methods and implemented the range-limited seeking as suggested in rust-lang/libs-team#555 (comment))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The usage of unsigned_abs
was to deal with u64
, i64
and the fact that I need to seek the inner
from Current
. I'm ok with your implementation though. I have one question about it: your implementation makes use of the unstable features unsigned_signed_diff
and seek_stream_len
, is it fine to use unstable features in the rust library? Should I just add the two unstable features to the crate attributes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
afaik it's generally fine to use unstable library features in the rust standard library, those are implemented in the same git repository, so if they need to change or are removed, the code using them can be updated at the same time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@programmerjake I pushed your implementation with a132fcb. I also removed the tests that now fail and added the needed unstable feature to library/std/src/lib.rs
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice! you'll probably want to add some tests that out-of-bounds seeks actually error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I added five new tests with 6ee1a13:
take_seek_out_of_bounds_start
checksStart
with offset bigger thanlen
take_seek_out_of_bounds_end_forward
checksEnd
with positive non-zero offsewttake_seek_out_of_bounds_end_before_start
checksEnd
with offset smaller than-len
take_seek_out_of_bounds_current_before_start
checksCurrent
with offset that pushes position before zerotake_seek_out_of_bounds_current_after_end
checksCurrent
with offset that pushes position afterlen
this looks generally pretty good to me, the next steps are to get someone to second the ACP and to get team signoff here (because the trait impl is insta-stable), I can't do either of those. @rustbot label +needs-fcp,+T-libs-api |
if you think you're done writing the code, you can comment |
@rustbot ready |
i guess i didn't notice it was already labeled as waiting on review...sorry, that wasn't necessary. |
No problem 😄. I created the PR and I should have checked. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me (not a reviewer). The logic seems sound and it even handles the pathological case of adapting absolute offsets over isize::MAX
to relative.
Since you update
Initially, I thought the inconsistency with |
ACP was accepted rust-lang/libs-team#555 (comment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the tracking issue #97227 needs to be updated to include position
and seek_io_take_position
.
other than that, lgtm!
@melrief could you squash? Also, what is the point of position? In cases where this may change ( |
@rust-lang/libs-api this adds the new insta-stable API so will need FCP: impl<T: Seek> Seek for Take<T> { /* ... */ This was accepted in ACP rust-lang/libs-team#555. The tracking issue #97227 has been around much longer, with an abandoned implementation in #97230 and #97807. @rustbot label +I-libs-api-nominated Also to consider is whether or not we need the |
imo it's useful because it's not fallible, this is kinda similar to how we have |
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One nit then r=me
e2ec4b6
to
3ae6577
Compare
This comment has been minimized.
This comment has been minimized.
3ae6577
to
7e44db3
Compare
let buf = Cursor::new(b"0123456789"); | ||
let mut take = buf.take(2); | ||
assert!(take.seek(SeekFrom::Start(3)).is_err()); | ||
assert!(take.seek(SeekFrom::End(1)).is_err()); | ||
assert!(take.seek(SeekFrom::End(-3)).is_err()); | ||
assert!(take.seek(SeekFrom::Current(-1)).is_err()); | ||
assert!(take.seek(SeekFrom::Current(3)).is_err()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, one more question. With .take(2)
, isn't SeekFrom::Start(3)
one beyond the error condition rather than the first error? I.e. SeekFrom::Start(2)
and SeekFrom::Current(2)
should also fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current implementation assumes that there is a valid position after the last element of the Take
and you can seek
to it. The rationale is to keep Read
and Seek
consistent. When you read
the last element of a Take
, the position is one after the last element. To stay consistent, seek
allows to move to this position. No element can be read from that point ofc . I can add a test of this behavior if you want.
Note that there is no documented requirement in seek
for this behavior. I just picked the one that made sense to me. I'm happy to change this if you think it's not correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for explaining, makes complete sense. A test wouldn’t hurt if you have one in mind, happy to merge after.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added https://github.com/rust-lang/rust/pull/138023/files#diff-7978b30f81fdec805305c6965b5f90ee70139a7f15e9f81a4f95734f715c7afcR441 and https://github.com/rust-lang/rust/pull/138023/files#diff-7978b30f81fdec805305c6965b5f90ee70139a7f15e9f81a4f95734f715c7afcR474 that checks that nothing can be read from the end of the Take
.
7e44db3
to
c8f5ff8
Compare
Thank you for all the follow up here! @bors r+ |
☀️ Test successful - checks-actions |
What is this?This is an experimental post-merge analysis report that shows differences in test outcomes between the merged PR and its parent PR.Comparing 59372f2 (parent) -> 60dabef (this PR) Test differencesShow 26 test diffsStage 0
Stage 1
Additionally, 20 doctest diffs were found. These are ignored, as they are noisy. Job group index
Test dashboardRun cargo run --manifest-path src/ci/citool/Cargo.toml -- \
test-dashboard 60dabef95a3de3ec974dcb50926e4bfe743f078f --output-dir test-dashboard And then open Job duration changes
How to interpret the job duration changes?Job durations can vary a lot, based on the actual runner instance |
Finished benchmarking commit (60dabef): comparison URL. Overall result: ❌ regressions - please read the text belowOur benchmarks found a performance regression caused by this PR. Next Steps:
@rustbot label: +perf-regression Instruction countThis is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.
Max RSS (memory usage)Results (secondary 2.0%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (primary 3.0%, secondary -1.7%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeResults (primary 1.1%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Bootstrap: 775.652s -> 775.977s (0.04%) |
since this is stabilizing new API, shouldn't this get the relnotes label? |
Noise in newly added benchmarks. @rustbot label: +perf-regression-triaged |
…tgross35 Add `std::io::Seek` instance for `std::io::Take` Library tracking issue [rust-lang#97227](rust-lang#97227). ACP: rust-lang/libs-team#555 1. add a `len` field to `Take` to keep track of the original number of bytes that `Take` could read 2. add a `position()` method to return the current position of the cursor inside `Take` 3. implement `std::io::Seek` for `std::io::Take` Closes: rust-lang/libs-team#555
Library tracking issue #97227.
ACP: rust-lang/libs-team#555
len
field toTake
to keep track of the original number of bytes thatTake
could readposition()
method to return the current position of the cursor insideTake
std::io::Seek
forstd::io::Take
Closes: rust-lang/libs-team#555