diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 1e748476a..4a7d3a0d9 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -33,6 +33,7 @@ use hir_def::{ | |||
33 | AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, | 33 | AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, |
34 | TypeParamId, | 34 | TypeParamId, |
35 | }; | 35 | }; |
36 | use hir_expand::name::name; | ||
36 | use itertools::Itertools; | 37 | use itertools::Itertools; |
37 | 38 | ||
38 | use crate::{ | 39 | use crate::{ |
@@ -129,8 +130,9 @@ pub enum TypeCtor { | |||
129 | 130 | ||
130 | /// This represents a placeholder for an opaque type in situations where we | 131 | /// This represents a placeholder for an opaque type in situations where we |
131 | /// don't know the hidden type (i.e. currently almost always). This is | 132 | /// 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 | /// analogous to the `AssociatedType` type constructor. |
133 | /// these are only produced by Chalk. | 134 | /// It is also used as the type of async block, with one type parameter |
135 | /// representing the Future::Output type. | ||
134 | OpaqueType(OpaqueTyId), | 136 | OpaqueType(OpaqueTyId), |
135 | 137 | ||
136 | /// The type of a specific closure. | 138 | /// The type of a specific closure. |
@@ -173,6 +175,8 @@ impl TypeCtor { | |||
173 | let generic_params = generics(db.upcast(), func.into()); | 175 | let generic_params = generics(db.upcast(), func.into()); |
174 | generic_params.len() | 176 | generic_params.len() |
175 | } | 177 | } |
178 | // 1 param representing Future::Output type. | ||
179 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => 1, | ||
176 | } | 180 | } |
177 | } | 181 | } |
178 | TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1, | 182 | TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1, |
@@ -205,6 +209,7 @@ impl TypeCtor { | |||
205 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { | 209 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { |
206 | Some(func.lookup(db.upcast()).module(db.upcast()).krate) | 210 | Some(func.lookup(db.upcast()).module(db.upcast()).krate) |
207 | } | 211 | } |
212 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _) => Some(def.module(db.upcast()).krate), | ||
208 | }, | 213 | }, |
209 | } | 214 | } |
210 | } | 215 | } |
@@ -843,6 +848,33 @@ impl Ty { | |||
843 | 848 | ||
844 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { | 849 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { |
845 | match self { | 850 | 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 | } | ||
846 | Ty::Opaque(opaque_ty) => { | 878 | Ty::Opaque(opaque_ty) => { |
847 | let predicates = match opaque_ty.opaque_ty_id { | 879 | let predicates = match opaque_ty.opaque_ty_id { |
848 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 880 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { |
@@ -853,6 +885,8 @@ impl Ty { | |||
853 | data.subst(&opaque_ty.parameters) | 885 | data.subst(&opaque_ty.parameters) |
854 | }) | 886 | }) |
855 | } | 887 | } |
888 | // It always has an parameter for Future::Output type. | ||
889 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => unreachable!(), | ||
856 | }; | 890 | }; |
857 | 891 | ||
858 | predicates.map(|it| it.value) | 892 | predicates.map(|it| it.value) |
@@ -1065,6 +1099,7 @@ impl<T: TypeWalk> TypeWalk for Vec<T> { | |||
1065 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 1099 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
1066 | pub enum OpaqueTyId { | 1100 | pub enum OpaqueTyId { |
1067 | ReturnTypeImplTrait(hir_def::FunctionId, u16), | 1101 | ReturnTypeImplTrait(hir_def::FunctionId, u16), |
1102 | AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId), | ||
1068 | } | 1103 | } |
1069 | 1104 | ||
1070 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 1105 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |