diff options
| author | Michael Goulet <michael@errs.io> | 2022-12-27 00:39:36 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-01-11 20:12:57 +0000 |
| commit | c8334ce60cce9571fcfdea31a3e67e3933fb7665 (patch) | |
| tree | 1f63730aeb8a6734ac3aaec57a44238e003a246b /compiler/rustc_trait_selection/src/traits | |
| parent | ef4046e4f3932991971cdb64915172899532aece (diff) | |
| download | rust-c8334ce60cce9571fcfdea31a3e67e3933fb7665.tar.gz rust-c8334ce60cce9571fcfdea31a3e67e3933fb7665.zip | |
Move autoderef to rustc_hir_analysis
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 43985495827..6c6696439c1 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -5,7 +5,6 @@ use super::{ PredicateObligation, }; -use crate::autoderef::Autoderef; use crate::infer::InferCtxt; use crate::traits::{NormalizeExt, ObligationCtxt}; @@ -750,26 +749,30 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } if let ty::Ref(region, base_ty, mutbl) = *real_ty.skip_binder().kind() { - let mut autoderef = Autoderef::new( - self, - obligation.param_env, - obligation.cause.body_id, - span, - base_ty, - ); - if let Some(steps) = autoderef.find_map(|(ty, steps)| { - // Re-add the `&` - let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl }); - - // Remapping bound vars here - let real_trait_pred_and_ty = - real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty)); - let obligation = self.mk_trait_obligation_with_new_self_ty( - obligation.param_env, - real_trait_pred_and_ty, - ); - Some(steps).filter(|_| self.predicate_may_hold(&obligation)) - }) { + let autoderef = (self.autoderef_steps)(base_ty); + if let Some(steps) = + autoderef.into_iter().enumerate().find_map(|(steps, (ty, obligations))| { + // Re-add the `&` + let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl }); + + // Remapping bound vars here + let real_trait_pred_and_ty = + real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty)); + let obligation = self.mk_trait_obligation_with_new_self_ty( + obligation.param_env, + real_trait_pred_and_ty, + ); + if obligations + .iter() + .chain([&obligation]) + .all(|obligation| self.predicate_may_hold(obligation)) + { + Some(steps) + } else { + None + } + }) + { if steps > 0 { // Don't care about `&mut` because `DerefMut` is used less // often and user will not expect autoderef happens. |
