33
44use std:: collections:: BTreeSet ;
55
6- use hir:: hir_def:: { scope_graph:: ScopeId , GenericParam , GenericParamOwner , IngotId , TypeBound } ;
6+ use hir:: hir_def:: {
7+ scope_graph:: ScopeId , GenericParam , GenericParamOwner , Impl , IngotId , ItemKind , TypeBound ,
8+ } ;
79use rustc_hash:: FxHashMap ;
810use salsa:: function:: Configuration ;
911
1012use crate :: {
11- ty:: { trait_lower:: lower_trait, unify:: InferenceKey } ,
13+ ty:: {
14+ trait_lower:: { lower_impl_trait, lower_trait} ,
15+ unify:: InferenceKey ,
16+ } ,
1217 HirAnalysisDb ,
1318} ;
1419
1520use super :: {
1621 constraint_solver:: { is_goal_satisfiable, GoalSatisfiability } ,
1722 trait_def:: { Implementor , TraitDef , TraitInstId } ,
1823 trait_lower:: lower_trait_ref,
19- ty_def:: { AdtDef , Subst , TyConcrete , TyData , TyId } ,
24+ ty_def:: { AdtDef , FuncDef , Subst , TyBase , TyData , TyId } ,
2025 ty_lower:: { collect_generic_params, lower_hir_ty, GenericParamOwnerId } ,
2126} ;
2227
@@ -40,30 +45,36 @@ pub(crate) fn ty_constraints(
4045 assert ! ( ty. free_inference_keys( db) . is_empty( ) ) ;
4146
4247 let ( base, args) = ty. decompose_ty_app ( db) ;
43- let TyData :: TyCon ( TyConcrete :: Adt ( adt) ) = base. data ( db) else {
44- return (
45- AssumptionListId :: empty_list ( db) ,
46- ConstraintListId :: empty_list ( db) ,
47- ) ;
48+ let ( params, base_constraints) = match base. data ( db) {
49+ TyData :: TyBase ( TyBase :: Adt ( adt) ) => ( adt. params ( db) , collect_adt_constraints ( db, adt) ) ,
50+ TyData :: TyBase ( TyBase :: Func ( func_def) ) => (
51+ func_def. params ( db) ,
52+ collect_func_def_constraints ( db, func_def) ,
53+ ) ,
54+ _ => {
55+ return (
56+ AssumptionListId :: empty_list ( db) ,
57+ ConstraintListId :: empty_list ( db) ,
58+ ) ;
59+ }
4860 } ;
4961
5062 let mut subst = FxHashMap :: default ( ) ;
5163 let mut arg_idx = 0 ;
52- for ( & param, arg) in adt . params ( db ) . iter ( ) . zip ( args) {
64+ for ( & param, arg) in params. iter ( ) . zip ( args) {
5365 subst. insert ( param, arg) ;
5466 arg_idx += 1 ;
5567 }
5668
5769 // Generalize unbound type parameters.
58- for & arg in adt . params ( db ) . iter ( ) . skip ( arg_idx) {
70+ for & arg in params. iter ( ) . skip ( arg_idx) {
5971 let key = InferenceKey ( arg_idx as u32 ) ;
6072 let ty_var = TyId :: ty_var ( db, arg. kind ( db) . clone ( ) , key) ;
6173 subst. insert ( arg, ty_var) ;
6274 arg_idx += 1 ;
6375 }
6476
65- // Substitute type parameters.
66- let constraints = collect_adt_constraints ( db, adt) . apply_subst ( db, & mut subst) ;
77+ let constraints = base_constraints. apply_subst ( db, & mut subst) ;
6778
6879 // If the predicate type is a type variable, collect it as an assumption
6980 // and remove it from the constraint.
@@ -182,19 +193,56 @@ pub(crate) fn collect_adt_constraints(db: &dyn HirAnalysisDb, adt: AdtDef) -> Co
182193 collector. collect ( )
183194}
184195
196+ #[ salsa:: tracked]
197+ pub ( crate ) fn collect_impl_block_constraints (
198+ db : & dyn HirAnalysisDb ,
199+ impl_ : Impl ,
200+ ) -> ConstraintListId {
201+ let owner = GenericParamOwnerId :: new ( db, impl_. into ( ) ) ;
202+ ConstraintCollector :: new ( db, owner) . collect ( )
203+ }
204+
185205/// Collect constraints that are specified by the given implementor(i.e., impl
186206/// trait).
187207#[ salsa:: tracked]
188208pub ( crate ) fn collect_implementor_constraints (
189209 db : & dyn HirAnalysisDb ,
190210 implementor : Implementor ,
191211) -> ConstraintListId {
192- let impl_trait = implementor. impl_trait ( db) ;
212+ let impl_trait = implementor. hir_impl_trait ( db) ;
193213 let collector = ConstraintCollector :: new ( db, GenericParamOwnerId :: new ( db, impl_trait. into ( ) ) ) ;
194214
195215 collector. collect ( )
196216}
197217
218+ #[ salsa:: tracked]
219+ pub ( crate ) fn collect_func_def_constraints (
220+ db : & dyn HirAnalysisDb ,
221+ func : FuncDef ,
222+ ) -> ConstraintListId {
223+ let hir_func = func. hir_func ( db) ;
224+
225+ let func_constraints =
226+ ConstraintCollector :: new ( db, GenericParamOwnerId :: new ( db, hir_func. into ( ) ) ) . collect ( ) ;
227+
228+ let parent_constraints = match hir_func. scope ( ) . parent_item ( db. as_hir_db ( ) ) {
229+ Some ( ItemKind :: Trait ( trait_) ) => collect_trait_constraints ( db, lower_trait ( db, trait_) ) ,
230+
231+ Some ( ItemKind :: Impl ( impl_) ) => collect_impl_block_constraints ( db, impl_) ,
232+
233+ Some ( ItemKind :: ImplTrait ( impl_trait) ) => {
234+ let Some ( implementor) = lower_impl_trait ( db, impl_trait) else {
235+ return func_constraints;
236+ } ;
237+ collect_implementor_constraints ( db, implementor)
238+ }
239+
240+ _ => return func_constraints,
241+ } ;
242+
243+ func_constraints. merge ( db, parent_constraints)
244+ }
245+
198246/// Returns a list of assumptions derived from the given assumptions by looking
199247/// up super traits.
200248#[ salsa:: tracked( return_ref) ]
@@ -231,6 +279,12 @@ impl PredicateId {
231279 let trait_ = self . trait_inst ( db) . apply_subst ( db, subst) ;
232280 Self :: new ( db, ty, trait_)
233281 }
282+
283+ pub fn pretty_print ( self , db : & dyn HirAnalysisDb ) -> String {
284+ let ty = self . ty ( db) ;
285+ let trait_ = self . trait_inst ( db) ;
286+ format ! ( "{}: {}" , ty. pretty_print( db) , trait_. pretty_print( db) )
287+ }
234288}
235289
236290/// The list of predicates.
0 commit comments