@@ -2791,14 +2791,19 @@ impl Impl {
27912791 all
27922792 }
27932793
2794- // FIXME: the return type is wrong. This should be a hir version of
2795- // `TraitRef` (to account for parameters and qualifiers)
27962794 pub fn trait_ ( self , db : & dyn HirDatabase ) -> Option < Trait > {
2797- let trait_ref = db. impl_trait ( self . id ) ?. skip_binders ( ) . clone ( ) ;
2798- let id = hir_ty :: from_chalk_trait_id ( trait_ref. trait_id ) ;
2795+ let trait_ref = db. impl_trait ( self . id ) ?;
2796+ let id = trait_ref. skip_binders ( ) . hir_trait_id ( ) ;
27992797 Some ( Trait { id } )
28002798 }
28012799
2800+ pub fn trait_ref ( self , db : & dyn HirDatabase ) -> Option < TraitRef > {
2801+ let substs = TyBuilder :: placeholder_subst ( db, self . id ) ;
2802+ let trait_ref = db. impl_trait ( self . id ) ?. substitute ( Interner , & substs) ;
2803+ let resolver = self . id . resolver ( db. upcast ( ) ) ;
2804+ Some ( TraitRef :: new_with_resolver ( db, & resolver, trait_ref) )
2805+ }
2806+
28022807 pub fn self_ty ( self , db : & dyn HirDatabase ) -> Type {
28032808 let resolver = self . id . resolver ( db. upcast ( ) ) ;
28042809 let substs = TyBuilder :: placeholder_subst ( db, self . id ) ;
@@ -2824,6 +2829,48 @@ impl Impl {
28242829 }
28252830}
28262831
2832+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
2833+ pub struct TraitRef {
2834+ env : Arc < TraitEnvironment > ,
2835+ trait_ref : hir_ty:: TraitRef ,
2836+ }
2837+
2838+ impl TraitRef {
2839+ pub ( crate ) fn new_with_resolver (
2840+ db : & dyn HirDatabase ,
2841+ resolver : & Resolver ,
2842+ trait_ref : hir_ty:: TraitRef ,
2843+ ) -> TraitRef {
2844+ let env = resolver. generic_def ( ) . map_or_else (
2845+ || Arc :: new ( TraitEnvironment :: empty ( resolver. krate ( ) ) ) ,
2846+ |d| db. trait_environment ( d) ,
2847+ ) ;
2848+ TraitRef { env, trait_ref }
2849+ }
2850+
2851+ pub fn trait_ ( & self ) -> Trait {
2852+ let id = self . trait_ref . hir_trait_id ( ) ;
2853+ Trait { id }
2854+ }
2855+
2856+ pub fn self_ty ( & self ) -> Type {
2857+ let ty = self . trait_ref . self_type_parameter ( Interner ) ;
2858+ Type { env : self . env . clone ( ) , ty }
2859+ }
2860+
2861+ /// Returns `idx`-th argument of this trait reference if it is a type argument. Note that the
2862+ /// first argument is the `Self` type.
2863+ pub fn get_type_argument ( & self , idx : usize ) -> Option < Type > {
2864+ self . trait_ref
2865+ . substitution
2866+ . as_slice ( Interner )
2867+ . get ( idx)
2868+ . and_then ( |arg| arg. ty ( Interner ) )
2869+ . cloned ( )
2870+ . map ( |ty| Type { env : self . env . clone ( ) , ty } )
2871+ }
2872+ }
2873+
28272874#[ derive( Clone , PartialEq , Eq , Debug ) ]
28282875pub struct Type {
28292876 env : Arc < TraitEnvironment > ,
0 commit comments