From fc840dbb2de83f2fd41dffbef2896196f84f4259 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 30 Mar 2023 13:18:44 +0200 Subject: [PATCH] internal: Don't expose InferenceTable outside of hir-ty --- crates/hir-ty/src/autoderef.rs | 28 ++++++++++++++++++++++---- crates/hir-ty/src/infer/expr.rs | 10 ++++----- crates/hir-ty/src/infer/unify.rs | 12 +++++------ crates/hir-ty/src/lib.rs | 10 +++++---- crates/hir-ty/src/method_resolution.rs | 7 ++++--- crates/hir/src/lib.rs | 19 +++++------------ 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, + ty: Canonical, +) -> impl Iterator> + '_ { + 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 +pub(crate) struct Canonicalized where T: HasInterner, { - pub value: Canonical, + pub(crate) value: Canonical, free_vars: Vec, } @@ -140,7 +140,7 @@ bitflags::bitflags! { type ChalkInferenceTable = chalk_solve::infer::InferenceTable; #[derive(Clone)] -pub struct InferenceTable<'a> { +pub(crate) struct InferenceTable<'a> { pub(crate) db: &'a dyn HirDatabase, pub(crate) trait_env: Arc, 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) -> Self { + pub(crate) fn new(db: &'a dyn HirDatabase, trait_env: Arc) -> Self { InferenceTable { db, trait_env, @@ -204,7 +204,7 @@ impl<'a> InferenceTable<'a> { .intern(Interner) } - pub fn canonicalize + HasInterner>( + pub(crate) fn canonicalize + HasInterner>( &mut self, t: T, ) -> Canonicalized @@ -320,7 +320,7 @@ impl<'a> InferenceTable<'a> { ) } - pub fn instantiate_canonical(&mut self, canonical: Canonical) -> T + pub(crate) fn instantiate_canonical(&mut self, canonical: Canonical) -> T where T: HasInterner + TypeFoldable + 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, ty: Canonical, index_trait: TraitId, ) -> Option { + 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 + '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