Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/method_resolution.rs')
| -rw-r--r-- | crates/hir-ty/src/method_resolution.rs | 740 |
1 files changed, 319 insertions, 421 deletions
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index 61d3091a0c..086abc9591 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -8,39 +8,42 @@ use arrayvec::ArrayVec; use base_db::Crate; use chalk_ir::{UniverseIndex, WithKind, cast::Cast}; use hir_def::{ - AssocItemId, BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup, - ModuleId, TraitId, + AdtId, AssocItemId, BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup, + ModuleId, TraitId, TypeAliasId, nameres::{DefMap, assoc::ImplItems, block_def_map, crate_def_map}, signatures::{ConstFlags, EnumFlags, FnFlags, StructFlags, TraitFlags, TypeAliasFlags}, }; use hir_expand::name::Name; use intern::sym; +use rustc_ast_ir::Mutability; use rustc_hash::{FxHashMap, FxHashSet}; -use rustc_type_ir::inherent::{IntoKind, SliceLike, Ty as _}; +use rustc_type_ir::{ + FloatTy, IntTy, UintTy, + inherent::{ + AdtDef, BoundExistentialPredicates, GenericArgs as _, IntoKind, SliceLike, Ty as _, + }, +}; use smallvec::{SmallVec, smallvec}; use stdx::never; use triomphe::Arc; use crate::{ - AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, GenericArgData, - Goal, InEnvironment, Interner, Mutability, Scalar, Substitution, TraitEnvironment, TraitRef, - TraitRefExt, Ty, TyBuilder, TyExt, TyKind, VariableKind, WhereClause, + CanonicalVarKinds, DebruijnIndex, GenericArgData, InEnvironment, Interner, TraitEnvironment, + TyBuilder, VariableKind, autoderef::{self, AutoderefKind}, db::HirDatabase, - from_chalk_trait_id, from_foreign_def_id, infer::{Adjust, Adjustment, OverloadedDeref, PointerCast, unify::InferenceTable}, lang_items::is_box, next_solver::{ - self, DbInterner, SolverDefId, + Canonical, DbInterner, ErrorGuaranteed, GenericArgs, Goal, Predicate, Region, SolverDefId, + TraitRef, Ty, TyKind, infer::{ DefineOpaqueTypes, traits::{ObligationCause, PredicateObligation}, }, - mapping::{ChalkToNextSolver, NextSolverToChalk}, + mapping::NextSolverToChalk, obligation_ctxt::ObligationCtxt, }, - primitive::{FloatTy, IntTy, UintTy}, - to_chalk_trait_id, traits::next_trait_solve_canonical_in_ctxt, utils::all_super_traits, }; @@ -55,11 +58,15 @@ pub enum TyFingerprint { Never, Ref(Mutability), RawPtr(Mutability), - Scalar(Scalar), + Bool, + Char, + Int(IntTy), + Uint(UintTy), + Float(FloatTy), // These can have user-defined impls: Adt(hir_def::AdtId), Dyn(TraitId), - ForeignType(ForeignDefId), + ForeignType(TypeAliasId), // These only exist for trait impls Unit, Unnameable, @@ -71,140 +78,73 @@ impl TyFingerprint { /// types can have inherent impls: if we have some `struct S`, we can have /// an `impl S`, but not `impl &S`. Hence, this will return `None` for /// reference types and such. - pub fn for_inherent_impl(ty: &Ty) -> Option<TyFingerprint> { - let fp = match ty.kind(Interner) { + pub fn for_inherent_impl<'db>(ty: Ty<'db>) -> Option<TyFingerprint> { + let fp = match ty.kind() { TyKind::Str => TyFingerprint::Str, TyKind::Never => TyFingerprint::Never, TyKind::Slice(..) => TyFingerprint::Slice, TyKind::Array(..) => TyFingerprint::Array, - TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar), - TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt), - TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability), - TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id), - TyKind::Dyn(_) => ty.dyn_trait().map(TyFingerprint::Dyn)?, + TyKind::Bool => TyFingerprint::Bool, + TyKind::Char => TyFingerprint::Char, + TyKind::Int(int) => TyFingerprint::Int(int), + TyKind::Uint(int) => TyFingerprint::Uint(int), + TyKind::Float(float) => TyFingerprint::Float(float), + TyKind::Adt(adt_def, _) => TyFingerprint::Adt(adt_def.def_id().0), + TyKind::RawPtr(_, mutability) => TyFingerprint::RawPtr(mutability), + TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(alias_id.0), + TyKind::Dynamic(bounds, _) => { + bounds.principal_def_id().map(|trait_| TyFingerprint::Dyn(trait_.0))? + } _ => return None, }; Some(fp) } /// Creates a TyFingerprint for looking up a trait impl. - pub fn for_trait_impl(ty: &Ty) -> Option<TyFingerprint> { - let fp = match ty.kind(Interner) { + pub fn for_trait_impl<'db>(ty: Ty<'db>) -> Option<TyFingerprint> { + let fp = match ty.kind() { TyKind::Str => TyFingerprint::Str, TyKind::Never => TyFingerprint::Never, TyKind::Slice(..) => TyFingerprint::Slice, TyKind::Array(..) => TyFingerprint::Array, - TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar), - TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt), - TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability), - TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id), - TyKind::Dyn(_) => ty.dyn_trait().map(TyFingerprint::Dyn)?, - TyKind::Ref(mutability, _, _) => TyFingerprint::Ref(*mutability), - TyKind::Tuple(_, subst) => { - let first_ty = subst.interned().first().map(|arg| arg.assert_ty_ref(Interner)); + TyKind::Bool => TyFingerprint::Bool, + TyKind::Char => TyFingerprint::Char, + TyKind::Int(int) => TyFingerprint::Int(int), + TyKind::Uint(int) => TyFingerprint::Uint(int), + TyKind::Float(float) => TyFingerprint::Float(float), + TyKind::Adt(adt_def, _) => TyFingerprint::Adt(adt_def.def_id().0), + TyKind::RawPtr(_, mutability) => TyFingerprint::RawPtr(mutability), + TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(alias_id.0), + TyKind::Dynamic(bounds, _) => { + bounds.principal_def_id().map(|trait_| TyFingerprint::Dyn(trait_.0))? + } + TyKind::Ref(_, _, mutability) => TyFingerprint::Ref(mutability), + TyKind::Tuple(subst) => { + let first_ty = subst.as_slice().first(); match first_ty { - Some(ty) => return TyFingerprint::for_trait_impl(ty), + Some(ty) => return TyFingerprint::for_trait_impl(*ty), None => TyFingerprint::Unit, } } - TyKind::AssociatedType(_, _) // FIXME(next-solver): Putting `Alias` here is *probably* incorrect, AFAIK it should return `None`. But this breaks // flyimport, which uses an incorrect but fast method resolution algorithm. Therefore we put it here, // because this function is only called by flyimport, and anyway we should get rid of `TyFingerprint` // and switch to `rustc_type_ir`'s `SimplifiedType`. - | TyKind::Alias(_) - | TyKind::OpaqueType(_, _) + TyKind::Alias(..) | TyKind::FnDef(_, _) | TyKind::Closure(_, _) | TyKind::Coroutine(..) + | TyKind::CoroutineClosure(..) | TyKind::CoroutineWitness(..) => TyFingerprint::Unnameable, - TyKind::Function(fn_ptr) => { - TyFingerprint::Function(fn_ptr.substitution.0.len(Interner) as u32) - } - TyKind::Placeholder(_) - | TyKind::BoundVar(_) - | TyKind::InferenceVar(_, _) - | TyKind::Error => return None, - }; - Some(fp) - } - - /// Creates a TyFingerprint for looking up a trait impl. - pub fn for_trait_impl_ns<'db>(ty: &next_solver::Ty<'db>) -> Option<TyFingerprint> { - use rustc_type_ir::TyKind; - let fp = match (*ty).kind() { - TyKind::Str => TyFingerprint::Str, - TyKind::Never => TyFingerprint::Never, - TyKind::Slice(..) => TyFingerprint::Slice, - TyKind::Array(..) => TyFingerprint::Array, - TyKind::Int(int) => TyFingerprint::Scalar(Scalar::Int(match int { - rustc_type_ir::IntTy::Isize => IntTy::Isize, - rustc_type_ir::IntTy::I8 => IntTy::I8, - rustc_type_ir::IntTy::I16 => IntTy::I16, - rustc_type_ir::IntTy::I32 => IntTy::I32, - rustc_type_ir::IntTy::I64 => IntTy::I64, - rustc_type_ir::IntTy::I128 => IntTy::I128, - })), - TyKind::Uint(uint) => TyFingerprint::Scalar(Scalar::Uint(match uint { - rustc_type_ir::UintTy::Usize => UintTy::Usize, - rustc_type_ir::UintTy::U8 => UintTy::U8, - rustc_type_ir::UintTy::U16 => UintTy::U16, - rustc_type_ir::UintTy::U32 => UintTy::U32, - rustc_type_ir::UintTy::U64 => UintTy::U64, - rustc_type_ir::UintTy::U128 => UintTy::U128, - })), - TyKind::Float(float) => TyFingerprint::Scalar(Scalar::Float(match float { - rustc_type_ir::FloatTy::F16 => FloatTy::F16, - rustc_type_ir::FloatTy::F32 => FloatTy::F32, - rustc_type_ir::FloatTy::F64 => FloatTy::F64, - rustc_type_ir::FloatTy::F128 => FloatTy::F128, - })), - TyKind::Bool => TyFingerprint::Scalar(Scalar::Bool), - TyKind::Char => TyFingerprint::Scalar(Scalar::Char), - TyKind::Adt(def, _) => TyFingerprint::Adt(def.inner().id), - TyKind::RawPtr(.., mutability) => match mutability { - rustc_ast_ir::Mutability::Mut => TyFingerprint::RawPtr(Mutability::Mut), - rustc_ast_ir::Mutability::Not => TyFingerprint::RawPtr(Mutability::Not), - }, - TyKind::Foreign(def) => TyFingerprint::ForeignType(crate::to_foreign_def_id(def.0)), - TyKind::Dynamic(bounds, _) => { - let trait_ref = bounds - .as_slice() - .iter() - .map(|b| (*b).skip_binder()) - .filter_map(|b| match b { - rustc_type_ir::ExistentialPredicate::Trait(t) => Some(t.def_id), - _ => None, - }) - .next()?; - TyFingerprint::Dyn(trait_ref.0) - } - TyKind::Ref(_, _, mutability) => match mutability { - rustc_ast_ir::Mutability::Mut => TyFingerprint::Ref(Mutability::Mut), - rustc_ast_ir::Mutability::Not => TyFingerprint::Ref(Mutability::Not), - }, - TyKind::Tuple(tys) => { - let first_ty = tys.as_slice().iter().next(); - match first_ty { - Some(ty) => return TyFingerprint::for_trait_impl_ns(ty), - None => TyFingerprint::Unit, - } - } - TyKind::FnDef(_, _) - | TyKind::Closure(_, _) - | TyKind::Coroutine(..) - | TyKind::CoroutineWitness(..) - | TyKind::Pat(..) - | TyKind::CoroutineClosure(..) => TyFingerprint::Unnameable, TyKind::FnPtr(sig, _) => { - TyFingerprint::Function(sig.inputs().skip_binder().len() as u32) + TyFingerprint::Function(sig.skip_binder().inputs_and_output.inner().len() as u32) } - TyKind::Alias(..) - | TyKind::Placeholder(_) + TyKind::Param(_) | TyKind::Bound(..) + | TyKind::Placeholder(..) | TyKind::Infer(_) | TyKind::Error(_) - | TyKind::Param(..) + | TyKind::Pat(..) | TyKind::UnsafeBinder(..) => return None, }; Some(fp) @@ -212,25 +152,25 @@ impl TyFingerprint { } pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ - TyFingerprint::Scalar(Scalar::Int(IntTy::I8)), - TyFingerprint::Scalar(Scalar::Int(IntTy::I16)), - TyFingerprint::Scalar(Scalar::Int(IntTy::I32)), - TyFingerprint::Scalar(Scalar::Int(IntTy::I64)), - TyFingerprint::Scalar(Scalar::Int(IntTy::I128)), - TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)), - TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)), - TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)), - TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)), - TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)), - TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)), - TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)), + TyFingerprint::Int(IntTy::I8), + TyFingerprint::Int(IntTy::I16), + TyFingerprint::Int(IntTy::I32), + TyFingerprint::Int(IntTy::I64), + TyFingerprint::Int(IntTy::I128), + TyFingerprint::Int(IntTy::Isize), + TyFingerprint::Uint(UintTy::U8), + TyFingerprint::Uint(UintTy::U16), + TyFingerprint::Uint(UintTy::U32), + TyFingerprint::Uint(UintTy::U64), + TyFingerprint::Uint(UintTy::U128), + TyFingerprint::Uint(UintTy::Usize), ]; pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 4] = [ - TyFingerprint::Scalar(Scalar::Float(FloatTy::F16)), - TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)), - TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)), - TyFingerprint::Scalar(Scalar::Float(FloatTy::F128)), + TyFingerprint::Float(FloatTy::F16), + TyFingerprint::Float(FloatTy::F32), + TyFingerprint::Float(FloatTy::F64), + TyFingerprint::Float(FloatTy::F128), ]; type TraitFpMap = FxHashMap<TraitId, FxHashMap<Option<TyFingerprint>, Box<[ImplId]>>>; @@ -300,9 +240,8 @@ impl TraitImpls { Some(tr) => tr.skip_binder().def_id.0, None => continue, }; - let interner = DbInterner::new_with(db, None, None); - let self_ty = db.impl_self_ty(impl_id).instantiate_identity().to_chalk(interner); - let self_ty_fp = TyFingerprint::for_trait_impl(&self_ty); + let self_ty = db.impl_self_ty(impl_id); + let self_ty_fp = TyFingerprint::for_trait_impl(self_ty.instantiate_identity()); map.entry(target_trait).or_default().entry(self_ty_fp).or_default().push(impl_id); } @@ -415,8 +354,8 @@ impl InherentImpls { continue; } - let interner = DbInterner::new_with(db, None, None); - let self_ty = &db.impl_self_ty(impl_id).instantiate_identity().to_chalk(interner); + let self_ty = db.impl_self_ty(impl_id); + let self_ty = self_ty.instantiate_identity(); match is_inherent_impl_coherent(db, def_map, impl_id, self_ty) { true => { @@ -440,7 +379,7 @@ impl InherentImpls { } } - pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { + pub fn for_self_ty<'db>(&self, self_ty: Ty<'db>) -> &[ImplId] { match TyFingerprint::for_inherent_impl(self_ty) { Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]), None => &[], @@ -476,9 +415,14 @@ pub(crate) fn incoherent_inherent_impl_crates( res } -pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option<SmallVec<[Crate; 2]>> { - match ty.kind(Interner) { - &TyKind::Adt(AdtId(def_id), _) => { +pub fn def_crates<'db>( + db: &'db dyn HirDatabase, + ty: Ty<'db>, + cur_crate: Crate, +) -> Option<SmallVec<[Crate; 2]>> { + match ty.kind() { + TyKind::Adt(adt_def, _) => { + let def_id = adt_def.def_id().0; let rustc_has_incoherent_inherent_impls = match def_id { hir_def::AdtId::StructId(id) => db .struct_signature(id) @@ -499,22 +443,22 @@ pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option<Sma smallvec![def_id.module(db).krate()] }) } - &TyKind::Foreign(id) => { - let alias = from_foreign_def_id(id); + TyKind::Foreign(alias) => { + let alias = alias.0; Some( if db .type_alias_signature(alias) .flags .contains(TypeAliasFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPL) { - db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::ForeignType(id)) + db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::ForeignType(alias)) } else { smallvec![alias.module(db).krate()] }, ) } - TyKind::Dyn(_) => { - let trait_id = ty.dyn_trait()?; + TyKind::Dynamic(bounds, _) => { + let trait_id = bounds.principal_def_id()?.0; Some( if db .trait_signature(trait_id) @@ -530,11 +474,15 @@ pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option<Sma // for primitives, there may be impls in various places (core and alloc // mostly). We just check the whole crate graph for crates with impls // (cached behind a query). - TyKind::Scalar(_) + TyKind::Bool + | TyKind::Char + | TyKind::Int(_) + | TyKind::Uint(_) + | TyKind::Float(_) | TyKind::Str | TyKind::Slice(_) | TyKind::Array(..) - | TyKind::Raw(..) => Some(db.incoherent_inherent_impl_crates( + | TyKind::RawPtr(..) => Some(db.incoherent_inherent_impl_crates( cur_crate, TyFingerprint::for_inherent_impl(ty).expect("fingerprint for primitive"), )), @@ -545,7 +493,7 @@ pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option<Sma /// Look up the method with the given name. pub(crate) fn lookup_method<'db>( db: &'db dyn HirDatabase, - ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>, + ty: &Canonical<'db, Ty<'db>>, env: Arc<TraitEnvironment<'db>>, traits_in_scope: &FxHashSet<TraitId>, visible_from_module: VisibleFromModule, @@ -626,23 +574,23 @@ pub struct ReceiverAdjustments { } impl ReceiverAdjustments { - pub(crate) fn apply( + pub(crate) fn apply<'db>( &self, - table: &mut InferenceTable<'_>, - mut ty: Ty, - ) -> (Ty, Vec<Adjustment>) { + table: &mut InferenceTable<'db>, + mut ty: Ty<'db>, + ) -> (Ty<'db>, Vec<Adjustment<'db>>) { let mut adjust = Vec::new(); - let mut autoderef = table.autoderef(ty.to_nextsolver(table.interner)); + let mut autoderef = table.autoderef(ty); autoderef.next(); for _ in 0..self.autoderefs { match autoderef.next() { None => { never!("autoderef not possible for {:?}", ty); - ty = TyKind::Error.intern(Interner); + ty = Ty::new_error(table.interner(), ErrorGuaranteed); break; } Some((new_ty, _)) => { - ty = new_ty.to_chalk(autoderef.table.interner); + ty = new_ty; let mutbl = match self.autoref { Some(AutorefOrPtrAdjustment::Autoref(m)) => Some(m), Some(AutorefOrPtrAdjustment::ToConstPtr) => Some(Mutability::Not), @@ -654,26 +602,26 @@ impl ReceiverAdjustments { AutoderefKind::Overloaded => Some(OverloadedDeref(mutbl)), AutoderefKind::Builtin => None, }), - target: ty.clone(), + target: ty, }); } } } if let Some(autoref) = &self.autoref { - let lt = table.new_lifetime_var(); + let lt = table.next_region_var(); match autoref { AutorefOrPtrAdjustment::Autoref(m) => { - let a = Adjustment::borrow(*m, ty, lt); - ty = a.target.clone(); + let a = Adjustment::borrow(table.interner(), *m, ty, lt); + ty = a.target; adjust.push(a); } AutorefOrPtrAdjustment::ToConstPtr => { - if let TyKind::Raw(Mutability::Mut, pointee) = ty.kind(Interner) { + if let TyKind::RawPtr(pointee, Mutability::Mut) = ty.kind() { let a = Adjustment { kind: Adjust::Pointer(PointerCast::MutToConstPointer), - target: TyKind::Raw(Mutability::Not, pointee.clone()).intern(Interner), + target: Ty::new_ptr(table.interner(), pointee, Mutability::Not), }; - ty = a.target.clone(); + ty = a.target; adjust.push(a); } else { never!("`ToConstPtr` target is not a raw mutable pointer"); @@ -683,23 +631,20 @@ impl ReceiverAdjustments { } if self.unsize_array { ty = 'it: { - if let TyKind::Ref(m, l, inner) = ty.kind(Interner) - && let TyKind::Array(inner, _) = inner.kind(Interner) + if let TyKind::Ref(l, inner, m) = ty.kind() + && let TyKind::Array(inner, _) = inner.kind() { - break 'it TyKind::Ref( - *m, - l.clone(), - TyKind::Slice(inner.clone()).intern(Interner), - ) - .intern(Interner); + break 'it Ty::new_ref( + table.interner(), + l, + Ty::new_slice(table.interner(), inner), + m, + ); } // FIXME: report diagnostic if array unsizing happens without indirection. ty }; - adjust.push(Adjustment { - kind: Adjust::Pointer(PointerCast::Unsize), - target: ty.clone(), - }); + adjust.push(Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), target: ty }); } (ty, adjust) } @@ -713,7 +658,7 @@ impl ReceiverAdjustments { // lifetime problems, because we need to borrow temp `CrateImplDefs`. // FIXME add a context type here? pub(crate) fn iterate_method_candidates<'db, T>( - ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>, + ty: &Canonical<'db, Ty<'db>>, db: &'db dyn HirDatabase, env: Arc<TraitEnvironment<'db>>, traits_in_scope: &FxHashSet<TraitId>, @@ -744,17 +689,18 @@ pub(crate) fn iterate_method_candidates<'db, T>( } pub fn lookup_impl_const<'db>( - db: &'db dyn HirDatabase, + interner: DbInterner<'db>, env: Arc<TraitEnvironment<'db>>, const_id: ConstId, - subs: Substitution, -) -> (ConstId, Substitution) { + subs: GenericArgs<'db>, +) -> (ConstId, GenericArgs<'db>) { + let db = interner.db; + let trait_id = match const_id.lookup(db).container { ItemContainerId::TraitId(id) => id, _ => return (const_id, subs), }; - let substitution = Substitution::from_iter(Interner, subs.iter(Interner)); - let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution }; + let trait_ref = TraitRef::new(interner, trait_id.into(), subs); let const_signature = db.const_signature(const_id); let name = match const_signature.name.as_ref() { @@ -772,37 +718,30 @@ pub fn lookup_impl_const<'db>( /// Checks if the self parameter of `Trait` method is the `dyn Trait` and we should /// call the method using the vtable. pub fn is_dyn_method<'db>( - db: &'db dyn HirDatabase, + interner: DbInterner<'db>, _env: Arc<TraitEnvironment<'db>>, func: FunctionId, - fn_subst: Substitution, + fn_subst: GenericArgs<'db>, ) -> Option<usize> { + let db = interner.db; + let ItemContainerId::TraitId(trait_id) = func.lookup(db).container else { return None; }; let trait_params = db.generic_params(trait_id.into()).len(); - let fn_params = fn_subst.len(Interner) - trait_params; - let trait_ref = TraitRef { - trait_id: to_chalk_trait_id(trait_id), - substitution: Substitution::from_iter(Interner, fn_subst.iter(Interner).take(trait_params)), - }; - let self_ty = trait_ref.self_type_parameter(Interner); - if let TyKind::Dyn(d) = self_ty.kind(Interner) { + let fn_params = fn_subst.len() - trait_params; + let trait_ref = TraitRef::new( + interner, + trait_id.into(), + GenericArgs::new_from_iter(interner, fn_subst.iter().take(trait_params)), + ); + let self_ty = trait_ref.self_ty(); + if let TyKind::Dynamic(d, _) = self_ty.kind() { + // rustc doesn't accept `impl Foo<2> for dyn Foo<5>`, so if the trait id is equal, no matter + // what the generics are, we are sure that the method is come from the vtable. let is_my_trait_in_bounds = d - .bounds - .skip_binders() - .as_slice(Interner) - .iter() - .map(|it| it.skip_binders()) - .flat_map(|it| match it { - WhereClause::Implemented(tr) => { - all_super_traits(db, from_chalk_trait_id(tr.trait_id)) - } - _ => smallvec![], - }) - // rustc doesn't accept `impl Foo<2> for dyn Foo<5>`, so if the trait id is equal, no matter - // what the generics are, we are sure that the method is come from the vtable. - .any(|x| x == trait_id); + .principal_def_id() + .is_some_and(|trait_| all_super_traits(db, trait_.0).contains(&trait_id)); if is_my_trait_in_bounds { return Some(fn_params); } @@ -817,16 +756,19 @@ pub(crate) fn lookup_impl_method_query<'db>( db: &'db dyn HirDatabase, env: Arc<TraitEnvironment<'db>>, func: FunctionId, - fn_subst: Substitution, -) -> (FunctionId, Substitution) { + fn_subst: GenericArgs<'db>, +) -> (FunctionId, GenericArgs<'db>) { + let interner = DbInterner::new_with(db, Some(env.krate), env.block); + let ItemContainerId::TraitId(trait_id) = func.lookup(db).container else { return (func, fn_subst); }; let trait_params = db.generic_params(trait_id.into()).len(); - let trait_ref = TraitRef { - trait_id: to_chalk_trait_id(trait_id), - substitution: Substitution::from_iter(Interner, fn_subst.iter(Interner).take(trait_params)), - }; + let trait_ref = TraitRef::new( + interner, + trait_id.into(), + GenericArgs::new_from_iter(interner, fn_subst.iter().take(trait_params)), + ); let name = &db.function_signature(func).name; let Some((impl_fn, impl_subst)) = @@ -839,28 +781,28 @@ pub(crate) fn lookup_impl_method_query<'db>( ( impl_fn, - Substitution::from_iter( - Interner, - impl_subst.iter(Interner).chain(fn_subst.iter(Interner).skip(trait_params)), + GenericArgs::new_from_iter( + interner, + impl_subst.iter().chain(fn_subst.iter().skip(trait_params)), ), ) } fn lookup_impl_assoc_item_for_trait_ref<'db>( - trait_ref: TraitRef, + trait_ref: TraitRef<'db>, db: &'db dyn HirDatabase, env: Arc<TraitEnvironment<'db>>, name: &Name, -) -> Option<(AssocItemId, Substitution)> { - let hir_trait_id = trait_ref.hir_trait_id(); - let self_ty = trait_ref.self_type_parameter(Interner); - let self_ty_fp = TyFingerprint::for_trait_impl(&self_ty)?; +) -> Option<(AssocItemId, GenericArgs<'db>)> { + let hir_trait_id = trait_ref.def_id.0; + let self_ty = trait_ref.self_ty(); + let self_ty_fp = TyFingerprint::for_trait_impl(self_ty)?; let impls = db.trait_impls_in_deps(env.krate); let trait_module = hir_trait_id.module(db); let type_module = match self_ty_fp { TyFingerprint::Adt(adt_id) => Some(adt_id.module(db)), - TyFingerprint::ForeignType(type_id) => Some(from_foreign_def_id(type_id).module(db)), + TyFingerprint::ForeignType(type_id) => Some(type_id.module(db)), TyFingerprint::Dyn(trait_id) => Some(trait_id.module(db)), _ => None, }; @@ -888,84 +830,85 @@ fn lookup_impl_assoc_item_for_trait_ref<'db>( Some((item, impl_subst)) } -fn find_matching_impl( +fn find_matching_impl<'db>( mut impls: impl Iterator<Item = ImplId>, - mut table: InferenceTable<'_>, - actual_trait_ref: TraitRef, -) -> Option<(&ImplItems, Substitution)> { + mut table: InferenceTable<'db>, + actual_trait_ref: TraitRef<'db>, +) -> Option<(&'db ImplItems, GenericArgs<'db>)> { let db = table.db; impls.find_map(|impl_| { table.run_in_snapshot(|table| { - let impl_substs = - TyBuilder::subst_for_def(db, impl_, None).fill_with_inference_vars(table).build(); - let args: crate::next_solver::GenericArgs<'_> = - impl_substs.to_nextsolver(table.interner); + let impl_substs = table.fresh_args_for_item(impl_.into()); let trait_ref = db .impl_trait(impl_) .expect("non-trait method in find_matching_impl") - .instantiate(table.interner, args) - .to_chalk(table.interner); + .instantiate(table.interner(), impl_substs); - if !table.unify(&trait_ref, &actual_trait_ref) { + if !table.unify(trait_ref, actual_trait_ref) { return None; } - let wcs = crate::chalk_db::convert_where_clauses(db, impl_.into(), &impl_substs) - .into_iter() - .map(|b| -> Goal { b.cast(Interner) }); - for goal in wcs { - let goal = goal.to_nextsolver(table.interner); - if table.try_obligation(goal).no_solution() { - return None; + if let Some(predicates) = + db.generic_predicates_ns(impl_.into()).instantiate(table.interner(), impl_substs) + { + for predicate in predicates { + if table.try_obligation(predicate.0).no_solution() { + return None; + } + table.register_obligation(predicate.0); } - table.register_obligation(goal); } - Some(( - impl_.impl_items(db), - table.resolve_completely::<_, crate::next_solver::GenericArgs<'_>>(impl_substs), - )) + Some((impl_.impl_items(db), table.resolve_completely(impl_substs))) }) }) } -fn is_inherent_impl_coherent( - db: &dyn HirDatabase, +fn is_inherent_impl_coherent<'db>( + db: &'db dyn HirDatabase, def_map: &DefMap, impl_id: ImplId, - self_ty: &Ty, + self_ty: Ty<'db>, ) -> bool { - let self_ty = self_ty.kind(Interner); + let self_ty = self_ty.kind(); let impl_allowed = match self_ty { - TyKind::Tuple(_, _) + TyKind::Tuple(_) | TyKind::FnDef(_, _) | TyKind::Array(_, _) | TyKind::Never - | TyKind::Raw(_, _) + | TyKind::RawPtr(_, _) | TyKind::Ref(_, _, _) | TyKind::Slice(_) | TyKind::Str - | TyKind::Scalar(_) => def_map.is_rustc_coherence_is_core(), + | TyKind::Bool + | TyKind::Char + | TyKind::Int(_) + | TyKind::Uint(_) + | TyKind::Float(_) => def_map.is_rustc_coherence_is_core(), - &TyKind::Adt(AdtId(adt), _) => adt.module(db).krate() == def_map.krate(), - TyKind::Dyn(it) => it.principal_id().is_some_and(|trait_id| { - from_chalk_trait_id(trait_id).module(db).krate() == def_map.krate() - }), + TyKind::Adt(adt_def, _) => adt_def.def_id().0.module(db).krate() == def_map.krate(), + TyKind::Dynamic(it, _) => it + .principal_def_id() + .is_some_and(|trait_id| trait_id.0.module(db).krate() == def_map.krate()), _ => true, }; impl_allowed || { let rustc_has_incoherent_inherent_impls = match self_ty { - TyKind::Tuple(_, _) + TyKind::Tuple(_) | TyKind::FnDef(_, _) | TyKind::Array(_, _) | TyKind::Never - | TyKind::Raw(_, _) + | TyKind::RawPtr(_, _) | TyKind::Ref(_, _, _) | TyKind::Slice(_) | TyKind::Str - | TyKind::Scalar(_) => true, + | TyKind::Bool + | TyKind::Char + | TyKind::Int(_) + | TyKind::Uint(_) + | TyKind::Float(_) => true, - &TyKind::Adt(AdtId(adt), _) => match adt { + TyKind::Adt(adt_def, _) => match adt_def.def_id().0 { hir_def::AdtId::StructId(id) => db .struct_signature(id) .flags @@ -979,8 +922,8 @@ fn is_inherent_impl_coherent( .flags .contains(EnumFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS), }, - TyKind::Dyn(it) => it.principal_id().is_some_and(|trait_id| { - db.trait_signature(from_chalk_trait_id(trait_id)) + TyKind::Dynamic(it, _) => it.principal_def_id().is_some_and(|trait_id| { + db.trait_signature(trait_id.0) .flags .contains(TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS) }), @@ -1012,8 +955,7 @@ fn is_inherent_impl_coherent( /// - All of /// - At least one of the types `T0..=Tn`` must be a local type. Let `Ti`` be the first such type. /// - No uncovered type parameters `P1..=Pn` may appear in `T0..Ti`` (excluding `Ti`) -pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool { - let substs = TyBuilder::placeholder_subst(db, impl_); +pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool { let Some(impl_trait) = db.impl_trait(impl_) else { // not a trait impl return true; @@ -1022,24 +964,25 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool { let local_crate = impl_.lookup(db).container.krate(); let is_local = |tgt_crate| tgt_crate == local_crate; - let interner = DbInterner::new_with(db, None, None); - let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner); - let trait_ref = impl_trait.instantiate(interner, args).to_chalk(interner); - let trait_id = from_chalk_trait_id(trait_ref.trait_id); + let trait_ref = impl_trait.instantiate_identity(); + let trait_id = trait_ref.def_id.0; if is_local(trait_id.module(db).krate()) { // trait to be implemented is local return true; } - let unwrap_fundamental = |mut ty: Ty| { + let unwrap_fundamental = |mut ty: Ty<'db>| { // Unwrap all layers of fundamental types with a loop. loop { - match ty.kind(Interner) { - TyKind::Ref(_, _, referenced) => ty = referenced.clone(), - &TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), ref subs) => { + match ty.kind() { + TyKind::Ref(_, referenced, _) => ty = referenced, + TyKind::Adt(adt_def, subs) => { + let AdtId::StructId(s) = adt_def.def_id().0 else { + break ty; + }; let struct_signature = db.struct_signature(s); if struct_signature.flags.contains(StructFlags::FUNDAMENTAL) { - let next = subs.type_parameters(Interner).next(); + let next = subs.types().next(); match next { Some(it) => ty = it, None => break ty, @@ -1056,22 +999,20 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool { // FIXME: param coverage // - No uncovered type parameters `P1..=Pn` may appear in `T0..Ti`` (excluding `Ti`) - let is_not_orphan = trait_ref.substitution.type_parameters(Interner).any(|ty| { - match unwrap_fundamental(ty).kind(Interner) { - &TyKind::Adt(AdtId(id), _) => is_local(id.module(db).krate()), - TyKind::Error => true, - TyKind::Dyn(it) => it - .principal_id() - .is_some_and(|trait_id| is_local(from_chalk_trait_id(trait_id).module(db).krate())), - _ => false, + let is_not_orphan = trait_ref.args.types().any(|ty| match unwrap_fundamental(ty).kind() { + TyKind::Adt(adt_def, _) => is_local(adt_def.def_id().0.module(db).krate()), + TyKind::Error(_) => true, + TyKind::Dynamic(it, _) => { + it.principal_def_id().is_some_and(|trait_id| is_local(trait_id.0.module(db).krate())) } + _ => false, }); #[allow(clippy::let_and_return)] is_not_orphan } pub fn iterate_path_candidates<'db>( - ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>, + ty: &Canonical<'db, Ty<'db>>, db: &'db dyn HirDatabase, env: Arc<TraitEnvironment<'db>>, traits_in_scope: &FxHashSet<TraitId>, @@ -1093,7 +1034,7 @@ pub fn iterate_path_candidates<'db>( } pub fn iterate_method_candidates_dyn<'db>( - ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>, + ty: &Canonical<'db, Ty<'db>>, db: &'db dyn HirDatabase, env: Arc<TraitEnvironment<'db>>, traits_in_scope: &FxHashSet<TraitId>, @@ -1132,7 +1073,7 @@ pub fn iterate_method_candidates_dyn<'db>( // types*. let mut table = InferenceTable::new(db, env); - let ty = table.instantiate_canonical_ns(*ty); + let ty = table.instantiate_canonical(*ty); let deref_chain = autoderef_method_receiver(&mut table, ty); deref_chain.into_iter().try_for_each(|(receiver_ty, adj)| { @@ -1165,14 +1106,14 @@ pub fn iterate_method_candidates_dyn<'db>( #[tracing::instrument(skip_all, fields(name = ?name))] fn iterate_method_candidates_with_autoref<'db>( table: &mut InferenceTable<'db>, - receiver_ty: next_solver::Canonical<'db, crate::next_solver::Ty<'db>>, + receiver_ty: Canonical<'db, Ty<'db>>, first_adjustment: ReceiverAdjustments, traits_in_scope: &FxHashSet<TraitId>, visible_from_module: VisibleFromModule, name: Option<&Name>, callback: &mut dyn MethodCandidateCallback, ) -> ControlFlow<()> { - let interner = table.interner; + let interner = table.interner(); let mut iterate_method_candidates_by_receiver = move |receiver_ty, first_adjustment| { iterate_method_candidates_by_receiver( @@ -1187,11 +1128,7 @@ fn iterate_method_candidates_with_autoref<'db>( }; let mut maybe_reborrowed = first_adjustment.clone(); - if let rustc_type_ir::TyKind::Ref(_, _, m) = receiver_ty.value.kind() { - let m = match m { - rustc_ast_ir::Mutability::Mut => chalk_ir::Mutability::Mut, - rustc_ast_ir::Mutability::Not => chalk_ir::Mutability::Not, - }; + if let TyKind::Ref(_, _, m) = receiver_ty.value.kind() { // Prefer reborrow of references to move maybe_reborrowed.autoref = Some(AutorefOrPtrAdjustment::Autoref(m)); maybe_reborrowed.autoderefs += 1; @@ -1199,15 +1136,10 @@ fn iterate_method_candidates_with_autoref<'db>( iterate_method_candidates_by_receiver(receiver_ty, maybe_reborrowed)?; - let refed = next_solver::Canonical { + let refed = Canonical { max_universe: receiver_ty.max_universe, variables: receiver_ty.variables, - value: next_solver::Ty::new_ref( - interner, - next_solver::Region::error(interner), - receiver_ty.value, - rustc_ast_ir::Mutability::Not, - ), + value: Ty::new_ref(interner, Region::error(interner), receiver_ty.value, Mutability::Not), }; iterate_method_candidates_by_receiver( @@ -1215,15 +1147,10 @@ fn iterate_method_candidates_with_autoref<'db>( first_adjustment.with_autoref(AutorefOrPtrAdjustment::Autoref(Mutability::Not)), )?; - let ref_muted = next_solver::Canonical { + let ref_muted = Canonical { max_universe: receiver_ty.max_universe, variables: receiver_ty.variables, - value: next_solver::Ty::new_ref( - interner, - next_solver::Region::error(interner), - receiver_ty.value, - rustc_ast_ir::Mutability::Mut, - ), + value: Ty::new_ref(interner, Region::error(interner), receiver_ty.value, Mutability::Mut), }; iterate_method_candidates_by_receiver( @@ -1231,12 +1158,10 @@ fn iterate_method_candidates_with_autoref<'db>( first_adjustment.with_autoref(AutorefOrPtrAdjustment::Autoref(Mutability::Mut)), )?; - if let rustc_type_ir::TyKind::RawPtr(ty, rustc_ast_ir::Mutability::Mut) = - receiver_ty.value.kind() - { + if let TyKind::RawPtr(ty, Mutability::Mut) = receiver_ty.value.kind() { let const_ptr_ty = rustc_type_ir::Canonical { max_universe: rustc_type_ir::UniverseIndex::ZERO, - value: next_solver::Ty::new_ptr(interner, ty, rustc_ast_ir::Mutability::Not), + value: Ty::new_ptr(interner, ty, Mutability::Not), variables: receiver_ty.variables, }; iterate_method_candidates_by_receiver( @@ -1290,30 +1215,27 @@ where #[tracing::instrument(skip_all, fields(name = ?name))] fn iterate_method_candidates_by_receiver<'db>( table: &mut InferenceTable<'db>, - receiver_ty: next_solver::Canonical<'db, crate::next_solver::Ty<'db>>, + receiver_ty: Canonical<'db, Ty<'db>>, receiver_adjustments: ReceiverAdjustments, traits_in_scope: &FxHashSet<TraitId>, visible_from_module: VisibleFromModule, name: Option<&Name>, callback: &mut dyn MethodCandidateCallback, ) -> ControlFlow<()> { - let interner = table.interner; - let receiver_ty = table.instantiate_canonical_ns(receiver_ty); - let receiver_ty: crate::Ty = receiver_ty.to_chalk(interner); + let receiver_ty = table.instantiate_canonical(receiver_ty); // We're looking for methods with *receiver* type receiver_ty. These could // be found in any of the derefs of receiver_ty, so we have to go through // that, including raw derefs. table.run_in_snapshot(|table| { - let mut autoderef = - autoderef::Autoderef::new_no_tracking(table, receiver_ty.to_nextsolver(interner)) - .include_raw_pointers() - .use_receiver_trait(); + let mut autoderef = autoderef::Autoderef::new_no_tracking(table, receiver_ty) + .include_raw_pointers() + .use_receiver_trait(); while let Some((self_ty, _)) = autoderef.next() { iterate_inherent_methods( - &self_ty.to_chalk(interner), + self_ty, autoderef.table, name, - Some(&receiver_ty), + Some(receiver_ty), Some(receiver_adjustments.clone()), visible_from_module, LookupMode::MethodCall, @@ -1325,23 +1247,21 @@ fn iterate_method_candidates_by_receiver<'db>( ControlFlow::Continue(()) })?; table.run_in_snapshot(|table| { - let mut autoderef = - autoderef::Autoderef::new_no_tracking(table, receiver_ty.to_nextsolver(interner)) - .include_raw_pointers() - .use_receiver_trait(); + let mut autoderef = autoderef::Autoderef::new_no_tracking(table, receiver_ty) + .include_raw_pointers() + .use_receiver_trait(); while let Some((self_ty, _)) = autoderef.next() { - if matches!(self_ty.kind(), crate::next_solver::TyKind::Infer(rustc_type_ir::TyVar(_))) - { + if matches!(self_ty.kind(), TyKind::Infer(rustc_type_ir::TyVar(_))) { // don't try to resolve methods on unknown types return ControlFlow::Continue(()); } iterate_trait_method_candidates( - &self_ty.to_chalk(interner), + self_ty, autoderef.table, traits_in_scope, name, - Some(&receiver_ty), + Some(receiver_ty), Some(receiver_adjustments.clone()), LookupMode::MethodCall, &mut |adjustments, item, is_visible| { @@ -1355,7 +1275,7 @@ fn iterate_method_candidates_by_receiver<'db>( #[tracing::instrument(skip_all, fields(name = ?name))] fn iterate_method_candidates_for_self_ty<'db>( - self_ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>, + self_ty: &Canonical<'db, Ty<'db>>, db: &'db dyn HirDatabase, env: Arc<TraitEnvironment<'db>>, traits_in_scope: &FxHashSet<TraitId>, @@ -1364,9 +1284,9 @@ fn iterate_method_candidates_for_self_ty<'db>( callback: &mut dyn MethodCandidateCallback, ) -> ControlFlow<()> { let mut table = InferenceTable::new(db, env); - let self_ty = table.instantiate_canonical_ns(*self_ty).to_chalk(table.interner); + let self_ty = table.instantiate_canonical(*self_ty); iterate_inherent_methods( - &self_ty, + self_ty, &mut table, name, None, @@ -1378,7 +1298,7 @@ fn iterate_method_candidates_for_self_ty<'db>( }, )?; iterate_trait_method_candidates( - &self_ty, + self_ty, &mut table, traits_in_scope, name, @@ -1392,19 +1312,19 @@ fn iterate_method_candidates_for_self_ty<'db>( } #[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))] -fn iterate_trait_method_candidates( - self_ty: &Ty, - table: &mut InferenceTable<'_>, +fn iterate_trait_method_candidates<'db>( + self_ty: Ty<'db>, + table: &mut InferenceTable<'db>, traits_in_scope: &FxHashSet<TraitId>, name: Option<&Name>, - receiver_ty: Option<&Ty>, + receiver_ty: Option<Ty<'db>>, receiver_adjustments: Option<ReceiverAdjustments>, mode: LookupMode, callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>, ) -> ControlFlow<()> { let db = table.db; - let canonical_self_ty = table.canonicalize(self_ty.clone().to_nextsolver(table.interner)); + let canonical_self_ty = table.canonicalize(self_ty); let krate = table.trait_env.krate; 'traits: for &t in traits_in_scope { @@ -1416,7 +1336,7 @@ fn iterate_trait_method_candidates( // This is to make `[a].into_iter()` not break code with the new `IntoIterator` impl for // arrays. if data.flags.contains(TraitFlags::SKIP_ARRAY_DURING_METHOD_DISPATCH) - && matches!(self_ty.kind(Interner), TyKind::Array(..)) + && matches!(self_ty.kind(), TyKind::Array(..)) { // FIXME: this should really be using the edition of the method name's span, in case it // comes from a macro @@ -1426,9 +1346,9 @@ fn iterate_trait_method_candidates( } if data.flags.contains(TraitFlags::SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH) && matches!( - self_ty.kind(Interner), TyKind::Adt(AdtId(def), subst) - if is_box(table.db, *def) - && matches!(subst.at(Interner, 0).assert_ty_ref(Interner).kind(Interner), TyKind::Slice(..)) + self_ty.kind(), TyKind::Adt(adt_def, subst) + if is_box(table.db, adt_def.def_id().0) + && matches!(subst.type_at(0).kind(), TyKind::Slice(..)) ) { // FIXME: this should really be using the edition of the method name's span, in case it @@ -1472,11 +1392,11 @@ fn iterate_trait_method_candidates( } #[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))] -fn iterate_inherent_methods( - self_ty: &Ty, - table: &mut InferenceTable<'_>, +fn iterate_inherent_methods<'db>( + self_ty: Ty<'db>, + table: &mut InferenceTable<'db>, name: Option<&Name>, - receiver_ty: Option<&Ty>, + receiver_ty: Option<Ty<'db>>, receiver_adjustments: Option<ReceiverAdjustments>, visible_from_module: VisibleFromModule, mode: LookupMode, @@ -1489,11 +1409,11 @@ fn iterate_inherent_methods( // its super traits are considered inherent methods. This matters because these methods have // higher priority than the other traits' methods, which would be considered in // `iterate_trait_method_candidates()` only after this function. - match self_ty.kind(Interner) { - TyKind::Placeholder(_) => { + match self_ty.kind() { + TyKind::Param(_) => { let env = table.trait_env.clone(); let traits = env - .traits_in_scope_from_clauses(self_ty.clone()) + .traits_in_scope_from_clauses(self_ty.to_chalk(table.interner())) .flat_map(|t| all_super_traits(db, t)); iterate_inherent_trait_methods( self_ty, @@ -1506,9 +1426,9 @@ fn iterate_inherent_methods( mode, )?; } - TyKind::Dyn(_) => { - if let Some(principal_trait) = self_ty.dyn_trait() { - let traits = all_super_traits(db, principal_trait); + TyKind::Dynamic(bounds, _) => { + if let Some(principal_trait) = bounds.principal_def_id() { + let traits = all_super_traits(db, principal_trait.0); iterate_inherent_trait_methods( self_ty, table, @@ -1568,11 +1488,11 @@ fn iterate_inherent_methods( return ControlFlow::Continue(()); #[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))] - fn iterate_inherent_trait_methods( - self_ty: &Ty, - table: &mut InferenceTable<'_>, + fn iterate_inherent_trait_methods<'db>( + self_ty: Ty<'db>, + table: &mut InferenceTable<'db>, name: Option<&Name>, - receiver_ty: Option<&Ty>, + receiver_ty: Option<Ty<'db>>, receiver_adjustments: Option<ReceiverAdjustments>, callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>, traits: impl Iterator<Item = TraitId>, @@ -1603,12 +1523,12 @@ fn iterate_inherent_methods( } #[tracing::instrument(skip_all, fields(name = ?name, visible_from_module, receiver_ty))] - fn impls_for_self_ty( + fn impls_for_self_ty<'db>( impls: &InherentImpls, - self_ty: &Ty, - table: &mut InferenceTable<'_>, + self_ty: Ty<'db>, + table: &mut InferenceTable<'db>, name: Option<&Name>, - receiver_ty: Option<&Ty>, + receiver_ty: Option<Ty<'db>>, receiver_adjustments: Option<ReceiverAdjustments>, visible_from_module: Option<ModuleId>, callback: &mut dyn FnMut(ReceiverAdjustments, AssocItemId, bool) -> ControlFlow<()>, @@ -1639,10 +1559,10 @@ fn iterate_inherent_methods( /// Returns the receiver type for the index trait call. pub(crate) fn resolve_indexing_op<'db>( table: &mut InferenceTable<'db>, - ty: next_solver::Canonical<'db, next_solver::Ty<'db>>, + ty: Canonical<'db, Ty<'db>>, index_trait: TraitId, ) -> Option<ReceiverAdjustments> { - let ty = table.instantiate_canonical_ns(ty); + let ty = table.instantiate_canonical(ty); let deref_chain = autoderef_method_receiver(table, ty); for (ty, adj) in deref_chain { let goal = generic_implements_goal_ns(table, index_trait, ty); @@ -1670,10 +1590,10 @@ enum IsValidCandidate { } #[tracing::instrument(skip_all, fields(name))] -fn is_valid_impl_method_candidate( - table: &mut InferenceTable<'_>, - self_ty: &Ty, - receiver_ty: Option<&Ty>, +fn is_valid_impl_method_candidate<'db>( + table: &mut InferenceTable<'db>, + self_ty: Ty<'db>, + receiver_ty: Option<Ty<'db>>, visible_from_module: Option<ModuleId>, name: Option<&Name>, impl_id: ImplId, @@ -1705,9 +1625,8 @@ fn is_valid_impl_method_candidate( let self_ty_matches = table.run_in_snapshot(|table| { let expected_self_ty = TyBuilder::impl_self_ty(db, impl_id) .fill_with_inference_vars(table) - .build(DbInterner::conjure()) - .to_chalk(DbInterner::conjure()); - table.unify(&expected_self_ty, self_ty) + .build(table.interner()); + table.unify(expected_self_ty, self_ty) }); if !self_ty_matches { cov_mark::hit!(const_candidate_self_type_mismatch); @@ -1721,13 +1640,13 @@ fn is_valid_impl_method_candidate( /// Checks whether a given `AssocItemId` is applicable for `receiver_ty`. #[tracing::instrument(skip_all, fields(name))] -fn is_valid_trait_method_candidate( - table: &mut InferenceTable<'_>, +fn is_valid_trait_method_candidate<'db>( + table: &mut InferenceTable<'db>, trait_id: TraitId, name: Option<&Name>, - receiver_ty: Option<&Ty>, + receiver_ty: Option<Ty<'db>>, item: AssocItemId, - self_ty: &Ty, + self_ty: Ty<'db>, mode: LookupMode, ) -> IsValidCandidate { let db = table.db; @@ -1738,27 +1657,20 @@ fn is_valid_trait_method_candidate( check_that!(name.is_none_or(|n| n == &data.name)); table.run_in_snapshot(|table| { - let impl_subst = TyBuilder::subst_for_def(db, trait_id, None) - .fill_with_inference_vars(table) - .build(); - let expect_self_ty = impl_subst.at(Interner, 0).assert_ty_ref(Interner).clone(); + let impl_subst = table.fresh_args_for_item(trait_id.into()); + let expect_self_ty = impl_subst.type_at(0); - check_that!(table.unify(&expect_self_ty, self_ty)); + check_that!(table.unify(expect_self_ty, self_ty)); if let Some(receiver_ty) = receiver_ty { check_that!(data.has_self_param()); - let fn_subst = TyBuilder::subst_for_def(db, fn_id, Some(impl_subst)) - .fill_with_inference_vars(table) - .build(); + let args = table.fill_rest_fresh_args(fn_id.into(), impl_subst); - let args: crate::next_solver::GenericArgs<'_> = - fn_subst.to_nextsolver(table.interner); let sig = db.callable_item_signature(fn_id.into()); let expected_receiver = sig .map_bound(|s| s.skip_binder().inputs_and_output.as_slice()[0]) - .instantiate(table.interner, args) - .to_chalk(table.interner); + .instantiate(table.interner(), args); // FIXME: Clean up this mess with some context struct like rustc's `ProbeContext` let variance = match mode { @@ -1767,16 +1679,8 @@ fn is_valid_trait_method_candidate( }; let res = table .infer_ctxt - .at( - &next_solver::infer::traits::ObligationCause::dummy(), - table.trait_env.env, - ) - .relate( - DefineOpaqueTypes::No, - expected_receiver.to_nextsolver(table.interner), - variance, - receiver_ty.to_nextsolver(table.interner), - ); + .at(&ObligationCause::dummy(), table.trait_env.env) + .relate(DefineOpaqueTypes::No, expected_receiver, variance, receiver_ty); let Ok(infer_ok) = res else { return IsValidCandidate::No; }; @@ -1788,7 +1692,7 @@ fn is_valid_trait_method_candidate( check_that!(ctxt.select_where_possible().is_empty()); } - check_that!(table.unify(receiver_ty, &expected_receiver)); + check_that!(table.unify(receiver_ty, expected_receiver)); } IsValidCandidate::Yes @@ -1805,13 +1709,13 @@ fn is_valid_trait_method_candidate( } #[tracing::instrument(skip_all, fields(name))] -fn is_valid_impl_fn_candidate( - table: &mut InferenceTable<'_>, +fn is_valid_impl_fn_candidate<'db>( + table: &mut InferenceTable<'db>, impl_id: ImplId, fn_id: FunctionId, name: Option<&Name>, - receiver_ty: Option<&Ty>, - self_ty: &Ty, + receiver_ty: Option<Ty<'db>>, + self_ty: Ty<'db>, visible_from_module: Option<ModuleId>, item_name: &Name, ) -> IsValidCandidate { @@ -1829,34 +1733,28 @@ fn is_valid_impl_fn_candidate( table.run_in_snapshot(|table| { let _p = tracing::info_span!("subst_for_def").entered(); let impl_subst = table.infer_ctxt.fresh_args_for_item(impl_id.into()); - let expect_self_ty = db - .impl_self_ty(impl_id) - .instantiate(table.interner, &impl_subst) - .to_chalk(table.interner); + let expect_self_ty = db.impl_self_ty(impl_id).instantiate(table.interner(), &impl_subst); - check_that!(table.unify(&expect_self_ty, self_ty)); + check_that!(table.unify(expect_self_ty, self_ty)); if let Some(receiver_ty) = receiver_ty { let _p = tracing::info_span!("check_receiver_ty").entered(); check_that!(data.has_self_param()); - let fn_subst: crate::Substitution = - table.infer_ctxt.fresh_args_for_item(fn_id.into()).to_chalk(table.interner); + let args = table.infer_ctxt.fresh_args_for_item(fn_id.into()); - let args: crate::next_solver::GenericArgs<'_> = fn_subst.to_nextsolver(table.interner); let sig = db.callable_item_signature(fn_id.into()); let expected_receiver = sig .map_bound(|s| s.skip_binder().inputs_and_output.as_slice()[0]) - .instantiate(table.interner, args) - .to_chalk(table.interner); + .instantiate(table.interner(), args); - check_that!(table.unify(receiver_ty, &expected_receiver)); + check_that!(table.unify(receiver_ty, expected_receiver)); } // We need to consider the bounds on the impl to distinguish functions of the same name // for a type. let predicates = db.generic_predicates_ns(impl_id.into()); - let Some(predicates) = predicates.instantiate(table.interner, impl_subst) else { + let Some(predicates) = predicates.instantiate(table.interner(), impl_subst) else { return IsValidCandidate::Yes; }; @@ -1864,7 +1762,7 @@ fn is_valid_impl_fn_candidate( ctxt.register_obligations(predicates.into_iter().map(|p| { PredicateObligation::new( - table.interner, + table.interner(), ObligationCause::new(), table.trait_env.env, p.0, @@ -1880,7 +1778,7 @@ fn is_valid_impl_fn_candidate( } pub fn implements_trait_unique<'db>( - ty: &Canonical<Ty>, + ty: &crate::Canonical<crate::Ty>, db: &'db dyn HirDatabase, env: &TraitEnvironment<'db>, trait_: TraitId, @@ -1896,8 +1794,8 @@ fn generic_implements_goal<'db>( db: &'db dyn HirDatabase, env: &TraitEnvironment<'db>, trait_: TraitId, - self_ty: &Canonical<Ty>, -) -> Canonical<InEnvironment<super::DomainGoal>> { + self_ty: &crate::Canonical<crate::Ty>, +) -> crate::Canonical<crate::InEnvironment<crate::DomainGoal>> { let binders = self_ty.binders.interned(); let trait_ref = TyBuilder::trait_ref(db, trait_) .push(self_ty.value.clone()) @@ -1920,7 +1818,7 @@ fn generic_implements_goal<'db>( &env.env.to_chalk(DbInterner::new_with(db, Some(env.krate), env.block)), obligation, ); - Canonical { binders, value } + crate::Canonical { binders, value } } /// This creates Substs for a trait with the given Self type and type variables @@ -1929,23 +1827,23 @@ fn generic_implements_goal<'db>( fn generic_implements_goal_ns<'db>( table: &mut InferenceTable<'db>, trait_: TraitId, - self_ty: next_solver::Canonical<'db, crate::next_solver::Ty<'db>>, -) -> next_solver::Canonical<'db, next_solver::Goal<'db, crate::next_solver::Predicate<'db>>> { + self_ty: Canonical<'db, Ty<'db>>, +) -> Canonical<'db, Goal<'db, Predicate<'db>>> { let args = table.infer_ctxt.fresh_args_for_item(SolverDefId::TraitId(trait_)); - let self_ty = table.instantiate_canonical_ns(self_ty); + let self_ty = table.instantiate_canonical(self_ty); let trait_ref = rustc_type_ir::TraitRef::new_from_args(table.infer_ctxt.interner, trait_.into(), args) .with_replaced_self_ty(table.infer_ctxt.interner, self_ty); - let goal = next_solver::Goal::new(table.infer_ctxt.interner, table.trait_env.env, trait_ref); + let goal = Goal::new(table.infer_ctxt.interner, table.trait_env.env, trait_ref); table.canonicalize(goal) } fn autoderef_method_receiver<'db>( table: &mut InferenceTable<'db>, - ty: next_solver::Ty<'db>, -) -> Vec<(next_solver::Canonical<'db, crate::next_solver::Ty<'db>>, ReceiverAdjustments)> { - let interner = table.interner; + ty: Ty<'db>, +) -> Vec<(Canonical<'db, Ty<'db>>, ReceiverAdjustments)> { + let interner = table.interner(); let mut deref_chain = Vec::new(); let mut autoderef = autoderef::Autoderef::new_no_tracking(table, ty).use_receiver_trait(); while let Some((ty, derefs)) = autoderef.next() { @@ -1958,9 +1856,9 @@ fn autoderef_method_receiver<'db>( if let Some((rustc_type_ir::Array(parameters, _), variables, max_universe, adj)) = deref_chain.last().map(|d| (d.0.value.kind(), d.0.variables, d.0.max_universe, d.1.clone())) { - let unsized_ty = next_solver::Ty::new_slice(interner, parameters); + let unsized_ty = Ty::new_slice(interner, parameters); deref_chain.push(( - next_solver::Canonical { max_universe, value: unsized_ty, variables }, + Canonical { max_universe, value: unsized_ty, variables }, ReceiverAdjustments { unsize_array: true, ..adj.clone() }, )); } |