@@ -808,7 +808,15 @@ impl<'a> TyLoweringContext<'a> {
808
808
// handle defaults. In expression or pattern path segments without
809
809
// explicitly specified type arguments, missing type arguments are inferred
810
810
// (i.e. defaults aren't used).
811
- if !infer_args || had_explicit_args {
811
+ // Generic parameters for associated types are not supposed to have defaults, so we just
812
+ // ignore them.
813
+ let is_assoc_ty = if let GenericDefId :: TypeAliasId ( id) = def {
814
+ let container = id. lookup ( self . db . upcast ( ) ) . container ;
815
+ matches ! ( container, ItemContainerId :: TraitId ( _) )
816
+ } else {
817
+ false
818
+ } ;
819
+ if !is_assoc_ty && ( !infer_args || had_explicit_args) {
812
820
let defaults = self . db . generic_defaults ( def) ;
813
821
assert_eq ! ( total_len, defaults. len( ) ) ;
814
822
let parent_from = item_len - substs. len ( ) ;
@@ -997,9 +1005,28 @@ impl<'a> TyLoweringContext<'a> {
997
1005
None => return SmallVec :: new ( ) ,
998
1006
Some ( t) => t,
999
1007
} ;
1008
+ // FIXME: `substs_from_path_segment()` pushes `TyKind::Error` for every parent
1009
+ // generic params. It's inefficient to splice the `Substitution`s, so we may want
1010
+ // that method to optionally take parent `Substitution` as we already know them at
1011
+ // this point (`super_trait_ref.substitution`).
1012
+ let substitution = self . substs_from_path_segment (
1013
+ // FIXME: This is hack. We shouldn't really build `PathSegment` directly.
1014
+ PathSegment { name : & binding. name , args_and_bindings : binding. args . as_deref ( ) } ,
1015
+ Some ( associated_ty. into ( ) ) ,
1016
+ false , // this is not relevant
1017
+ Some ( super_trait_ref. self_type_parameter ( Interner ) ) ,
1018
+ ) ;
1019
+ let self_params = generics ( self . db . upcast ( ) , associated_ty. into ( ) ) . len_self ( ) ;
1020
+ let substitution = Substitution :: from_iter (
1021
+ Interner ,
1022
+ substitution
1023
+ . iter ( Interner )
1024
+ . take ( self_params)
1025
+ . chain ( super_trait_ref. substitution . iter ( Interner ) ) ,
1026
+ ) ;
1000
1027
let projection_ty = ProjectionTy {
1001
1028
associated_ty_id : to_assoc_type_id ( associated_ty) ,
1002
- substitution : super_trait_ref . substitution ,
1029
+ substitution,
1003
1030
} ;
1004
1031
let mut preds: SmallVec < [ _ ; 1 ] > = SmallVec :: with_capacity (
1005
1032
binding. type_ref . as_ref ( ) . map_or ( 0 , |_| 1 ) + binding. bounds . len ( ) ,
0 commit comments