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.rs39
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};
36use hir_expand::name::name;
36use itertools::Itertools; 37use itertools::Itertools;
37 38
38use crate::{ 39use 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)]
1066pub enum OpaqueTyId { 1100pub 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)]