Skip to content

Simplify Duration::from_secs(expr) and Duration::from_mins(expr) when expr is a valid minute or hour #16335

@edward-shen

Description

@edward-shen

What it does

I would like to enable a lint across my codebase for when Durations needlessly constructed from a smaller unit of time (seconds, minutes) when a larger unit of time (minutes, hours; respectively) suffice.

Generally, I'd like to see a lint complex_duration_construction where it does the following in order:

  • if expr in Duration::from_secs(expr) is a multiple of 3600, replace it with Duration::from_hours(expr2), where expr2 is expr / 3600.
  • if expr in Duration::from_secs(expr) is a multiple of 60, replace it with Duration::from_mins(expr2), where expr2 is expr / 60.
  • if expr in Duration::from_mins(expr) is a multiple of 60, replace it with Duration::from_hours(expr2), where expr2 is expr / 60.

This lint would probably only apply for only literal values.

Advantage

  • Clarifies larger durations
  • Reduces chances for bad math in calculating hours

Drawbacks

  • Limited to places where it's not evaluating some other value, e.g. const ONE_SECOND = 1; Duration::from_secs(ONE_SECOND * 60) would be missed.
  • Might need maintenance for higher level constructors, e.g. a hypothetical Duration::from_days
  • For larger durations, e.g. 2 days, might not be better, e.g. Duration::from_secs(86400 * 2) would be linted to Duration::from_hours(48).

Example

Duration::from_secs(3600);
Duration::from_secs(60 * 60);
Duration::from_secs(5 * 60 * 60);
Duration::from_secs(60 * 60 * 5);
Duration::from_secs(60 * 5 * 60);
Duration::from_secs(5 * 1 * 1 * 1 * 1 * 60 * 60); // expr can be very long
Duration::from_secs(3600);
Duration::from_secs(86400 * 5);

Duration::from_secs(5 * 60);
Duration::from_secs(60 * 5);
Duration::from_secs(60 * 1 * 1 * 1 * 1 * 5); 

Duration::from_mins(60);
Duration::from_mins(5 * 60);
Duration::from_mins(60 * 5);
Duration::from_mins(60 * 1 * 1 * 1 * 5);

Could be written as:

Duration::from_hours(1);
Duration::from_hours(1);
Duration::from_hours(5);
Duration::from_hours(5);
Duration::from_hours(5);
Duration::from_hours(5); // expr can be very long
Duration::from_hours(1);
Duration::from_hours(120);

Duration::from_mins(5);
Duration::from_mins(5);
Duration::from_mins(5); 

Duration::from_hours(1);
Duration::from_hours(5);
Duration::from_hours(5);
Duration::from_hours(5);

Comparison with existing lints

clippy::duration_subsec applies something somewhat similar but in the other direction; clippy::unreadable_literal probably is closer to the intent of this lint.

Additional Context

No response

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