aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/traits
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/traits')
-rw-r--r--crates/hir_ty/src/traits/chalk.rs103
-rw-r--r--crates/hir_ty/src/traits/chalk/tls.rs3
2 files changed, 85 insertions, 21 deletions
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 17c83b6a4..25e8ac186 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -11,6 +11,7 @@ use hir_def::{
11 lang_item::{lang_attr, LangItemTarget}, 11 lang_item::{lang_attr, LangItemTarget},
12 AssocContainerId, AssocItemId, HasModule, Lookup, TypeAliasId, 12 AssocContainerId, AssocItemId, HasModule, Lookup, TypeAliasId,
13}; 13};
14use hir_expand::name::name;
14 15
15use super::ChalkContext; 16use super::ChalkContext;
16use crate::{ 17use crate::{
@@ -18,7 +19,8 @@ use crate::{
18 display::HirDisplay, 19 display::HirDisplay,
19 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, 20 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
20 utils::generics, 21 utils::generics,
21 CallableDefId, DebruijnIndex, FnSig, GenericPredicate, Substs, Ty, TypeCtor, 22 BoundVar, CallableDefId, DebruijnIndex, FnSig, GenericPredicate, ProjectionPredicate,
23 ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
22}; 24};
23use mapping::{ 25use mapping::{
24 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, 26 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
@@ -166,27 +168,86 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
166 fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> { 168 fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> {
167 let interned_id = crate::db::InternedOpaqueTyId::from(id); 169 let interned_id = crate::db::InternedOpaqueTyId::from(id);
168 let full_id = self.db.lookup_intern_impl_trait_id(interned_id); 170 let full_id = self.db.lookup_intern_impl_trait_id(interned_id);
169 let (func, idx) = match full_id { 171 let bound = match full_id {
170 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => (func, idx), 172 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
171 }; 173 let datas = self
172 let datas = 174 .db
173 self.db.return_type_impl_traits(func).expect("impl trait id without impl traits"); 175 .return_type_impl_traits(func)
174 let data = &datas.value.impl_traits[idx as usize]; 176 .expect("impl trait id without impl traits");
175 let bound = OpaqueTyDatumBound { 177 let data = &datas.value.impl_traits[idx as usize];
176 bounds: make_binders( 178 let bound = OpaqueTyDatumBound {
177 data.bounds 179 bounds: make_binders(
178 .value 180 data.bounds
179 .iter() 181 .value
180 .cloned() 182 .iter()
181 .filter(|b| !b.is_error()) 183 .cloned()
182 .map(|b| b.to_chalk(self.db)) 184 .filter(|b| !b.is_error())
183 .collect(), 185 .map(|b| b.to_chalk(self.db))
184 1, 186 .collect(),
185 ), 187 1,
186 where_clauses: make_binders(vec![], 0), 188 ),
189 where_clauses: make_binders(vec![], 0),
190 };
191 let num_vars = datas.num_binders;
192 make_binders(bound, num_vars)
193 }
194 crate::OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
195 if let Some((future_trait, future_output)) = self
196 .db
197 .lang_item(self.krate, "future_trait".into())
198 .and_then(|item| item.as_trait())
199 .and_then(|trait_| {
200 let alias =
201 self.db.trait_data(trait_).associated_type_by_name(&name![Output])?;
202 Some((trait_, alias))
203 })
204 {
205 // AsyncBlock<T>: Future</* Self */>
206 // This is required by `fn impls_future` to check if we need to provide `.await` completion.
207 let impl_bound = GenericPredicate::Implemented(TraitRef {
208 trait_: future_trait,
209 // Self type as the first parameter.
210 substs: Substs::single(Ty::Bound(BoundVar {
211 debruijn: DebruijnIndex::INNERMOST,
212 index: 0,
213 })),
214 });
215 // AsyncBlock<T>: Future</* Self, */ Output = T>;
216 // debruijn: ^1 ^0
217 let proj_bound = GenericPredicate::Projection(ProjectionPredicate {
218 // The parameter of the opaque type.
219 ty: Ty::Bound(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }),
220 projection_ty: ProjectionTy {
221 associated_ty: future_output,
222 // Self type as the first parameter.
223 parameters: Substs::single(Ty::Bound(BoundVar::new(
224 DebruijnIndex::INNERMOST,
225 0,
226 ))),
227 },
228 });
229 let bound = OpaqueTyDatumBound {
230 bounds: make_binders(
231 vec![impl_bound.to_chalk(self.db), proj_bound.to_chalk(self.db)],
232 1,
233 ),
234 where_clauses: make_binders(vec![], 0),
235 };
236 // The opaque type has 1 parameter.
237 make_binders(bound, 1)
238 } else {
239 // If failed to find `Future::Output`, return empty bounds as fallback.
240 let bound = OpaqueTyDatumBound {
241 bounds: make_binders(vec![], 0),
242 where_clauses: make_binders(vec![], 0),
243 };
244 // The opaque type has 1 parameter.
245 make_binders(bound, 1)
246 }
247 }
187 }; 248 };
188 let num_vars = datas.num_binders; 249
189 Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound: make_binders(bound, num_vars) }) 250 Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound })
190 } 251 }
191 252
192 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> { 253 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> {
diff --git a/crates/hir_ty/src/traits/chalk/tls.rs b/crates/hir_ty/src/traits/chalk/tls.rs
index db915625c..cb6b0fe81 100644
--- a/crates/hir_ty/src/traits/chalk/tls.rs
+++ b/crates/hir_ty/src/traits/chalk/tls.rs
@@ -73,6 +73,9 @@ impl DebugContext<'_> {
73 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 73 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
74 write!(f, "{{impl trait {} of {:?}}}", idx, func)?; 74 write!(f, "{{impl trait {} of {:?}}}", idx, func)?;
75 } 75 }
76 crate::OpaqueTyId::AsyncBlockTypeImplTrait(def, idx) => {
77 write!(f, "{{impl trait of async block {} of {:?}}}", idx.into_raw(), def)?;
78 }
76 }, 79 },
77 TypeCtor::Closure { def, expr } => { 80 TypeCtor::Closure { def, expr } => {
78 write!(f, "{{closure {:?} in ", expr.into_raw())?; 81 write!(f, "{{closure {:?} in ", expr.into_raw())?;