diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 1e748476a..f16d1fc97 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -129,8 +129,9 @@ pub enum TypeCtor { | |||
129 | 129 | ||
130 | /// This represents a placeholder for an opaque type in situations where we | 130 | /// 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 | 131 | /// don't know the hidden type (i.e. currently almost always). This is |
132 | /// analogous to the `AssociatedType` type constructor. As with that one, | 132 | /// analogous to the `AssociatedType` type constructor. |
133 | /// these are only produced by Chalk. | 133 | /// It is also used as the type of async block, with one type parameter |
134 | /// representing the Future::Output type. | ||
134 | OpaqueType(OpaqueTyId), | 135 | OpaqueType(OpaqueTyId), |
135 | 136 | ||
136 | /// The type of a specific closure. | 137 | /// The type of a specific closure. |
@@ -173,6 +174,8 @@ impl TypeCtor { | |||
173 | let generic_params = generics(db.upcast(), func.into()); | 174 | let generic_params = generics(db.upcast(), func.into()); |
174 | generic_params.len() | 175 | generic_params.len() |
175 | } | 176 | } |
177 | // 1 param representing Future::Output type. | ||
178 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => 1, | ||
176 | } | 179 | } |
177 | } | 180 | } |
178 | TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1, | 181 | TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1, |
@@ -205,6 +208,7 @@ impl TypeCtor { | |||
205 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { | 208 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { |
206 | Some(func.lookup(db.upcast()).module(db.upcast()).krate) | 209 | Some(func.lookup(db.upcast()).module(db.upcast()).krate) |
207 | } | 210 | } |
211 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _) => Some(def.module(db.upcast()).krate), | ||
208 | }, | 212 | }, |
209 | } | 213 | } |
210 | } | 214 | } |
@@ -843,6 +847,29 @@ impl Ty { | |||
843 | 847 | ||
844 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { | 848 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { |
845 | match self { | 849 | match self { |
850 | Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { | ||
851 | match opaque_ty_id { | ||
852 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { | ||
853 | let krate = def.module(db.upcast()).krate; | ||
854 | if let Some(future_trait) = db | ||
855 | .lang_item(krate, "future_trait".into()) | ||
856 | .and_then(|item| item.as_trait()) | ||
857 | { | ||
858 | // This is only used by type walking. | ||
859 | // Parameters will be walked outside, and projection predicate is not used. | ||
860 | // So just provide the Future trait. | ||
861 | let impl_bound = GenericPredicate::Implemented(TraitRef { | ||
862 | trait_: future_trait, | ||
863 | substs: Substs::empty(), | ||
864 | }); | ||
865 | Some(vec![impl_bound]) | ||
866 | } else { | ||
867 | None | ||
868 | } | ||
869 | } | ||
870 | OpaqueTyId::ReturnTypeImplTrait(..) => None, | ||
871 | } | ||
872 | } | ||
846 | Ty::Opaque(opaque_ty) => { | 873 | Ty::Opaque(opaque_ty) => { |
847 | let predicates = match opaque_ty.opaque_ty_id { | 874 | let predicates = match opaque_ty.opaque_ty_id { |
848 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 875 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { |
@@ -853,6 +880,8 @@ impl Ty { | |||
853 | data.subst(&opaque_ty.parameters) | 880 | data.subst(&opaque_ty.parameters) |
854 | }) | 881 | }) |
855 | } | 882 | } |
883 | // It always has an parameter for Future::Output type. | ||
884 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => unreachable!(), | ||
856 | }; | 885 | }; |
857 | 886 | ||
858 | predicates.map(|it| it.value) | 887 | predicates.map(|it| it.value) |
@@ -1065,6 +1094,7 @@ impl<T: TypeWalk> TypeWalk for Vec<T> { | |||
1065 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 1094 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
1066 | pub enum OpaqueTyId { | 1095 | pub enum OpaqueTyId { |
1067 | ReturnTypeImplTrait(hir_def::FunctionId, u16), | 1096 | ReturnTypeImplTrait(hir_def::FunctionId, u16), |
1097 | AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId), | ||
1068 | } | 1098 | } |
1069 | 1099 | ||
1070 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 1100 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |