Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/unify.rs')
| -rw-r--r-- | crates/hir-ty/src/infer/unify.rs | 67 |
1 files changed, 19 insertions, 48 deletions
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs index a18cdda559..0f582a1c23 100644 --- a/crates/hir-ty/src/infer/unify.rs +++ b/crates/hir-ty/src/infer/unify.rs @@ -2,10 +2,10 @@ use std::fmt; -use hir_def::{AdtId, GenericParamId, lang_item::LangItem}; +use hir_def::{AdtId, DefWithBodyId, GenericParamId, lang_item::LangItem}; use hir_expand::name::Name; use intern::sym; -use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_hash::FxHashSet; use rustc_type_ir::{ DebruijnIndex, InferConst, InferTy, RegionVid, TyVid, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UpcastFrom, @@ -17,12 +17,12 @@ use triomphe::Arc; use crate::{ TraitEnvironment, - db::{HirDatabase, InternedOpaqueTyId}, + db::HirDatabase, infer::InferenceContext, next_solver::{ self, AliasTy, Binder, Canonical, ClauseKind, Const, ConstKind, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, Predicate, PredicateKind, Region, RegionKind, - SolverDefId, SolverDefIds, TraitRef, Ty, TyKind, TypingMode, + SolverDefId, TraitRef, Ty, TyKind, TypingMode, fulfill::{FulfillmentCtxt, NextSolverError}, infer::{ DbInternerInferExt, InferCtxt, InferOk, InferResult, @@ -139,10 +139,7 @@ fn could_unify_impl<'db>( select: for<'a> fn(&mut ObligationCtxt<'a, 'db>) -> Vec<NextSolverError<'db>>, ) -> bool { let interner = DbInterner::new_with(db, Some(env.krate), env.block); - // FIXME(next-solver): I believe this should use `PostAnalysis` (this is only used for IDE things), - // but this causes some bug because of our incorrect impl of `type_of_opaque_hir_typeck()` for TAIT - // and async blocks. - let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); + let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); let cause = ObligationCause::dummy(); let at = infcx.at(&cause, env.env); let ((ty1_with_vars, ty2_with_vars), _) = infcx.instantiate_canonical(tys); @@ -158,7 +155,6 @@ fn could_unify_impl<'db>( pub(crate) struct InferenceTable<'db> { pub(crate) db: &'db dyn HirDatabase, pub(crate) trait_env: Arc<TraitEnvironment<'db>>, - pub(crate) tait_coercion_table: Option<FxHashMap<InternedOpaqueTyId, Ty<'db>>>, pub(crate) infer_ctxt: InferCtxt<'db>, pub(super) fulfillment_cx: FulfillmentCtxt<'db>, pub(super) diverging_type_vars: FxHashSet<Ty<'db>>, @@ -170,15 +166,23 @@ pub(crate) struct InferenceTableSnapshot<'db> { } impl<'db> InferenceTable<'db> { - pub(crate) fn new(db: &'db dyn HirDatabase, trait_env: Arc<TraitEnvironment<'db>>) -> Self { + /// Inside hir-ty you should use this for inference only, and always pass `owner`. + /// Outside it, always pass `owner = None`. + pub(crate) fn new( + db: &'db dyn HirDatabase, + trait_env: Arc<TraitEnvironment<'db>>, + owner: Option<DefWithBodyId>, + ) -> Self { let interner = DbInterner::new_with(db, Some(trait_env.krate), trait_env.block); - let infer_ctxt = interner.infer_ctxt().build(rustc_type_ir::TypingMode::Analysis { - defining_opaque_types_and_generators: SolverDefIds::new_from_iter(interner, []), - }); + let typing_mode = match owner { + Some(owner) => TypingMode::typeck_for_body(interner, owner.into()), + // IDE things wants to reveal opaque types. + None => TypingMode::PostAnalysis, + }; + let infer_ctxt = interner.infer_ctxt().build(typing_mode); InferenceTable { db, trait_env, - tait_coercion_table: None, fulfillment_cx: FulfillmentCtxt::new(&infer_ctxt), infer_ctxt, diverging_type_vars: FxHashSet::default(), @@ -698,40 +702,7 @@ impl<'db> InferenceTable<'db> { where T: TypeFoldable<DbInterner<'db>>, { - struct Folder<'a, 'db> { - table: &'a mut InferenceTable<'db>, - } - impl<'db> TypeFolder<DbInterner<'db>> for Folder<'_, 'db> { - fn cx(&self) -> DbInterner<'db> { - self.table.interner() - } - - fn fold_ty(&mut self, ty: Ty<'db>) -> Ty<'db> { - if !ty.references_error() { - return ty; - } - - if ty.is_ty_error() { self.table.next_ty_var() } else { ty.super_fold_with(self) } - } - - fn fold_const(&mut self, ct: Const<'db>) -> Const<'db> { - if !ct.references_error() { - return ct; - } - - if ct.is_ct_error() { - self.table.next_const_var() - } else { - ct.super_fold_with(self) - } - } - - fn fold_region(&mut self, r: Region<'db>) -> Region<'db> { - if r.is_error() { self.table.next_region_var() } else { r } - } - } - - ty.fold_with(&mut Folder { table: self }) + self.infer_ctxt.insert_type_vars(ty) } /// Replaces `Ty::Error` by a new type var, so we can maybe still infer it. |