Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/utils.rs')
-rw-r--r--crates/hir-ty/src/utils.rs36
1 files changed, 34 insertions, 2 deletions
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs
index 3b2a726688..aa40d08479 100644
--- a/crates/hir-ty/src/utils.rs
+++ b/crates/hir-ty/src/utils.rs
@@ -23,10 +23,11 @@ use hir_expand::name::Name;
use intern::Interned;
use rustc_hash::FxHashSet;
use smallvec::{smallvec, SmallVec};
+use stdx::never;
use crate::{
- db::HirDatabase, ChalkTraitId, Interner, Substitution, TraitRef, TraitRefExt, Ty, TyExt,
- WhereClause,
+ db::HirDatabase, ChalkTraitId, GenericArg, Interner, Substitution, TraitRef, TraitRefExt, Ty,
+ TyExt, WhereClause,
};
pub(crate) fn fn_traits(
@@ -176,6 +177,37 @@ pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
Generics { def, params: db.generic_params(def), parent_generics }
}
+/// It is a bit different from the rustc equivalent. Currently it stores:
+/// - 0: the function signature, encoded as a function pointer type
+/// - 1..n: generics of the parent
+///
+/// and it doesn't store the closure types and fields.
+///
+/// Codes should not assume this ordering, and should always use methods available
+/// on this struct for retriving, and `TyBuilder::substs_for_closure` for creating.
+pub(crate) struct ClosureSubst<'a>(pub(crate) &'a Substitution);
+
+impl<'a> ClosureSubst<'a> {
+ pub(crate) fn parent_subst(&self) -> &'a [GenericArg] {
+ match self.0.as_slice(Interner) {
+ [_, x @ ..] => x,
+ _ => {
+ never!("Closure missing parameter");
+ &[]
+ }
+ }
+ }
+
+ pub(crate) fn sig_ty(&self) -> &'a Ty {
+ match self.0.as_slice(Interner) {
+ [x, ..] => x.assert_ty_ref(Interner),
+ _ => {
+ unreachable!("Closure missing sig_ty parameter");
+ }
+ }
+ }
+}
+
#[derive(Debug)]
pub(crate) struct Generics {
def: GenericDefId,