@@ -28,11 +28,11 @@ use crate::{
2828 db:: HirDatabase ,
2929 primitive:: { FloatTy , IntTy } ,
3030 utils:: {
31- all_super_traits , associated_type_by_name_including_super_traits, generics, make_mut_slice ,
32- variant_data,
31+ all_super_trait_refs , associated_type_by_name_including_super_traits, generics,
32+ make_mut_slice , variant_data,
3333 } ,
3434 Binders , BoundVar , DebruijnIndex , FnSig , GenericPredicate , PolyFnSig , ProjectionPredicate ,
35- ProjectionTy , Substs , TraitEnvironment , TraitRef , Ty , TypeCtor ,
35+ ProjectionTy , Substs , TraitEnvironment , TraitRef , Ty , TypeCtor , TypeWalk ,
3636} ;
3737
3838#[ derive( Debug ) ]
@@ -256,7 +256,7 @@ impl Ty {
256256 if remaining_segments. len ( ) == 1 {
257257 // resolve unselected assoc types
258258 let segment = remaining_segments. first ( ) . unwrap ( ) ;
259- ( Ty :: select_associated_type ( ctx, ty , res, segment) , None )
259+ ( Ty :: select_associated_type ( ctx, res, segment) , None )
260260 } else if remaining_segments. len ( ) > 1 {
261261 // FIXME report error (ambiguous associated type)
262262 ( Ty :: Unknown , None )
@@ -380,21 +380,20 @@ impl Ty {
380380
381381 fn select_associated_type (
382382 ctx : & TyLoweringContext < ' _ > ,
383- self_ty : Ty ,
384383 res : Option < TypeNs > ,
385384 segment : PathSegment < ' _ > ,
386385 ) -> Ty {
387386 let traits_from_env: Vec < _ > = match res {
388387 Some ( TypeNs :: SelfType ( impl_id) ) => match ctx. db . impl_trait ( impl_id) {
389388 None => return Ty :: Unknown ,
390- Some ( trait_ref) => vec ! [ trait_ref. value. trait_ ] ,
389+ Some ( trait_ref) => vec ! [ trait_ref. value] ,
391390 } ,
392391 Some ( TypeNs :: GenericParam ( param_id) ) => {
393392 let predicates = ctx. db . generic_predicates_for_param ( param_id) ;
394393 let mut traits_: Vec < _ > = predicates
395394 . iter ( )
396395 . filter_map ( |pred| match & pred. value {
397- GenericPredicate :: Implemented ( tr) => Some ( tr. trait_ ) ,
396+ GenericPredicate :: Implemented ( tr) => Some ( tr. clone ( ) ) ,
398397 _ => None ,
399398 } )
400399 . collect ( ) ;
@@ -404,20 +403,37 @@ impl Ty {
404403 if generics. params . types [ param_id. local_id ] . provenance
405404 == TypeParamProvenance :: TraitSelf
406405 {
407- traits_. push ( trait_id) ;
406+ let trait_ref = TraitRef {
407+ trait_ : trait_id,
408+ substs : Substs :: bound_vars ( & generics, DebruijnIndex :: INNERMOST ) ,
409+ } ;
410+ traits_. push ( trait_ref) ;
408411 }
409412 }
410413 traits_
411414 }
412415 _ => return Ty :: Unknown ,
413416 } ;
414- let traits = traits_from_env. into_iter ( ) . flat_map ( |t| all_super_traits ( ctx. db . upcast ( ) , t) ) ;
417+ let traits = traits_from_env. into_iter ( ) . flat_map ( |t| all_super_trait_refs ( ctx. db , t) ) ;
415418 for t in traits {
416- if let Some ( associated_ty) = ctx. db . trait_data ( t) . associated_type_by_name ( & segment. name )
419+ if let Some ( associated_ty) =
420+ ctx. db . trait_data ( t. trait_ ) . associated_type_by_name ( & segment. name )
417421 {
418- let substs =
419- Substs :: build_for_def ( ctx. db , t) . push ( self_ty) . fill_with_unknown ( ) . build ( ) ;
420- // FIXME handle type parameters on the segment
422+ let substs = match ctx. type_param_mode {
423+ TypeParamLoweringMode :: Placeholder => {
424+ // if we're lowering to placeholders, we have to put
425+ // them in now
426+ let s = Substs :: type_params (
427+ ctx. db ,
428+ ctx. resolver
429+ . generic_def ( )
430+ . expect ( "there should be generics if there's a generic param" ) ,
431+ ) ;
432+ t. substs . subst_bound_vars ( & s)
433+ }
434+ TypeParamLoweringMode :: Variable => t. substs ,
435+ } ;
436+ // FIXME handle (forbid) type parameters on the segment
421437 return Ty :: Projection ( ProjectionTy { associated_ty, parameters : substs } ) ;
422438 }
423439 }
0 commit comments