aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r--crates/hir_ty/src/lib.rs45
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)]
1066pub enum OpaqueTyId { 1106pub 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)]