@@ -603,9 +603,8 @@ impl<'a> TyLoweringContext<'a> {
603
603
}
604
604
605
605
fn select_associated_type ( & self , res : Option < TypeNs > , segment : PathSegment < ' _ > ) -> Ty {
606
- let ( def, res) = match ( self . resolver . generic_def ( ) , res) {
607
- ( Some ( def) , Some ( res) ) => ( def, res) ,
608
- _ => return TyKind :: Error . intern ( Interner ) ,
606
+ let Some ( ( def, res) ) = self . resolver . generic_def ( ) . zip ( res) else {
607
+ return TyKind :: Error . intern ( Interner ) ;
609
608
} ;
610
609
let ty = named_associated_type_shorthand_candidates (
611
610
self . db ,
@@ -617,6 +616,21 @@ impl<'a> TyLoweringContext<'a> {
617
616
return None ;
618
617
}
619
618
619
+ let parent_subst = t. substitution . clone ( ) ;
620
+ let parent_subst = match self . type_param_mode {
621
+ ParamLoweringMode :: Placeholder => {
622
+ // if we're lowering to placeholders, we have to put them in now.
623
+ let generics = generics ( self . db . upcast ( ) , def) ;
624
+ let s = generics. placeholder_subst ( self . db ) ;
625
+ s. apply ( parent_subst, Interner )
626
+ }
627
+ ParamLoweringMode :: Variable => {
628
+ // We need to shift in the bound vars, since
629
+ // `named_associated_type_shorthand_candidates` does not do that.
630
+ parent_subst. shifted_in_from ( Interner , self . in_binders )
631
+ }
632
+ } ;
633
+
620
634
// FIXME: `substs_from_path_segment()` pushes `TyKind::Error` for every parent
621
635
// generic params. It's inefficient to splice the `Substitution`s, so we may want
622
636
// that method to optionally take parent `Substitution` as we already know them at
@@ -632,22 +646,9 @@ impl<'a> TyLoweringContext<'a> {
632
646
633
647
let substs = Substitution :: from_iter (
634
648
Interner ,
635
- substs. iter ( Interner ) . take ( len_self) . chain ( t . substitution . iter ( Interner ) ) ,
649
+ substs. iter ( Interner ) . take ( len_self) . chain ( parent_subst . iter ( Interner ) ) ,
636
650
) ;
637
651
638
- let substs = match self . type_param_mode {
639
- ParamLoweringMode :: Placeholder => {
640
- // if we're lowering to placeholders, we have to put
641
- // them in now
642
- let generics = generics ( self . db . upcast ( ) , def) ;
643
- let s = generics. placeholder_subst ( self . db ) ;
644
- s. apply ( substs, Interner )
645
- }
646
- ParamLoweringMode :: Variable => substs,
647
- } ;
648
- // We need to shift in the bound vars, since
649
- // associated_type_shorthand_candidates does not do that
650
- let substs = substs. shifted_in_from ( Interner , self . in_binders ) ;
651
652
Some (
652
653
TyKind :: Alias ( AliasTy :: Projection ( ProjectionTy {
653
654
associated_ty_id : to_assoc_type_id ( associated_ty) ,
@@ -1190,9 +1191,9 @@ pub fn associated_type_shorthand_candidates<R>(
1190
1191
db : & dyn HirDatabase ,
1191
1192
def : GenericDefId ,
1192
1193
res : TypeNs ,
1193
- cb : impl FnMut ( & Name , & TraitRef , TypeAliasId ) -> Option < R > ,
1194
+ mut cb : impl FnMut ( & Name , TypeAliasId ) -> Option < R > ,
1194
1195
) -> Option < R > {
1195
- named_associated_type_shorthand_candidates ( db, def, res, None , cb )
1196
+ named_associated_type_shorthand_candidates ( db, def, res, None , |name , _ , id| cb ( name , id ) )
1196
1197
}
1197
1198
1198
1199
fn named_associated_type_shorthand_candidates < R > (
@@ -1202,6 +1203,9 @@ fn named_associated_type_shorthand_candidates<R>(
1202
1203
def : GenericDefId ,
1203
1204
res : TypeNs ,
1204
1205
assoc_name : Option < Name > ,
1206
+ // Do NOT let `cb` touch `TraitRef` outside of `TyLoweringContext`. Its substitution contains
1207
+ // free `BoundVar`s that need to be shifted and only `TyLoweringContext` knows how to do that
1208
+ // properly (see `TyLoweringContext::select_associated_type()`).
1205
1209
mut cb : impl FnMut ( & Name , & TraitRef , TypeAliasId ) -> Option < R > ,
1206
1210
) -> Option < R > {
1207
1211
let mut search = |t| {
0 commit comments