Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/chalk_ext.rs')
-rw-r--r--crates/hir-ty/src/chalk_ext.rs54
1 files changed, 29 insertions, 25 deletions
diff --git a/crates/hir-ty/src/chalk_ext.rs b/crates/hir-ty/src/chalk_ext.rs
index 836cc96233..1faf9f66dc 100644
--- a/crates/hir-ty/src/chalk_ext.rs
+++ b/crates/hir-ty/src/chalk_ext.rs
@@ -14,10 +14,9 @@ use hir_def::{
use crate::{
AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Canonical, CanonicalVarKinds,
ClosureId, DynTy, FnPointer, ImplTraitId, InEnvironment, Interner, Lifetime, ProjectionTy,
- QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeFlags, WhereClause,
- db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
- from_placeholder_idx, generics::generics, mapping::ToChalk, to_chalk_trait_id,
- utils::ClosureSubst,
+ QuantifiedWhereClause, Substitution, ToChalk, TraitRef, Ty, TyBuilder, TyKind, TypeFlags,
+ WhereClause, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
+ from_placeholder_idx, generics::generics, to_chalk_trait_id, utils::ClosureSubst,
};
pub trait TyExt {
@@ -211,7 +210,7 @@ impl TyExt for Ty {
match self.kind(Interner) {
TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
TyKind::FnDef(def, parameters) => Some(CallableSig::from_def(db, *def, parameters)),
- TyKind::Closure(.., substs) => ClosureSubst(substs).sig_ty().callable_sig(db),
+ TyKind::Closure(.., substs) => ClosureSubst(substs).sig_ty(db).callable_sig(db),
_ => None,
}
}
@@ -246,26 +245,30 @@ impl TyExt for Ty {
}
fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> {
+ let handle_async_block_type_impl_trait = |def: DefWithBodyId| {
+ let krate = def.module(db).krate();
+ if let Some(future_trait) = LangItem::Future.resolve_trait(db, krate) {
+ // This is only used by type walking.
+ // Parameters will be walked outside, and projection predicate is not used.
+ // So just provide the Future trait.
+ let impl_bound = Binders::empty(
+ Interner,
+ WhereClause::Implemented(TraitRef {
+ trait_id: to_chalk_trait_id(future_trait),
+ substitution: Substitution::empty(Interner),
+ }),
+ );
+ Some(vec![impl_bound])
+ } else {
+ None
+ }
+ };
+
match self.kind(Interner) {
TyKind::OpaqueType(opaque_ty_id, subst) => {
match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
- let krate = def.module(db).krate();
- if let Some(future_trait) = LangItem::Future.resolve_trait(db, krate) {
- // This is only used by type walking.
- // Parameters will be walked outside, and projection predicate is not used.
- // So just provide the Future trait.
- let impl_bound = Binders::empty(
- Interner,
- WhereClause::Implemented(TraitRef {
- trait_id: to_chalk_trait_id(future_trait),
- substitution: Substitution::empty(Interner),
- }),
- );
- Some(vec![impl_bound])
- } else {
- None
- }
+ handle_async_block_type_impl_trait(def)
}
ImplTraitId::ReturnTypeImplTrait(func, idx) => {
db.return_type_impl_traits(func).map(|it| {
@@ -300,14 +303,15 @@ impl TyExt for Ty {
data.substitute(Interner, &opaque_ty.substitution)
})
}
- // It always has an parameter for Future::Output type.
- ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(),
+ ImplTraitId::AsyncBlockTypeImplTrait(def, _) => {
+ return handle_async_block_type_impl_trait(def);
+ }
};
predicates.map(|it| it.into_value_and_skipped_binders().0)
}
TyKind::Placeholder(idx) => {
- let id = from_placeholder_idx(db, *idx);
+ let id = from_placeholder_idx(db, *idx).0;
let generic_params = db.generic_params(id.parent);
let param_data = &generic_params[id.local_id];
match param_data {
@@ -371,7 +375,7 @@ impl TyExt for Ty {
value: InEnvironment::new(&env.env, trait_ref.cast(Interner)),
binders: CanonicalVarKinds::empty(Interner),
};
- db.trait_solve(crate_id, None, goal).is_some()
+ !db.trait_solve(crate_id, None, goal).no_solution()
}
fn equals_ctor(&self, other: &Ty) -> bool {