Skip to content

Commit 3e15b92

Browse files
committed
Revert "Suggest dereferncing when possible in E0277, fix rust-lang#87437"
This reverts commit 883b93c.
1 parent 746c9b4 commit 3e15b92

File tree

7 files changed

+41
-121
lines changed

7 files changed

+41
-121
lines changed

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

+38-66
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::{
2-
DerivedObligationCause, EvaluationResult, ImplDerivedObligationCause, Obligation,
3-
ObligationCause, ObligationCauseCode, PredicateObligation, SelectionContext,
2+
EvaluationResult, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
3+
SelectionContext,
44
};
55

66
use crate::autoderef::Autoderef;
@@ -504,78 +504,50 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
504504
trait_pred: ty::PolyTraitPredicate<'tcx>,
505505
) -> bool {
506506
// It only make sense when suggesting dereferences for arguments
507-
let ObligationCauseCode::FunctionArgumentObligation { .. } = obligation.cause.code() else {
507+
let code = if let ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } =
508+
obligation.cause.code()
509+
{
510+
parent_code.clone()
511+
} else {
508512
return false;
509513
};
510514
let param_env = obligation.param_env;
511515
let body_id = obligation.cause.body_id;
512516
let span = obligation.cause.span;
513-
let mut real_trait_pred = trait_pred;
514-
let mut code = obligation.cause.code();
515-
loop {
516-
match &code {
517-
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => {
518-
code = &parent_code;
519-
}
520-
ObligationCauseCode::ImplDerivedObligation(box ImplDerivedObligationCause {
521-
derived: DerivedObligationCause { parent_code, parent_trait_pred },
522-
..
523-
})
524-
| ObligationCauseCode::BuiltinDerivedObligation(DerivedObligationCause {
525-
parent_code,
526-
parent_trait_pred,
527-
})
528-
| ObligationCauseCode::DerivedObligation(DerivedObligationCause {
529-
parent_code,
530-
parent_trait_pred,
531-
}) => {
532-
code = &parent_code;
533-
real_trait_pred = *parent_trait_pred;
534-
}
535-
_ => break,
536-
};
537-
let Some(real_ty) = real_trait_pred.self_ty().no_bound_vars() else {
538-
continue;
539-
};
517+
let real_trait_pred = match &*code {
518+
ObligationCauseCode::ImplDerivedObligation(cause) => cause.derived.parent_trait_pred,
519+
ObligationCauseCode::DerivedObligation(cause)
520+
| ObligationCauseCode::BuiltinDerivedObligation(cause) => cause.parent_trait_pred,
521+
_ => trait_pred,
522+
};
523+
let Some(real_ty) = real_trait_pred.self_ty().no_bound_vars() else {
524+
return false;
525+
};
540526

541-
if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() {
542-
let mut autoderef = Autoderef::new(self, param_env, body_id, span, base_ty, span);
543-
if let Some(steps) = autoderef.find_map(|(ty, steps)| {
544-
// Re-add the `&`
545-
let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl });
546-
let obligation =
547-
self.mk_trait_obligation_with_new_self_ty(param_env, real_trait_pred, ty);
548-
Some(steps).filter(|_| self.predicate_may_hold(&obligation))
549-
}) {
550-
if steps > 0 {
551-
if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(span) {
552-
// Don't care about `&mut` because `DerefMut` is used less
553-
// often and user will not expect autoderef happens.
554-
if src.starts_with('&') && !src.starts_with("&mut ") {
555-
let derefs = "*".repeat(steps);
556-
err.span_suggestion(
557-
span,
558-
"consider dereferencing here",
559-
format!("&{}{}", derefs, &src[1..]),
560-
Applicability::MachineApplicable,
561-
);
562-
return true;
563-
}
527+
if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() {
528+
let mut autoderef = Autoderef::new(self, param_env, body_id, span, base_ty, span);
529+
if let Some(steps) = autoderef.find_map(|(ty, steps)| {
530+
// Re-add the `&`
531+
let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl });
532+
let obligation =
533+
self.mk_trait_obligation_with_new_self_ty(param_env, real_trait_pred, ty);
534+
Some(steps).filter(|_| self.predicate_may_hold(&obligation))
535+
}) {
536+
if steps > 0 {
537+
if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(span) {
538+
// Don't care about `&mut` because `DerefMut` is used less
539+
// often and user will not expect autoderef happens.
540+
if src.starts_with('&') && !src.starts_with("&mut ") {
541+
let derefs = "*".repeat(steps);
542+
err.span_suggestion(
543+
span,
544+
"consider adding dereference here",
545+
format!("&{}{}", derefs, &src[1..]),
546+
Applicability::MachineApplicable,
547+
);
548+
return true;
564549
}
565550
}
566-
} else if real_trait_pred != trait_pred {
567-
// This branch addresses #87437.
568-
let obligation =
569-
self.mk_trait_obligation_with_new_self_ty(param_env, real_trait_pred, base_ty);
570-
if self.predicate_may_hold(&obligation) {
571-
err.span_suggestion_verbose(
572-
span.shrink_to_lo(),
573-
"consider dereferencing here",
574-
"*".to_string(),
575-
Applicability::MachineApplicable,
576-
);
577-
return true;
578-
}
579551
}
580552
}
581553
}

src/test/ui/traits/suggest-deferences/issue-39029.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | let _errors = TcpListener::bind(&bad);
55
| ----------------- ^^^^
66
| | |
77
| | the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs`
8-
| | help: consider dereferencing here: `&*bad`
8+
| | help: consider adding dereference here: `&*bad`
99
| required by a bound introduced by this call
1010
|
1111
= note: required because of the requirements on the impl of `ToSocketAddrs` for `&NoToSocketAddrs`

src/test/ui/traits/suggest-deferences/issue-62530.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | takes_type_parameter(&string); // Error
55
| -------------------- ^^^^^^^
66
| | |
77
| | the trait `SomeTrait` is not implemented for `&String`
8-
| | help: consider dereferencing here: `&*string`
8+
| | help: consider adding dereference here: `&*string`
99
| required by a bound introduced by this call
1010
|
1111
note: required by a bound in `takes_type_parameter`

src/test/ui/traits/suggest-deferences/multiple-0.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | foo(&baz);
55
| --- ^^^^
66
| | |
77
| | the trait `Happy` is not implemented for `&Baz`
8-
| | help: consider dereferencing here: `&***baz`
8+
| | help: consider adding dereference here: `&***baz`
99
| required by a bound introduced by this call
1010
|
1111
note: required by a bound in `foo`

src/test/ui/traits/suggest-deferences/root-obligation.fixed

-14
This file was deleted.

src/test/ui/traits/suggest-deferences/root-obligation.rs

-14
This file was deleted.

src/test/ui/traits/suggest-deferences/root-obligation.stderr

-24
This file was deleted.

0 commit comments

Comments
 (0)