Skip to content

Duration arithmetic #13734

Open
Open
@sharksforarms

Description

@sharksforarms

What it does

A common pattern is to get the current epoch time and to subtract another epoch timestamp to get the difference, for example:

use std::time::{Duration, SystemTime, UNIX_EPOCH};

fn main() {
    let now = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("could not get epoch time");
    let event_timestamp = now + Duration::from_secs(5); // future

    let event_delay = now - event_timestamp; // <-- may panic, lint for this would be cool
    dbg!(&event_delay);
}

thread 'main' panicked at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/time.rs:1141:31:
overflow when subtracting durations
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

The unchecked_duration_subtraction seems to apply only to Instant - Duration where in this case, it's a Duration - Duration, there's also other cases where a Duration may panic (overflow, for example)

https://rust-lang.github.io/rust-clippy/master/index.html#/unchecked_duration_subtraction

The unchecked_duration_subtraction sounds generic enough that this pattern could be folded into that lint? Thoughts?

Advantage

No response

Drawbacks

No response

Example

use std::time::{Duration, SystemTime, UNIX_EPOCH};

fn main() {
    let now = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("could not get epoch time");
    let event_timestamp = now + Duration::from_secs(5); // future

    let event_delay = now - event_timestamp; // <-- may panic, lint for this would be cool
    dbg!(&event_delay);
}

Could be written as:

use std::time::{Duration, SystemTime, UNIX_EPOCH};

fn main() {
    let now = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("could not get epoch time");
    let event_timestamp = now + Duration::from_secs(5); // future

    let event_delay = now.checked_sub(event_timestamp) // or `saturating_sub`
    dbg!(&event_delay);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintArea: New lints

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions