Skip to content

Tracking Issue for clamp_to #147781

Open
Open

Description

@Kyuuhachi

Feature gate: #![feature(clamp_to)], as well as possibly perma-unstable #[feature(clamp_bounds)].

This is a tracking issue for rust-lang/libs-team#665, which adds less confusable alternatives for x.min(y) and x.max(y).

Public API

// Perma-unstable
trait ClampBounds<T> {
    fn clamp(self, x: T) -> T;
}

impl ClampBounds<T> for RangeInclusive<T> where T: Ord {}
impl ClampBounds<f32> for RangeInclusive<f32> {}
// likewise for RangeFrom, RangeToInclusive, and RangeFull, and for f16/f64/f128

trait Ord {
    fn clamp_to(self, range: impl ClampBounds<Self>) -> Self;
}

// For each floating-point type:
impl f32 {
    fn clamp_to(self, range: impl ClampBounds<Self>) -> Self;
}

Steps / History

(Remember to update the S-tracking-* label when checking boxes.)

Unresolved Questions

  • Is having these functions, where clamp_min == max, actually less confusing than the status quo?
    • It is not. Switched to clamp_to with ranges.
  • Should there be a lint that suggests replacing x.max(y) with x.clamp_to(y..)?
  • What semantics should the float versions have regarding NaN? NAN.max(0.0) is 0, while NAN.clamp(0.0, 0.0) is NaN, and 0.0.clamp(NAN, NAN) panics.

Footnotes

  1. https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html ↩

Activity

  1. added
    T-libs-api[DEPRECATED; DO NOT USE]
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    on Oct 16, 2025
  2. Kyuuhachi commented on Oct 16, 2025

    @Kyuuhachi
    ContributorAuthor

    I'm adding NaN semantics to unresolved questions. Current implementation has same as .max(), but it would also make sense to have the same semantics as .clamp().

  3. ChrisDenton commented on Oct 17, 2025

    @ChrisDenton
    Member

    On the original zulip thread, simulacrum suggested naming these at_most and at_least, which would avoid the slightly confusing naming where clamp_max does the opposite to max.

  4. clarfonthey commented on Oct 19, 2025

    @clarfonthey
    Contributor

    I don't really like the idea of having two methods that do exactly the same thing with different names. I think it's reasonable to deprecate a name in favour of a new one, but not just have two concurrent names at the same time.

    I agree that at_most and at_least are more understandable than the current names and might actually be an improvement, but I would much rather have something like clamp_into(range) than a pair of methods, so there's actually the additional benefit of showing the range instead, although you would have to be careful to explicitly disallow exclusive ranges.

  5. joboet commented on Oct 21, 2025

    @joboet
    Member

    I too favour the originally proposed clamp_range, especially as it corresponds nicely with the notion of a "valid value range".

  6. ChrisDenton commented on Oct 21, 2025

    @ChrisDenton
    Member

    Using range types was discussed In the libs-api meeting but team members weren't generally favourable. From memory I think the concern was the added complexity especially considering the fact that most people would be looking to clamp only one side.

    I don't really like the idea of having two methods that do exactly the same thing with different names.

    This was also a concern raised in the meeting. But experimenting with it in nightly was deemed acceptable.

  7. boomshroom commented on Oct 21, 2025

    @boomshroom

    Using range types was discussed In the libs-api meeting but team members weren't generally favourable. From memory I think the concern was the added complexity especially considering the fact that most people would be looking to clamp only one side.

    Oh, so I guess we should get rid of clamp then, since it clamps from both sides?

    Using a range type makes it more obvious that 1-sided clamps from either side and 2-sided clamps are fundamentally the same operation.

  8. ChrisDenton commented on Oct 22, 2025

    @ChrisDenton
    Member

    Oh, so I guess we should get rid of clamp then, since it clamps from both sides?

    No, the fact that clamp exists and nobody has taken issue with it suggests it doesn't need a range replacement.

  9. clarfonthey commented on Oct 22, 2025

    @clarfonthey
    Contributor

    I think that having different names for the versions with different calling conventions is fine, but we can't limit the calling conventions of methods at the moment. Perhaps a good path forward if we do choose to pursue this path is to have a clippy lint (I only propose clippy because it has MSRV support, which rustc lints do not), which suggests reformatting x.min/max(y) into x.clamp_max/min(y) and Ord::clamp_min/max(x, y) into Ord::max/min(x, y). I think this shouldn't be machine-applicable because we want to verify that the user was actually using the right version, and so they should have to manually fix it.

  10. added 2 commits that reference this issue on Nov 1, 2025
  11. added a commit that references this issue on Nov 1, 2025
  12. orlp commented on Dec 16, 2025

    @orlp
    Contributor

    I think the names clamp_min and clamp_max are actively harmful. They only further amplify the original motivation for the ACP, rather than solve it:

    It is a fairly common mistake to write x.max(8) and expect "x but no more than 8", when it's in fact the opposite.

    Before this was simply a problem for beginners, a mistake you make a couple times before realizing that that is not how min/max work. You adjust and move on.

    With the introduction of clamp_min and clamp_max... we've now reified the actual confusion! What used to just be a mistake rooted in imagination is now an actual real function under a subtly different name!


    I would strongly recommend the adoption of a name which does not include min or max. I would suggest either

    • .clamp_at_most(x) / .clamp_at_least(x)
    • .at_most(x) / .at_least(x)
  13. 14 remaining items

  14. added a commit that references this issue on Aug 21, 2026
  15. added a commit that references this issue on Aug 27, 2026
  16. added a commit that references this issue on Aug 27, 2026
  17. added 5 commits that reference this issue on Aug 27, 2026
  18. added 2 commits that reference this issue on Aug 27, 2026
  19. added a commit that references this issue on Aug 27, 2026
  20. added 3 commits that reference this issue on Aug 28, 2026
  21. added a commit that references this issue on Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCS-tracking-unimplementedStatus: The feature has not been implemented.T-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions