@@ -50,7 +50,7 @@ use crate::{
50
50
to_assoc_type_id, to_chalk_trait_id,
51
51
traits:: ChalkContext ,
52
52
utils:: ClosureSubst ,
53
- wrap_empty_binders,
53
+ variable_kinds_from_generics , wrap_empty_binders,
54
54
} ;
55
55
56
56
pub ( crate ) type AssociatedTyDatum = chalk_solve:: rust_ir:: AssociatedTyDatum < Interner > ;
@@ -1059,9 +1059,14 @@ fn impl_method_rpitit_values(
1059
1059
DebruijnIndex :: INNERMOST ,
1060
1060
) ;
1061
1061
let trait_assoc = trait_assoc_id. loc ( db) ;
1062
+ // Completely unlike the docs, Chalk requires both the impl generics and the associated type
1063
+ // generics in the binder.
1062
1064
let impl_rpitit_binders = VariableKinds :: from_iter (
1063
1065
Interner ,
1064
- & trait_assoc. bounds . binders . as_slice ( Interner ) [ ..trait_method_generics. len ( ) ] ,
1066
+ trait_assoc. bounds . binders . as_slice ( Interner ) [ ..trait_method_generics. len ( ) ]
1067
+ . iter ( )
1068
+ . cloned ( )
1069
+ . chain ( variable_kinds_from_generics ( db, impl_method_generics. iter_parent_id ( ) ) ) ,
1065
1070
) ;
1066
1071
let impl_rpitit = Binders :: new (
1067
1072
impl_rpitit_binders,
@@ -1288,44 +1293,48 @@ pub(crate) fn associated_ty_value_query(
1288
1293
AnyImplAssocType :: Normal ( type_alias) => {
1289
1294
type_alias_associated_ty_value ( db, krate, type_alias)
1290
1295
}
1291
- AnyImplAssocType :: Rpitit ( assoc_type_id) => {
1292
- let assoc_type = assoc_type_id. loc ( db) ;
1293
- let trait_assoc = assoc_type. trait_assoc . loc ( db) ;
1294
- let all_method_assocs = impl_method_rpitit_values (
1295
- db,
1296
- assoc_type. impl_id ,
1297
- trait_assoc. synthesized_from_method ,
1298
- ) ;
1299
- let trait_assoc_id = to_assoc_type_id_rpitit ( assoc_type. trait_assoc ) ;
1300
- all_method_assocs
1301
- . iter ( )
1302
- . find ( |method_assoc| method_assoc. associated_ty_id == trait_assoc_id)
1303
- . cloned ( )
1304
- . unwrap_or_else ( || {
1305
- let impl_id = hir_def:: ImplId :: to_chalk ( assoc_type. impl_id , db) ;
1306
- let trait_method_generics =
1307
- generics ( db, trait_assoc. synthesized_from_method . into ( ) ) ;
1308
- Arc :: new ( AssociatedTyValue {
1309
- associated_ty_id : trait_assoc_id,
1310
- impl_id,
1311
- // In this situation, we don't know even that the trait and impl generics match, therefore
1312
- // the only binders we can give to comply with the trait's binders are the trait's binders.
1313
- // However, for impl associated types chalk wants only their own generics, excluding
1314
- // those of the impl (unlike in traits), therefore we filter them here.
1315
- value : Binders :: new (
1316
- VariableKinds :: from_iter (
1317
- Interner ,
1318
- & trait_assoc. bounds . binders . as_slice ( Interner )
1319
- [ ..trait_method_generics. len_self ( ) ] ,
1320
- ) ,
1321
- rust_ir:: AssociatedTyValueBound { ty : TyKind :: Error . intern ( Interner ) } ,
1322
- ) ,
1323
- } )
1324
- } )
1325
- }
1296
+ AnyImplAssocType :: Rpitit ( assoc_type_id) => rpitit_associated_ty_value ( db, assoc_type_id) ,
1326
1297
}
1327
1298
}
1328
1299
1300
+ fn rpitit_associated_ty_value (
1301
+ db : & dyn HirDatabase ,
1302
+ assoc_type_id : RpititImplAssocTyId ,
1303
+ ) -> Arc < AssociatedTyValue > {
1304
+ let assoc_type = assoc_type_id. loc ( db) ;
1305
+ let trait_assoc = assoc_type. trait_assoc . loc ( db) ;
1306
+ let all_method_assocs =
1307
+ impl_method_rpitit_values ( db, assoc_type. impl_id , trait_assoc. synthesized_from_method ) ;
1308
+ let trait_assoc_id = to_assoc_type_id_rpitit ( assoc_type. trait_assoc ) ;
1309
+ all_method_assocs
1310
+ . iter ( )
1311
+ . find ( |method_assoc| method_assoc. associated_ty_id == trait_assoc_id)
1312
+ . cloned ( )
1313
+ . unwrap_or_else ( || {
1314
+ let impl_id = hir_def:: ImplId :: to_chalk ( assoc_type. impl_id , db) ;
1315
+ let trait_method_generics = generics ( db, trait_assoc. synthesized_from_method . into ( ) ) ;
1316
+ let impl_generics = generics ( db, assoc_type. impl_id . into ( ) ) ;
1317
+ // In this situation, we don't know even that the trait and impl generics match, therefore
1318
+ // the only binders we can give to comply with the trait's binders are the trait's binders.
1319
+ // However, for impl associated types chalk wants only their own generics, excluding
1320
+ // those of the impl (unlike in traits), therefore we filter them here.
1321
+ // Completely unlike the docs, Chalk requires both the impl generics and the associated type
1322
+ // generics in the binder.
1323
+ let value = Binders :: new (
1324
+ VariableKinds :: from_iter (
1325
+ Interner ,
1326
+ trait_assoc. bounds . binders . as_slice ( Interner )
1327
+ [ ..trait_method_generics. len_self ( ) ]
1328
+ . iter ( )
1329
+ . cloned ( )
1330
+ . chain ( variable_kinds_from_generics ( db, impl_generics. iter_id ( ) ) ) ,
1331
+ ) ,
1332
+ rust_ir:: AssociatedTyValueBound { ty : TyKind :: Error . intern ( Interner ) } ,
1333
+ ) ;
1334
+ Arc :: new ( AssociatedTyValue { associated_ty_id : trait_assoc_id, impl_id, value } )
1335
+ } )
1336
+ }
1337
+
1329
1338
fn type_alias_associated_ty_value (
1330
1339
db : & dyn HirDatabase ,
1331
1340
_krate : Crate ,
0 commit comments