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.rs | 54 |
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 { |