Skip to content

Fully generalize cmp instances #20063

Open

Description

@aturon

With cmp/ops reform, all of the comparison traits allow the types of the two sides to differ. However, the traits provide a default type for the right-hand size that is the same as the left-hand side. Thus, an impl like:

impl<T: PartialEq> PartialEq for Rc<T> { ... }

is more limited than it needs to be; it could instead be

impl<U, T: PartialEq<U>> PartialEq<Rc<U>> for Rc<T> { ... }

(Of course, you could imagine being even more general than that, allowing Rc values to be compared to other values.)

The various impls in the standard library should probably be generalized along these lines; currently a few are but most aren't.

Activity

  1. aturon commented on Dec 20, 2014

    @aturon
    ContributorAuthor

    cc @japaric @alexcrichton

    I don't think we need to do this prior to stabilization, since we can always safely generalize in the future. I'd also like to put some thought into how general we want to make things, but the example above seems like a good minimum.

  2. aturon commented on Dec 20, 2014

    @aturon
    ContributorAuthor

    A bit of follow up: I'm seeing some cases where e.g. the PartialEq implementation has been generalized like the above, but the Eq hasn't.

  3. added a commit that references this issue on Dec 31, 2014
  4. steveklabnik commented on Jan 21, 2015

    @steveklabnik
    Contributor

    What's the status of this with #20065 merged?

  5. steveklabnik commented on Feb 15, 2015

    @steveklabnik
    Contributor

    I am guessing the status is that it's done, so I'm giving it a close. Let me know if there's anything specific still missing.

  6. aturon commented on Feb 16, 2015

    @aturon
    ContributorAuthor

    @steveklabnik No, this hasn't been done yet. Basically it would require a sweep through all existing impls to generalize them.

    I'm not sure where you want to track tickets like this. It's generally backwards compatible to make these changes, and not exactly high priority, but something nice for expressiveness and consistency (and definitely does not require an RFC).

  7. reopened this on Feb 16, 2015
  8. steveklabnik commented on Feb 16, 2015

    @steveklabnik
    Contributor

    Yeah, it's hard because it's not directly actionable, it's more like 'double check all these things.' It'd be nice if we had an actual list.

  9. 10 remaining items

  10. added
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    and removed on Jul 22, 2017
  11. added
    C-feature-requestCategory: A feature request, i.e: not implemented / a PR.
    and removed
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    on Nov 19, 2017
  12. m-ou-se commented on Jan 5, 2022

    @m-ou-se
    Member

    @rust-lang/lang How realistic would it be to for a solution for the problem here to be designed and accepted any time soon? Ideally we'd make Some("1".to_string()) == Some("1") work, but right now we can't do that without breaking Some(1) == None and None == Some(1).

  13. m-ou-se commented on Jan 5, 2022

    @m-ou-se
    Member

    Note that it wouldn't need to have T = U and U = T defaults on the PartialEq impl. Default of T = ! and U = ! (or some other dummy type) would also work, as long as ! implements PartialEq<T> for all T, and all T implement PartialEq<!> (which overlap, but that should be fine for !).

  14. fdecode commented on Nov 22, 2024

    @fdecode

    Some languages are able to do point-to-point vectorial comparisons:

    [1, 2, 3, 4, 5] <= [5, 4, 3, 2, 1] will give [true, true, true, false, false]
    

    Such overloading would be possible, for example, if trait PartialOrd had associated output type, as (this is only a sketchy suggestion):

    pub trait PartialOrd<Rhs = Self>: PartialEq<Rhs>
    where
        Rhs: ?Sized,
    {
        type Ordering;
        type Bool;
        
        fn partial_cmp(&self, other: &Rhs) -> Option<Self::Ordering>;
    
        fn lt(&self, other: &Rhs) -> Self::Bool { ... }
        fn le(&self, other: &Rhs) -> Self::Bool { ... }
        fn gt(&self, other: &Rhs) -> Self::Bool { ... }
        fn ge(&self, other: &Rhs) -> Self::Bool { ... }
    }
    

    In whatever case, is there an RFC aimed at enabling point-to-point vector comparisons (or even more general comparisons such as functional point-to-point comparisons, etc.)?

  15. scottmcm commented on Nov 24, 2024

    @scottmcm
    Member
  16. added 2 commits that reference this issue on Jun 30, 2025
  17. added
    T-libsRelevant to the library team, which will review and decide on the PR/issue.
    and removed
    T-libs-api[DEPRECATED; DO NOT USE]
    on Aug 12, 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-feature-requestCategory: A feature request, i.e: not implemented / a PR.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