You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
== fails to match types on associated type with two PartialEq<A / B> bounds #34792
pubstructA;pubstructB;pubtraitFoo{typeT:PartialEq<A> + PartialEq<B>;}pubfngeneric<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.
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.
@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(_) => {ifletProjectionCandidate(_) = other.candidate{false}else{true}},
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.
Activity
hanna-kruppe commentedon Jul 13, 2016
cf. #24066
eddyb commentedon Jul 16, 2016
Looks like this is caused by using
findon 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
rozbb commentedon Jul 18, 2016
Update: using filter and then calling
candidates.extendon all matching bounds does not fix this issue.eddyb commentedon Jul 18, 2016
@doomrobo I believe your problem is this logic.
Right now it works fine because the
if victim.candidate == other.candidateabove would trigger forObjectCandidatevsObjectCandidateorParamCandidatevsParamCandidate.However, it's incorrect with your changes as
ParamCandidate(bound_a)is dropped in favor ofParamCandidate(bound_b)even ifbound_aandbound_bare not equal.The correct form would be more like this:
nikomatsakis commentedon Jul 18, 2016
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.nikomatsakis commentedon Jul 21, 2016
Related: #34912
pnkfelix commentedon Jul 21, 2016
triage: P-medium
9 remaining items
SimonSapin commentedon Jan 8, 2021
Oh good point. Sorry I missed the label.
@humancalico Yes, feel free to work on adding a regression test!
bugadani commentedon Jan 16, 2021
@rustbot claim
Rollup merge of rust-lang#81081 - bugadani:double-partialeq, r=Mark-S…
Rollup merge of rust-lang#81081 - bugadani:double-partialeq, r=Mark-S…
Auto merge of rust-lang#81089 - m-ou-se:rollup-z7iac6i, r=m-ou-se