aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/traits/chalk.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/traits/chalk.rs')
-rw-r--r--crates/hir_ty/src/traits/chalk.rs127
1 files changed, 98 insertions, 29 deletions
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 01b5717a3..27f0ed628 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,10 +19,12 @@ 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, TypeAliasAsAssocType,
27 TypeAliasAsValue,
25}; 28};
26 29
27pub use self::interner::*; 30pub use self::interner::*;
@@ -166,27 +169,88 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
166 fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> { 169 fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> {
167 let interned_id = crate::db::InternedOpaqueTyId::from(id); 170 let interned_id = crate::db::InternedOpaqueTyId::from(id);
168 let full_id = self.db.lookup_intern_impl_trait_id(interned_id); 171 let full_id = self.db.lookup_intern_impl_trait_id(interned_id);
169 let (func, idx) = match full_id { 172 let bound = match full_id {
170 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => (func, idx), 173 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
171 }; 174 let datas = self
172 let datas = 175 .db
173 self.db.return_type_impl_traits(func).expect("impl trait id without impl traits"); 176 .return_type_impl_traits(func)
174 let data = &datas.value.impl_traits[idx as usize]; 177 .expect("impl trait id without impl traits");
175 let bound = OpaqueTyDatumBound { 178 let data = &datas.value.impl_traits[idx as usize];
176 bounds: make_binders( 179 let bound = OpaqueTyDatumBound {
177 data.bounds 180 bounds: make_binders(
178 .value 181 data.bounds
179 .iter() 182 .value
180 .cloned() 183 .iter()
181 .filter(|b| !b.is_error()) 184 .cloned()
182 .map(|b| b.to_chalk(self.db)) 185 .filter(|b| !b.is_error())
183 .collect(), 186 .map(|b| b.to_chalk(self.db))
184 1, 187 .collect(),
185 ), 188 1,
186 where_clauses: make_binders(vec![], 0), 189 ),
190 where_clauses: make_binders(vec![], 0),
191 };
192 let num_vars = datas.num_binders;
193 make_binders(bound, num_vars)
194 }
195 crate::OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
196 if let Some((future_trait, future_output)) = self
197 .db
198 .lang_item(self.krate, "future_trait".into())
199 .and_then(|item| item.as_trait())
200 .and_then(|trait_| {
201 let alias =
202 self.db.trait_data(trait_).associated_type_by_name(&name![Output])?;
203 Some((trait_, alias))
204 })
205 {
206 // Making up `AsyncBlock<T>: Future<Output = T>`
207 //
208 // |--------------------OpaqueTyDatum-------------------|
209 // |-------------OpaqueTyDatumBound--------------|
210 // for<T> <Self> [Future<Self>, Future::Output<Self> = T]
211 // ^1 ^0 ^0 ^0 ^1
212 let impl_bound = GenericPredicate::Implemented(TraitRef {
213 trait_: future_trait,
214 // Self type as the first parameter.
215 substs: Substs::single(Ty::Bound(BoundVar {
216 debruijn: DebruijnIndex::INNERMOST,
217 index: 0,
218 })),
219 });
220 let proj_bound = GenericPredicate::Projection(ProjectionPredicate {
221 // The parameter of the opaque type.
222 ty: Ty::Bound(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }),
223 projection_ty: ProjectionTy {
224 associated_ty: future_output,
225 // Self type as the first parameter.
226 parameters: Substs::single(Ty::Bound(BoundVar::new(
227 DebruijnIndex::INNERMOST,
228 0,
229 ))),
230 },
231 });
232 let bound = OpaqueTyDatumBound {
233 bounds: make_binders(
234 vec![impl_bound.to_chalk(self.db), proj_bound.to_chalk(self.db)],
235 1,
236 ),
237 where_clauses: make_binders(vec![], 0),
238 };
239 // The opaque type has 1 parameter.
240 make_binders(bound, 1)
241 } else {
242 // If failed to find `Future::Output`, return empty bounds as fallback.
243 let bound = OpaqueTyDatumBound {
244 bounds: make_binders(vec![], 0),
245 where_clauses: make_binders(vec![], 0),
246 };
247 // The opaque type has 1 parameter.
248 make_binders(bound, 1)
249 }
250 }
187 }; 251 };
188 let num_vars = datas.num_binders; 252
189 Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound: make_binders(bound, num_vars) }) 253 Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound })
190 } 254 }
191 255
192 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> { 256 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> {
@@ -277,7 +341,7 @@ pub(crate) fn associated_ty_data_query(
277 id: AssocTypeId, 341 id: AssocTypeId,
278) -> Arc<AssociatedTyDatum> { 342) -> Arc<AssociatedTyDatum> {
279 debug!("associated_ty_data {:?}", id); 343 debug!("associated_ty_data {:?}", id);
280 let type_alias: TypeAliasId = from_chalk(db, id); 344 let type_alias: TypeAliasId = from_chalk::<TypeAliasAsAssocType, _>(db, id).0;
281 let trait_ = match type_alias.lookup(db.upcast()).container { 345 let trait_ = match type_alias.lookup(db.upcast()).container {
282 AssocContainerId::TraitId(t) => t, 346 AssocContainerId::TraitId(t) => t,
283 _ => panic!("associated type not in trait"), 347 _ => panic!("associated type not in trait"),
@@ -331,8 +395,10 @@ pub(crate) fn trait_datum_query(
331 fundamental: false, 395 fundamental: false,
332 }; 396 };
333 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); 397 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars);
334 let associated_ty_ids = 398 let associated_ty_ids = trait_data
335 trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect(); 399 .associated_types()
400 .map(|type_alias| TypeAliasAsAssocType(type_alias).to_chalk(db))
401 .collect();
336 let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses }; 402 let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses };
337 let well_known = 403 let well_known =
338 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name)); 404 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name));
@@ -370,6 +436,7 @@ fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str {
370 WellKnownTrait::FnMut => "fn_mut", 436 WellKnownTrait::FnMut => "fn_mut",
371 WellKnownTrait::Fn => "fn", 437 WellKnownTrait::Fn => "fn",
372 WellKnownTrait::Unsize => "unsize", 438 WellKnownTrait::Unsize => "unsize",
439 WellKnownTrait::Unpin => "unpin",
373 } 440 }
374} 441}
375 442
@@ -513,7 +580,7 @@ fn type_alias_associated_ty_value(
513 let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; 580 let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) };
514 let value = rust_ir::AssociatedTyValue { 581 let value = rust_ir::AssociatedTyValue {
515 impl_id: impl_id.to_chalk(db), 582 impl_id: impl_id.to_chalk(db),
516 associated_ty_id: assoc_ty.to_chalk(db), 583 associated_ty_id: TypeAliasAsAssocType(assoc_ty).to_chalk(db),
517 value: make_binders(value_bound, ty.num_binders), 584 value: make_binders(value_bound, ty.num_binders),
518 }; 585 };
519 Arc::new(value) 586 Arc::new(value)
@@ -548,9 +615,11 @@ pub(crate) fn fn_def_datum_query(
548 }; 615 };
549 let datum = FnDefDatum { 616 let datum = FnDefDatum {
550 id: fn_def_id, 617 id: fn_def_id,
551 abi: (), 618 sig: chalk_ir::FnSig {
552 safety: chalk_ir::Safety::Safe, 619 abi: (),
553 variadic: sig.value.is_varargs, 620 safety: chalk_ir::Safety::Safe,
621 variadic: sig.value.is_varargs,
622 },
554 binders: make_binders(bound, sig.num_binders), 623 binders: make_binders(bound, sig.num_binders),
555 }; 624 };
556 Arc::new(datum) 625 Arc::new(datum)