rust-lang / rust-lang/rust-clippy

`SeekFrom::End` should take a non-positive number

Open
#10,799 1 comment 0 reactions 1 assignee View on GitHub

@anthonygedeon is already working on this.

Since May 19, 2023.

A-lint
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

What it does

Notices possible typos of passing a positive literal number to the std::io::SeekFrom::End variant, which is almost always supposed to be used with negative numbers or zero.

Other Seek lints: #7886 seek_from_current, #8600 seek_to_start_instead_of_rewind

Lint Name

seek_from_end_positive

Category

suspicious

Advantage

This is almost certainly a typo. When used with std::fs::File, this results in an empty implementer of std::io::Read, which is the same std::io::Read behavior as SeekFrom::End(0). It is likely the programmer intended to use the negative version of the number.

Although rare, there is no guarantee that the implementer will remember how far past the end it has seeked, leading to possibly inconsistent behavior when operating generically over Seek implementations. A seek past the end could return the stream length, or u32::MAX, or anything else depending on the implementation details.

The main implication of SeekFrom::End is that there is nothing beyond zero, so seeking past the end can still be confusing even when done correctly.

Drawbacks

It is possible SeekFrom is being used outside of Seek::seek. It could also be storing a value that will be modified before passing to Seek::seek. These are uncommon.

It is possible that an implementer of Seek would have meaningful behavior when seeked past the end, especially if this is paired with another (likely variable) seek that uses a negative SeekFrom::Current to bring it back into the valid range of the implementer. However, those are often combined into one Seek::seek call anyway.

Example
use std::io::{Cursor, Seek, SeekFrom};
let mut buf = Cursor::new(vec![1, 2, 3]);
buf.seek(SeekFrom::End(1)).unwrap();

Should be written as:

use std::io::{Cursor, Seek, SeekFrom};
let mut buf = Cursor::new(vec![1, 2, 3]);
buf.seek(SeekFrom::End(-1)).unwrap();

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.