diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 1e748476a..768d95eff 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -129,10 +129,14 @@ 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 | ||
137 | /// Represents a foreign type declared in external blocks. | ||
138 | ForeignType(TypeAliasId), | ||
139 | |||
136 | /// The type of a specific closure. | 140 | /// The type of a specific closure. |
137 | /// | 141 | /// |
138 | /// The closure signature is stored in a `FnPtr` type in the first type | 142 | /// The closure signature is stored in a `FnPtr` type in the first type |
@@ -167,12 +171,18 @@ impl TypeCtor { | |||
167 | let generic_params = generics(db.upcast(), type_alias.into()); | 171 | let generic_params = generics(db.upcast(), type_alias.into()); |
168 | generic_params.len() | 172 | generic_params.len() |
169 | } | 173 | } |
174 | TypeCtor::ForeignType(type_alias) => { | ||
175 | let generic_params = generics(db.upcast(), type_alias.into()); | ||
176 | generic_params.len() | ||
177 | } | ||
170 | TypeCtor::OpaqueType(opaque_ty_id) => { | 178 | TypeCtor::OpaqueType(opaque_ty_id) => { |
171 | match opaque_ty_id { | 179 | match opaque_ty_id { |
172 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { | 180 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { |
173 | let generic_params = generics(db.upcast(), func.into()); | 181 | let generic_params = generics(db.upcast(), func.into()); |
174 | generic_params.len() | 182 | generic_params.len() |
175 | } | 183 | } |
184 | // 1 param representing Future::Output type. | ||
185 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => 1, | ||
176 | } | 186 | } |
177 | } | 187 | } |
178 | TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1, | 188 | TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1, |
@@ -201,10 +211,14 @@ impl TypeCtor { | |||
201 | TypeCtor::AssociatedType(type_alias) => { | 211 | TypeCtor::AssociatedType(type_alias) => { |
202 | Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate) | 212 | Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate) |
203 | } | 213 | } |
214 | TypeCtor::ForeignType(type_alias) => { | ||
215 | Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate) | ||
216 | } | ||
204 | TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id { | 217 | TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id { |
205 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { | 218 | OpaqueTyId::ReturnTypeImplTrait(func, _) => { |
206 | Some(func.lookup(db.upcast()).module(db.upcast()).krate) | 219 | Some(func.lookup(db.upcast()).module(db.upcast()).krate) |
207 | } | 220 | } |
221 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _) => Some(def.module(db.upcast()).krate), | ||
208 | }, | 222 | }, |
209 | } | 223 | } |
210 | } | 224 | } |
@@ -227,6 +241,7 @@ impl TypeCtor { | |||
227 | TypeCtor::Adt(adt) => Some(adt.into()), | 241 | TypeCtor::Adt(adt) => Some(adt.into()), |
228 | TypeCtor::FnDef(callable) => Some(callable.into()), | 242 | TypeCtor::FnDef(callable) => Some(callable.into()), |
229 | TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), | 243 | TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), |
244 | TypeCtor::ForeignType(type_alias) => Some(type_alias.into()), | ||
230 | TypeCtor::OpaqueType(_impl_trait_id) => None, | 245 | TypeCtor::OpaqueType(_impl_trait_id) => None, |
231 | } | 246 | } |
232 | } | 247 | } |
@@ -843,6 +858,29 @@ impl Ty { | |||
843 | 858 | ||
844 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { | 859 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { |
845 | match self { | 860 | match self { |
861 | Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { | ||
862 | match opaque_ty_id { | ||
863 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { | ||
864 | let krate = def.module(db.upcast()).krate; | ||
865 | if let Some(future_trait) = db | ||
866 | .lang_item(krate, "future_trait".into()) | ||
867 | .and_then(|item| item.as_trait()) | ||
868 | { | ||
869 | // This is only used by type walking. | ||
870 | // Parameters will be walked outside, and projection predicate is not used. | ||
871 | // So just provide the Future trait. | ||
872 | let impl_bound = GenericPredicate::Implemented(TraitRef { | ||
873 | trait_: future_trait, | ||
874 | substs: Substs::empty(), | ||
875 | }); | ||
876 | Some(vec![impl_bound]) | ||
877 | } else { | ||
878 | None | ||
879 | } | ||
880 | } | ||
881 | OpaqueTyId::ReturnTypeImplTrait(..) => None, | ||
882 | } | ||
883 | } | ||
846 | Ty::Opaque(opaque_ty) => { | 884 | Ty::Opaque(opaque_ty) => { |
847 | let predicates = match opaque_ty.opaque_ty_id { | 885 | let predicates = match opaque_ty.opaque_ty_id { |
848 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 886 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { |
@@ -853,6 +891,8 @@ impl Ty { | |||
853 | data.subst(&opaque_ty.parameters) | 891 | data.subst(&opaque_ty.parameters) |
854 | }) | 892 | }) |
855 | } | 893 | } |
894 | // It always has an parameter for Future::Output type. | ||
895 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => unreachable!(), | ||
856 | }; | 896 | }; |
857 | 897 | ||
858 | predicates.map(|it| it.value) | 898 | predicates.map(|it| it.value) |
@@ -1065,6 +1105,7 @@ impl<T: TypeWalk> TypeWalk for Vec<T> { | |||
1065 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 1105 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
1066 | pub enum OpaqueTyId { | 1106 | pub enum OpaqueTyId { |
1067 | ReturnTypeImplTrait(hir_def::FunctionId, u16), | 1107 | ReturnTypeImplTrait(hir_def::FunctionId, u16), |
1108 | AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId), | ||
1068 | } | 1109 | } |
1069 | 1110 | ||
1070 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 1111 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |