about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2023-03-30 13:18:44 +0200
committerLukas Wirth <lukastw97@gmail.com>2023-03-30 13:27:10 +0200
commitfc840dbb2de83f2fd41dffbef2896196f84f4259 (patch)
tree548783b8a009dc7aeb63a185cf08b77b73a0e28f
parentb915eb32fafd465ed02b27f1ba03c2d9b35dc87d (diff)
downloadrust-fc840dbb2de83f2fd41dffbef2896196f84f4259.tar.gz
rust-fc840dbb2de83f2fd41dffbef2896196f84f4259.zip
internal: Don't expose InferenceTable outside of hir-ty
-rw-r--r--crates/hir-ty/src/autoderef.rs28
-rw-r--r--crates/hir-ty/src/infer/expr.rs10
-rw-r--r--crates/hir-ty/src/infer/unify.rs12
-rw-r--r--crates/hir-ty/src/lib.rs10
-rw-r--r--crates/hir-ty/src/method_resolution.rs7
-rw-r--r--crates/hir/src/lib.rs19
6 files changed, 49 insertions, 37 deletions
diff --git a/crates/hir-ty/src/autoderef.rs b/crates/hir-ty/src/autoderef.rs
index c749bf570c3..af9070fd292 100644
--- a/crates/hir-ty/src/autoderef.rs
+++ b/crates/hir-ty/src/autoderef.rs
@@ -3,6 +3,8 @@
 //! reference to a type with the field `bar`. This is an approximation of the
 //! logic in rustc (which lives in rustc_hir_analysis/check/autoderef.rs).
 
+use std::sync::Arc;
+
 use chalk_ir::cast::Cast;
 use hir_def::{
     lang_item::{LangItem, LangItemTarget},
@@ -11,7 +13,10 @@ use hir_def::{
 use hir_expand::name::name;
 use limit::Limit;
 
-use crate::{infer::unify::InferenceTable, Goal, Interner, ProjectionTyExt, Ty, TyBuilder, TyKind};
+use crate::{
+    db::HirDatabase, infer::unify::InferenceTable, Canonical, Goal, Interner, ProjectionTyExt,
+    TraitEnvironment, Ty, TyBuilder, TyKind,
+};
 
 static AUTODEREF_RECURSION_LIMIT: Limit = Limit::new(10);
 
@@ -21,16 +26,31 @@ pub(crate) enum AutoderefKind {
     Overloaded,
 }
 
+pub fn autoderef(
+    db: &dyn HirDatabase,
+    env: Arc<TraitEnvironment>,
+    ty: Canonical<Ty>,
+) -> impl Iterator<Item = Canonical<Ty>> + '_ {
+    let mut table = InferenceTable::new(db, env);
+    let ty = table.instantiate_canonical(ty);
+    let mut autoderef = Autoderef::new(&mut table, ty);
+    let mut v = Vec::new();
+    while let Some((ty, _steps)) = autoderef.next() {
+        v.push(autoderef.table.canonicalize(ty).value);
+    }
+    v.into_iter()
+}
+
 #[derive(Debug)]
-pub struct Autoderef<'a, 'db> {
-    pub table: &'a mut InferenceTable<'db>,
+pub(crate) struct Autoderef<'a, 'db> {
+    pub(crate) table: &'a mut InferenceTable<'db>,
     ty: Ty,
     at_start: bool,
     steps: Vec<(AutoderefKind, Ty)>,
 }
 
 impl<'a, 'db> Autoderef<'a, 'db> {
-    pub fn new(table: &'a mut InferenceTable<'db>, ty: Ty) -> Self {
+    pub(crate) fn new(table: &'a mut InferenceTable<'db>, ty: Ty) -> Self {
         let ty = table.resolve_ty_shallow(&ty);
         Autoderef { table, ty, at_start: true, steps: Vec::new() }
     }
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 73f3ba1e320..38a09953027 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -23,7 +23,7 @@ use stdx::always;
 use syntax::ast::RangeOp;
 
 use crate::{
-    autoderef::{self, Autoderef},
+    autoderef::{builtin_deref, deref_by_trait, Autoderef},
     consteval,
     infer::{
         coerce::CoerceMany, find_continuable, pat::contains_explicit_ref_binding, BreakableKind,
@@ -675,12 +675,10 @@ impl<'a> InferenceContext<'a> {
                                 );
                             }
                         }
-                        if let Some(derefed) =
-                            autoderef::builtin_deref(&mut self.table, &inner_ty, true)
-                        {
+                        if let Some(derefed) = builtin_deref(&mut self.table, &inner_ty, true) {
                             self.resolve_ty_shallow(derefed)
                         } else {
-                            autoderef::deref_by_trait(&mut self.table, inner_ty)
+                            deref_by_trait(&mut self.table, inner_ty)
                                 .unwrap_or_else(|| self.err_ty())
                         }
                     }
@@ -793,7 +791,7 @@ impl<'a> InferenceContext<'a> {
                     let canonicalized = self.canonicalize(base_ty.clone());
                     let receiver_adjustments = method_resolution::resolve_indexing_op(
                         self.db,
-                        &mut self.table,
+                        self.table.trait_env.clone(),
                         canonicalized.value,
                         index_trait,
                     );
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs
index b3428938e0d..f0e0714e1db 100644
--- a/crates/hir-ty/src/infer/unify.rs
+++ b/crates/hir-ty/src/infer/unify.rs
@@ -32,11 +32,11 @@ impl<'a> InferenceContext<'a> {
 }
 
 #[derive(Debug, Clone)]
-pub struct Canonicalized<T>
+pub(crate) struct Canonicalized<T>
 where
     T: HasInterner<Interner = Interner>,
 {
-    pub value: Canonical<T>,
+    pub(crate) value: Canonical<T>,
     free_vars: Vec<GenericArg>,
 }
 
@@ -140,7 +140,7 @@ bitflags::bitflags! {
 type ChalkInferenceTable = chalk_solve::infer::InferenceTable<Interner>;
 
 #[derive(Clone)]
-pub struct InferenceTable<'a> {
+pub(crate) struct InferenceTable<'a> {
     pub(crate) db: &'a dyn HirDatabase,
     pub(crate) trait_env: Arc<TraitEnvironment>,
     var_unification_table: ChalkInferenceTable,
@@ -155,7 +155,7 @@ pub(crate) struct InferenceTableSnapshot {
 }
 
 impl<'a> InferenceTable<'a> {
-    pub fn new(db: &'a dyn HirDatabase, trait_env: Arc<TraitEnvironment>) -> Self {
+    pub(crate) fn new(db: &'a dyn HirDatabase, trait_env: Arc<TraitEnvironment>) -> Self {
         InferenceTable {
             db,
             trait_env,
@@ -204,7 +204,7 @@ impl<'a> InferenceTable<'a> {
         .intern(Interner)
     }
 
-    pub fn canonicalize<T: TypeFoldable<Interner> + HasInterner<Interner = Interner>>(
+    pub(crate) fn canonicalize<T: TypeFoldable<Interner> + HasInterner<Interner = Interner>>(
         &mut self,
         t: T,
     ) -> Canonicalized<T>
@@ -320,7 +320,7 @@ impl<'a> InferenceTable<'a> {
         )
     }
 
-    pub fn instantiate_canonical<T>(&mut self, canonical: Canonical<T>) -> T
+    pub(crate) fn instantiate_canonical<T>(&mut self, canonical: Canonical<T>) -> T
     where
         T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + std::fmt::Debug,
     {
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index 1cab32e958c..c36fad614f8 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/crates/hir-ty/src/lib.rs
@@ -52,14 +52,16 @@ use rustc_hash::FxHashSet;
 use traits::FnTrait;
 use utils::Generics;
 
-use crate::{consteval::unknown_const, db::HirDatabase, utils::generics};
+use crate::{
+    consteval::unknown_const, db::HirDatabase, infer::unify::InferenceTable, utils::generics,
+};
 
-pub use autoderef::Autoderef;
+pub use autoderef::autoderef;
 pub use builder::{ParamKind, TyBuilder};
 pub use chalk_ext::*;
 pub use infer::{
-    could_coerce, could_unify, unify::InferenceTable, Adjust, Adjustment, AutoBorrow, BindingMode,
-    InferenceDiagnostic, InferenceResult, OverloadedDeref, PointerCast,
+    could_coerce, could_unify, Adjust, Adjustment, AutoBorrow, BindingMode, InferenceDiagnostic,
+    InferenceResult, OverloadedDeref, PointerCast,
 };
 pub use interner::Interner;
 pub use lower::{
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index e08c44f0a04..7a29a51506f 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -1258,14 +1258,15 @@ fn iterate_inherent_methods(
 }
 
 /// Returns the receiver type for the index trait call.
-pub fn resolve_indexing_op(
+pub(crate) fn resolve_indexing_op(
     db: &dyn HirDatabase,
-    table: &mut InferenceTable<'_>,
+    env: Arc<TraitEnvironment>,
     ty: Canonical<Ty>,
     index_trait: TraitId,
 ) -> Option<ReceiverAdjustments> {
+    let mut table = InferenceTable::new(db, env.clone());
     let ty = table.instantiate_canonical(ty);
-    let deref_chain = autoderef_method_receiver(table, ty);
+    let deref_chain = autoderef_method_receiver(&mut table, ty);
     for (ty, adj) in deref_chain {
         let goal = generic_implements_goal(db, table.trait_env.clone(), index_trait, &ty);
         if db
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 5cad8315874..648ae00a5fa 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -57,7 +57,7 @@ use hir_def::{
 };
 use hir_expand::{name::name, MacroCallKind};
 use hir_ty::{
-    all_super_traits,
+    all_super_traits, autoderef,
     consteval::{try_const_usize, unknown_const_as_generic, ConstEvalError, ConstExt},
     diagnostics::BodyValidationDiagnostic,
     display::HexifiedConst,
@@ -66,10 +66,9 @@ use hir_ty::{
     mir::{self, interpret_mir},
     primitive::UintTy,
     traits::FnTrait,
-    AliasTy, Autoderef, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId,
-    GenericArgData, InferenceTable, Interner, ParamKind, QuantifiedWhereClause, Scalar,
-    Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind,
-    WhereClause,
+    AliasTy, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId,
+    GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar, Substitution,
+    TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, WhereClause,
 };
 use itertools::Itertools;
 use nameres::diagnostics::DefDiagnosticKind;
@@ -3518,15 +3517,7 @@ impl Type {
     fn autoderef_<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Ty> + 'a {
         // There should be no inference vars in types passed here
         let canonical = hir_ty::replace_errors_with_variables(&self.ty);
-
-        let mut table = InferenceTable::new(db, self.env.clone());
-        let ty = table.instantiate_canonical(canonical);
-        let mut autoderef = Autoderef::new(&mut table, ty);
-        let mut v = Vec::new();
-        while let Some((ty, _steps)) = autoderef.next() {
-            v.push(autoderef.table.canonicalize(ty).value);
-        }
-        v.into_iter().map(|canonical| canonical.value)
+        autoderef(db, self.env.clone(), canonical).map(|canonical| canonical.value)
     }
 
     // This would be nicer if it just returned an iterator, but that runs into