Skip to content

== fails to match types on associated type with two PartialEq<A / B> bounds #34792

Closed

Description

@SimonSapin

rustc 1.12.0-nightly (47b3a98 2016-07-10)

pub struct A;
pub struct B;

pub trait Foo {
    type T: PartialEq<A> + PartialEq<B>;
}

pub fn generic<F: Foo>(t: F::T, a: A, b: B) -> bool {
    t == a && t == b
}
error: mismatched types [--explain E0308]
  --> a.rs:12:10
   |>
12 |>     t == a && t == b
   |>          ^ expected struct `B`, found struct `A`
note: expected type `B`
note:    found type `A`

error: aborting due to previous error

Changing the order of bounds in the associated type declaration changes which == causes a spurious "mismatched types" error.

Using UFCS works around the issue:

    PartialEq::<A>::eq(&t, &a) && t == b

The same issue exists with bounds like type T: PartialEq + PartialEq<B> to compare T with itself as well as another type.

Activity

  1. added
    A-associated-itemsArea: Associated items (types, constants & functions)
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jul 12, 2016
  2. hanna-kruppe commented on Jul 13, 2016

    @hanna-kruppe
    Contributor

    cf. #24066

  3. eddyb commented on Jul 16, 2016

    @eddyb
    Contributor

    Looks like this is caused by using find on the set of bounds from the trait, but that is just find the first one (in the order they are internally stored), this needs to filter and produce a vector of bounds or something similar.

    cc @rust-lang/compiler

  4. rozbb commented on Jul 18, 2016

    @rozbb

    Update: using filter and then calling candidates.extend on all matching bounds does not fix this issue.

  5. eddyb commented on Jul 18, 2016

    @eddyb
    Contributor

    @doomrobo I believe your problem is this logic.
    Right now it works fine because the if victim.candidate == other.candidate above would trigger for ObjectCandidate vs ObjectCandidate or ParamCandidate vs ParamCandidate.

    However, it's incorrect with your changes as ParamCandidate(bound_a) is dropped in favor of ParamCandidate(bound_b) even if bound_a and bound_b are not equal.
    The correct form would be more like this:

                    // Arbitrarily give param candidates priority
                    // over projection and object candidates.
                    ObjectCandidate => true,
                    ProjectionCandidate(_) => {
                        if let ProjectionCandidate(_) = other.candidate {
                            false
                        } else {
                            true
                        }
                    },
  6. nikomatsakis commented on Jul 18, 2016

    @nikomatsakis
    Contributor

    I guess that you didn't just call filter, but are also packaging up the specific bound that was matched? Anyway, not having seen the full diff, the general direction of these changes make sense to me.

  7. nikomatsakis commented on Jul 21, 2016

    @nikomatsakis
    Contributor

    Related: #34912

  8. pnkfelix commented on Jul 21, 2016

    @pnkfelix
    Contributor

    triage: P-medium

  9. 9 remaining items

  10. SimonSapin commented on Jan 8, 2021

    @SimonSapin
    ContributorAuthor

    Oh good point. Sorry I missed the label.

    @humancalico Yes, feel free to work on adding a regression test!

  11. bugadani commented on Jan 16, 2021

    @bugadani
    Contributor

    @rustbot claim

  12. added a commit that references this issue on Jan 16, 2021
  13. added a commit that references this issue on Jan 16, 2021
  14. added a commit that references this issue on Jan 16, 2021
  15. added and removed on Dec 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-associated-itemsArea: Associated items (types, constants & functions)A-type-systemArea: Type systemC-bugCategory: This is a bug.E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.P-mediumMedium priorityT-compilerRelevant to the compiler 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