]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/check/method/suggest.rs
introduce PredicateAtom
[rust.git] / src / librustc_typeck / check / method / suggest.rs
index b9f1f8064c861062c253efc98188957f0e829fd9..07cc8332b84cfebb2ccf8bd972d735427324bf5d 100644 (file)
@@ -570,12 +570,16 @@ macro_rules! report_function {
                     };
                     let mut type_params = FxHashMap::default();
                     let mut bound_spans = vec![];
-                    let mut collect_type_param_suggestions =
-                        |self_ty: Ty<'_>, parent_pred: &ty::Predicate<'_>, obligation: &str| {
-                            if let (ty::Param(_), ty::PredicateKind::Trait(p, _)) =
-                                (&self_ty.kind, parent_pred.kind())
+
+                    let mut collect_type_param_suggestions = {
+                        // We need to move `tcx` while only borrowing the rest,
+                        // this is kind of ugly.
+                        |self_ty: Ty<'tcx>, parent_pred: &ty::Predicate<'tcx>, obligation: &str| {
+                            // We don't care about regions here, so it's fine to skip the binder here.
+                            if let (ty::Param(_), ty::PredicateAtom::Trait(p, _)) =
+                                (&self_ty.kind, parent_pred.skip_binders())
                             {
-                                if let ty::Adt(def, _) = p.skip_binder().trait_ref.self_ty().kind {
+                                if let ty::Adt(def, _) = p.trait_ref.self_ty().kind {
                                     let node = def.did.as_local().map(|def_id| {
                                         self.tcx.hir().get(self.tcx.hir().as_local_hir_id(def_id))
                                     });
@@ -597,7 +601,8 @@ macro_rules! report_function {
                                     }
                                 }
                             }
-                        };
+                        }
+                    };
                     let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
                         let msg = format!(
                             "doesn't satisfy `{}`",
@@ -625,8 +630,9 @@ macro_rules! report_function {
                         }
                     };
                     let mut format_pred = |pred: ty::Predicate<'tcx>| {
-                        match pred.kind() {
-                            ty::PredicateKind::Projection(pred) => {
+                        match pred.skip_binders() {
+                            ty::PredicateAtom::Projection(pred) => {
+                                let pred = ty::Binder::bind(pred);
                                 // `<Foo as Iterator>::Item = String`.
                                 let trait_ref =
                                     pred.skip_binder().projection_ty.trait_ref(self.tcx);
@@ -644,7 +650,8 @@ macro_rules! report_function {
                                 bound_span_label(trait_ref.self_ty(), &obligation, &quiet);
                                 Some((obligation, trait_ref.self_ty()))
                             }
-                            ty::PredicateKind::Trait(poly_trait_ref, _) => {
+                            ty::PredicateAtom::Trait(poly_trait_ref, _) => {
+                                let poly_trait_ref = ty::Binder::bind(poly_trait_ref);
                                 let p = poly_trait_ref.skip_binder().trait_ref;
                                 let self_ty = p.self_ty();
                                 let path = p.print_only_trait_path();
@@ -950,12 +957,16 @@ fn suggest_traits_to_import<'b>(
                 // this isn't perfect (that is, there are cases when
                 // implementing a trait would be legal but is rejected
                 // here).
-                unsatisfied_predicates.iter().all(|(p, _)| match p.kind() {
-                    // Hide traits if they are present in predicates as they can be fixed without
-                    // having to implement them.
-                    ty::PredicateKind::Trait(t, _) => t.def_id() == info.def_id,
-                    ty::PredicateKind::Projection(p) => p.item_def_id() == info.def_id,
-                    _ => false,
+                unsatisfied_predicates.iter().all(|(p, _)| {
+                    match p.skip_binders() {
+                        // Hide traits if they are present in predicates as they can be fixed without
+                        // having to implement them.
+                        ty::PredicateAtom::Trait(t, _) => t.def_id() == info.def_id,
+                        ty::PredicateAtom::Projection(p) => {
+                            p.projection_ty.item_def_id == info.def_id
+                        }
+                        _ => false,
+                    }
                 }) && (type_is_local || info.def_id.is_local())
                     && self
                         .associated_item(info.def_id, item_name, Namespace::ValueNS)