@@ -33,6 +33,7 @@ use hir_def::{
3333 AdtId , AssocContainerId , DefWithBodyId , GenericDefId , HasModule , Lookup , TraitId , TypeAliasId ,
3434 TypeParamId ,
3535} ;
36+ use hir_expand:: name:: name;
3637use itertools:: Itertools ;
3738
3839use crate :: {
@@ -129,8 +130,9 @@ pub enum TypeCtor {
129130
130131 /// This represents a placeholder for an opaque type in situations where we
131132 /// don't know the hidden type (i.e. currently almost always). This is
132- /// analogous to the `AssociatedType` type constructor. As with that one,
133- /// these are only produced by Chalk.
133+ /// analogous to the `AssociatedType` type constructor.
134+ /// It is also used as the type of async block, with one type parameter
135+ /// representing the Future::Output type.
134136 OpaqueType ( OpaqueTyId ) ,
135137
136138 /// The type of a specific closure.
@@ -173,6 +175,8 @@ impl TypeCtor {
173175 let generic_params = generics ( db. upcast ( ) , func. into ( ) ) ;
174176 generic_params. len ( )
175177 }
178+ // 1 param representing Future::Output type.
179+ OpaqueTyId :: AsyncBlockTypeImplTrait ( ..) => 1 ,
176180 }
177181 }
178182 TypeCtor :: FnPtr { num_args, is_varargs : _ } => num_args as usize + 1 ,
@@ -205,6 +209,7 @@ impl TypeCtor {
205209 OpaqueTyId :: ReturnTypeImplTrait ( func, _) => {
206210 Some ( func. lookup ( db. upcast ( ) ) . module ( db. upcast ( ) ) . krate )
207211 }
212+ OpaqueTyId :: AsyncBlockTypeImplTrait ( def, _) => Some ( def. module ( db. upcast ( ) ) . krate ) ,
208213 } ,
209214 }
210215 }
@@ -843,6 +848,33 @@ impl Ty {
843848
844849 pub fn impl_trait_bounds ( & self , db : & dyn HirDatabase ) -> Option < Vec < GenericPredicate > > {
845850 match self {
851+ Ty :: Apply ( ApplicationTy { ctor : TypeCtor :: OpaqueType ( opaque_ty_id) , parameters } ) => {
852+ match opaque_ty_id {
853+ OpaqueTyId :: AsyncBlockTypeImplTrait ( def, _expr) => {
854+ let krate = def. module ( db. upcast ( ) ) . krate ;
855+ if let Some ( future_output) = db
856+ . lang_item ( krate, "future_trait" . into ( ) )
857+ . and_then ( |item| item. as_trait ( ) )
858+ . and_then ( |trait_| {
859+ db. trait_data ( trait_) . associated_type_by_name ( & name ! [ Output ] )
860+ } )
861+ {
862+ let proj = GenericPredicate :: Projection ( ProjectionPredicate {
863+ projection_ty : ProjectionTy {
864+ associated_ty : future_output,
865+ // Self type.
866+ parameters : Substs :: single ( self . clone ( ) ) ,
867+ } ,
868+ ty : parameters[ 0 ] . clone ( ) ,
869+ } ) ;
870+ Some ( vec ! [ proj] )
871+ } else {
872+ None
873+ }
874+ }
875+ OpaqueTyId :: ReturnTypeImplTrait ( ..) => None ,
876+ }
877+ }
846878 Ty :: Opaque ( opaque_ty) => {
847879 let predicates = match opaque_ty. opaque_ty_id {
848880 OpaqueTyId :: ReturnTypeImplTrait ( func, idx) => {
@@ -853,6 +885,8 @@ impl Ty {
853885 data. subst ( & opaque_ty. parameters )
854886 } )
855887 }
888+ // It always has an parameter for Future::Output type.
889+ OpaqueTyId :: AsyncBlockTypeImplTrait ( ..) => unreachable ! ( ) ,
856890 } ;
857891
858892 predicates. map ( |it| it. value )
@@ -1065,6 +1099,7 @@ impl<T: TypeWalk> TypeWalk for Vec<T> {
10651099#[ derive( Copy , Clone , PartialEq , Eq , Debug , Hash ) ]
10661100pub enum OpaqueTyId {
10671101 ReturnTypeImplTrait ( hir_def:: FunctionId , u16 ) ,
1102+ AsyncBlockTypeImplTrait ( hir_def:: DefWithBodyId , ExprId ) ,
10681103}
10691104
10701105#[ derive( Clone , PartialEq , Eq , Debug , Hash ) ]
0 commit comments