Skip to content

Commit bf93a77

Browse files
committed
Also suggest removing borrows
1 parent a3c7f62 commit bf93a77

File tree

1 file changed

+61
-40
lines changed
  • compiler/rustc_trait_selection/src/traits/error_reporting

1 file changed

+61
-40
lines changed

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

+61-40
Original file line numberDiff line numberDiff line change
@@ -838,57 +838,78 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
838838
}
839839
}
840840
}
841-
} else if let (ObligationCauseCode::BinOp { lhs_hir_id, .. }, predicate) =
841+
} else if let (ObligationCauseCode::BinOp { lhs_hir_id, rhs_hir_id: Some(_rhs_hir_id), .. }, predicate) =
842842
code.peel_derives_with_predicate()
843843
&& let hir::Node::Expr(lhs) = self.tcx.hir().get(*lhs_hir_id)
844844
{
845845
let trait_pred = predicate.unwrap_or(trait_pred);
846846
let lhs_ty = self.tcx.instantiate_bound_regions_with_erased(trait_pred.self_ty());
847-
if let ty::Ref(..) = *lhs_ty.kind() {
848-
let lhs_autoderef = (self.autoderef_steps)(lhs_ty);
849-
if let Some(steps) =
850-
lhs_autoderef.into_iter().enumerate().find_map(|(steps, (ty, obligations))| {
851-
// Remapping bound vars here
852-
let trait_pred_and_ty =
853-
trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty));
854-
let obligation = self.mk_trait_obligation_with_new_self_ty(
855-
obligation.param_env,
856-
trait_pred_and_ty,
857-
);
847+
let lhs_autoderef = (self.autoderef_steps)(lhs_ty);
848+
if let Some(mut steps) =
849+
lhs_autoderef.into_iter().enumerate().find_map(|(steps, (ty, obligations))| {
850+
// Remapping bound vars here
851+
let trait_pred_and_ty =
852+
trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty));
853+
let obligation = self.mk_trait_obligation_with_new_self_ty(
854+
obligation.param_env,
855+
trait_pred_and_ty,
856+
);
858857

859-
let may_hold = obligations
860-
.iter()
861-
.chain([&obligation])
862-
.all(|obligation| self.predicate_may_hold(obligation))
863-
.then_some(steps);
858+
let may_hold = obligations
859+
.iter()
860+
.chain([&obligation])
861+
.all(|obligation| self.predicate_may_hold(obligation))
862+
.then_some(steps);
864863

865-
may_hold
866-
})
867-
{
868-
if steps > 0 {
869-
// Suggest `&&**` rather than `**&&`
870-
let span = lhs.peel_borrows().span;
871-
let derefs = "*".repeat(steps);
872-
let needs_parens = match lhs.kind {
864+
may_hold
865+
})
866+
{
867+
if steps > 0 {
868+
// Suggest `&*` rather than `*&`
869+
let span = lhs.peel_borrows().span;
870+
871+
let mut lhs = lhs;
872+
let mut prefix_span = lhs.span.shrink_to_lo();
873+
let mut msg = "consider dereferencing here";
874+
if let hir::ExprKind::AddrOf(_, _, inner) = lhs.kind {
875+
msg = "consider removing the borrow and dereferencing instead";
876+
if let hir::ExprKind::AddrOf(..) = inner.kind {
877+
msg = "consider removing the borrows and dereferencing instead";
878+
}
879+
}
880+
while let hir::ExprKind::AddrOf(_, _, inner) = lhs.kind
881+
&& steps > 0
882+
{
883+
prefix_span = prefix_span.with_hi(inner.span.lo());
884+
lhs = inner;
885+
steps -= 1;
886+
}
887+
if steps == 0 {
888+
msg = msg.trim_end_matches(" and dereferencing instead");
889+
}
890+
891+
let derefs = "*".repeat(steps);
892+
let needs_parens = steps > 0
893+
&& match lhs.kind {
873894
hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
874895
_ if is_range_literal(lhs) => true,
875896
_ => false,
876897
};
877-
let suggestion = if needs_parens {
878-
vec![
879-
(span.shrink_to_lo(), format!("{derefs}(")),
880-
(span.shrink_to_hi(), ")".to_string()),
881-
]
882-
} else {
883-
vec![(span.shrink_to_lo(), format!("{derefs}"))]
884-
};
885-
err.multipart_suggestion_verbose(
886-
"consider dereferencing here",
887-
suggestion,
888-
Applicability::MachineApplicable,
889-
);
890-
return true;
891-
}
898+
let mut suggestion = if needs_parens {
899+
vec![
900+
(span.shrink_to_lo(), format!("{derefs}(")),
901+
(span.shrink_to_hi(), ")".to_string()),
902+
]
903+
} else {
904+
vec![(span.shrink_to_lo(), format!("{derefs}"))]
905+
};
906+
suggestion.push((prefix_span, "".to_string()));
907+
err.multipart_suggestion_verbose(
908+
msg,
909+
suggestion,
910+
Applicability::MachineApplicable,
911+
);
912+
return true;
892913
}
893914
}
894915
}

0 commit comments

Comments
 (0)