Skip to content

Commit 3a92645

Browse files
authored
Rollup merge of rust-lang#137171 - makai410:swapping-e0277, r=compiler-errors
Suggest swapping equality on E0277 Closes: rust-lang#132695 .
2 parents e6b3b88 + 9cd1de5 commit 3a92645

File tree

4 files changed

+88
-0
lines changed

4 files changed

+88
-0
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2419,6 +2419,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
24192419
&mut vec![],
24202420
&mut Default::default(),
24212421
);
2422+
self.suggest_swapping_lhs_and_rhs(
2423+
err,
2424+
obligation.predicate,
2425+
obligation.param_env,
2426+
obligation.cause.code(),
2427+
);
24222428
self.suggest_unsized_bound_if_applicable(err, obligation);
24232429
if let Some(span) = err.span.primary_span()
24242430
&& let Some(mut diag) =

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

+47
Original file line numberDiff line numberDiff line change
@@ -4914,6 +4914,53 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
49144914
);
49154915
true
49164916
}
4917+
pub(crate) fn suggest_swapping_lhs_and_rhs<T>(
4918+
&self,
4919+
err: &mut Diag<'_>,
4920+
predicate: T,
4921+
param_env: ty::ParamEnv<'tcx>,
4922+
cause_code: &ObligationCauseCode<'tcx>,
4923+
) where
4924+
T: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>,
4925+
{
4926+
let tcx = self.tcx;
4927+
let predicate = predicate.upcast(tcx);
4928+
match *cause_code {
4929+
ObligationCauseCode::BinOp {
4930+
lhs_hir_id,
4931+
rhs_hir_id: Some(rhs_hir_id),
4932+
rhs_span: Some(rhs_span),
4933+
..
4934+
} if let Some(typeck_results) = &self.typeck_results
4935+
&& let hir::Node::Expr(lhs) = tcx.hir_node(lhs_hir_id)
4936+
&& let hir::Node::Expr(rhs) = tcx.hir_node(rhs_hir_id)
4937+
&& let Some(lhs_ty) = typeck_results.expr_ty_opt(lhs)
4938+
&& let Some(rhs_ty) = typeck_results.expr_ty_opt(rhs) =>
4939+
{
4940+
if let Some(pred) = predicate.as_trait_clause()
4941+
&& tcx.is_lang_item(pred.def_id(), LangItem::PartialEq)
4942+
&& self
4943+
.infcx
4944+
.type_implements_trait(pred.def_id(), [rhs_ty, lhs_ty], param_env)
4945+
.must_apply_modulo_regions()
4946+
{
4947+
let lhs_span = tcx.hir().span(lhs_hir_id);
4948+
let sm = tcx.sess.source_map();
4949+
if let Ok(rhs_snippet) = sm.span_to_snippet(rhs_span)
4950+
&& let Ok(lhs_snippet) = sm.span_to_snippet(lhs_span)
4951+
{
4952+
err.note(format!("`{rhs_ty}` implements `PartialEq<{lhs_ty}>`"));
4953+
err.multipart_suggestion(
4954+
"consider swapping the equality",
4955+
vec![(lhs_span, rhs_snippet), (rhs_span, lhs_snippet)],
4956+
Applicability::MaybeIncorrect,
4957+
);
4958+
}
4959+
}
4960+
}
4961+
_ => {}
4962+
}
4963+
}
49174964
}
49184965

49194966
/// Add a hint to add a missing borrow or remove an unnecessary one.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
struct T(String);
2+
3+
impl PartialEq<String> for T {
4+
fn eq(&self, other: &String) -> bool {
5+
&self.0 == other
6+
}
7+
}
8+
9+
fn main() {
10+
String::from("Girls Band Cry") == T(String::from("Girls Band Cry")); //~ can't compare `String` with `T` [E0277]
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0277]: can't compare `String` with `T`
2+
--> $DIR/partialeq_suggest_swap_on_e0277.rs:10:36
3+
|
4+
LL | String::from("Girls Band Cry") == T(String::from("Girls Band Cry"));
5+
| ^^ no implementation for `String == T`
6+
|
7+
= help: the trait `PartialEq<T>` is not implemented for `String`
8+
= help: the following other types implement trait `PartialEq<Rhs>`:
9+
`String` implements `PartialEq<&str>`
10+
`String` implements `PartialEq<ByteStr>`
11+
`String` implements `PartialEq<ByteString>`
12+
`String` implements `PartialEq<Cow<'_, str>>`
13+
`String` implements `PartialEq<str>`
14+
`String` implements `PartialEq`
15+
= note: `T` implements `PartialEq<String>`
16+
help: consider swapping the equality
17+
|
18+
LL - String::from("Girls Band Cry") == T(String::from("Girls Band Cry"));
19+
LL + T(String::from("Girls Band Cry")) == String::from("Girls Band Cry");
20+
|
21+
22+
error: aborting due to 1 previous error
23+
24+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)