]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_hir_typeck/src/method/probe.rs
Rollup merge of #105343 - nbdd0121:hir, r=fee1-dead
[rust.git] / compiler / rustc_hir_typeck / src / method / probe.rs
index 4380e66a0d248221be4b3d7b896270c259ec2b94..ae299cc9d13706d1402600eef7c2a61328144f87 100644 (file)
@@ -9,7 +9,6 @@
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
-use rustc_hir::def::Namespace;
 use rustc_infer::infer::canonical::OriginalQueryValues;
 use rustc_infer::infer::canonical::{Canonical, QueryResponse};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_span::symbol::sym;
 use rustc_span::{symbol::Ident, Span, Symbol, DUMMY_SP};
 use rustc_trait_selection::autoderef::{self, Autoderef};
-use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use rustc_trait_selection::traits::query::method_autoderef::MethodAutoderefBadTy;
 use rustc_trait_selection::traits::query::method_autoderef::{
     CandidateStep, MethodAutoderefStepsResult,
 };
 use rustc_trait_selection::traits::query::CanonicalTyGoal;
+use rustc_trait_selection::traits::NormalizeExt;
 use rustc_trait_selection::traits::{self, ObligationCause};
 use std::cmp::max;
 use std::iter;
@@ -716,9 +715,8 @@ fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId) {
             // maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized,
             // see issue #89650
             let cause = traits::ObligationCause::misc(self.span, self.body_id);
-            let InferOk { value: xform_self_ty, obligations } = self
-                .fcx
-                .partially_normalize_associated_types_in(cause, self.param_env, xform_self_ty);
+            let InferOk { value: xform_self_ty, obligations } =
+                self.fcx.at(&cause, self.param_env).normalize(xform_self_ty);
 
             debug!(
                 "assemble_inherent_impl_probe after normalization: xform_self_ty = {:?}/{:?}",
@@ -1507,11 +1505,7 @@ fn consider_probe(
                     let InferOk {
                         value: normalized_xform_ret_ty,
                         obligations: normalization_obligations,
-                    } = self.fcx.partially_normalize_associated_types_in(
-                        cause.clone(),
-                        self.param_env,
-                        probe.xform_ret_ty,
-                    );
+                    } = self.fcx.at(&cause, self.param_env).normalize(probe.xform_ret_ty);
                     xform_ret_ty = normalized_xform_ret_ty;
                     debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty);
 
@@ -1521,11 +1515,7 @@ fn consider_probe(
                     let impl_bounds = impl_bounds.instantiate(self.tcx, substs);
 
                     let InferOk { value: impl_bounds, obligations: norm_obligations } =
-                        self.fcx.partially_normalize_associated_types_in(
-                            cause.clone(),
-                            self.param_env,
-                            impl_bounds,
-                        );
+                        self.fcx.at(&cause, self.param_env).normalize(impl_bounds);
 
                     // Convert the bounds into obligations.
                     let impl_obligations = traits::predicates_for_generics(
@@ -1885,6 +1875,15 @@ fn erase_late_bound_regions<T>(&self, value: ty::Binder<'tcx, T>) -> T
         self.tcx.erase_late_bound_regions(value)
     }
 
+    /// Determine if the given associated item type is relevant in the current context.
+    fn is_relevant_kind_for_mode(&self, kind: ty::AssocKind) -> bool {
+        match (self.mode, kind) {
+            (Mode::MethodCall, ty::AssocKind::Fn) => true,
+            (Mode::Path, ty::AssocKind::Const | ty::AssocKind::Fn) => true,
+            _ => false,
+        }
+    }
+
     /// Finds the method with the appropriate name (or return type, as the case may be). If
     /// `allow_similar_names` is set, find methods with close-matching names.
     // The length of the returned iterator is nearly always 0 or 1 and this
@@ -1897,7 +1896,7 @@ fn erase_late_bound_regions<T>(&self, value: ty::Binder<'tcx, T>) -> T
                     .associated_items(def_id)
                     .in_definition_order()
                     .filter(|x| {
-                        if x.kind.namespace() != Namespace::ValueNS {
+                        if !self.is_relevant_kind_for_mode(x.kind) {
                             return false;
                         }
                         match lev_distance_with_substrings(name.as_str(), x.name.as_str(), max_dist)
@@ -1911,10 +1910,16 @@ fn erase_late_bound_regions<T>(&self, value: ty::Binder<'tcx, T>) -> T
             } else {
                 self.fcx
                     .associated_value(def_id, name)
+                    .filter(|x| self.is_relevant_kind_for_mode(x.kind))
                     .map_or_else(SmallVec::new, |x| SmallVec::from_buf([x]))
             }
         } else {
-            self.tcx.associated_items(def_id).in_definition_order().copied().collect()
+            self.tcx
+                .associated_items(def_id)
+                .in_definition_order()
+                .filter(|x| self.is_relevant_kind_for_mode(x.kind))
+                .copied()
+                .collect()
         }
     }
 }