aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir_ty/src/builder.rs11
-rw-r--r--crates/hir_ty/src/infer/expr.rs8
-rw-r--r--crates/hir_ty/src/infer/unify.rs6
-rw-r--r--crates/hir_ty/src/lib.rs13
-rw-r--r--crates/hir_ty/src/lower.rs10
-rw-r--r--crates/hir_ty/src/method_resolution.rs16
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs10
-rw-r--r--crates/hir_ty/src/types.rs33
-rw-r--r--crates/hir_ty/src/walk.rs19
9 files changed, 86 insertions, 40 deletions
diff --git a/crates/hir_ty/src/builder.rs b/crates/hir_ty/src/builder.rs
index 9b2c6975a..791915fe0 100644
--- a/crates/hir_ty/src/builder.rs
+++ b/crates/hir_ty/src/builder.rs
@@ -12,8 +12,8 @@ use smallvec::SmallVec;
12 12
13use crate::{ 13use crate::{
14 db::HirDatabase, primitive, to_assoc_type_id, to_chalk_trait_id, utils::generics, Binders, 14 db::HirDatabase, primitive, to_assoc_type_id, to_chalk_trait_id, utils::generics, Binders,
15 CallableSig, FnPointer, FnSig, GenericArg, Interner, ProjectionTy, Substitution, TraitRef, Ty, 15 CallableSig, FnPointer, FnSig, FnSubst, GenericArg, Interner, ProjectionTy, Substitution,
16 TyDefId, TyKind, TypeWalk, ValueTyDefId, 16 TraitRef, Ty, TyDefId, TyKind, TypeWalk, ValueTyDefId,
17}; 17};
18 18
19/// This is a builder for `Ty` or anything that needs a `Substitution`. 19/// This is a builder for `Ty` or anything that needs a `Substitution`.
@@ -78,9 +78,12 @@ impl TyBuilder<()> {
78 78
79 pub fn fn_ptr(sig: CallableSig) -> Ty { 79 pub fn fn_ptr(sig: CallableSig) -> Ty {
80 TyKind::Function(FnPointer { 80 TyKind::Function(FnPointer {
81 num_args: sig.params().len(), 81 num_binders: 0,
82 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs }, 82 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs },
83 substs: Substitution::from_iter(&Interner, sig.params_and_return.iter().cloned()), 83 substitution: FnSubst(Substitution::from_iter(
84 &Interner,
85 sig.params_and_return.iter().cloned(),
86 )),
84 }) 87 })
85 .intern(&Interner) 88 .intern(&Interner)
86 } 89 }
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 185a2dfc3..a2a7236a8 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -22,8 +22,8 @@ use crate::{
22 to_chalk_trait_id, 22 to_chalk_trait_id,
23 traits::{chalk::from_chalk, FnTrait}, 23 traits::{chalk::from_chalk, FnTrait},
24 utils::{generics, variant_data, Generics}, 24 utils::{generics, variant_data, Generics},
25 AdtId, Binders, CallableDefId, FnPointer, FnSig, InEnvironment, Interner, ProjectionTyExt, 25 AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
26 Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind, 26 ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind,
27}; 27};
28 28
29use super::{ 29use super::{
@@ -260,9 +260,9 @@ impl<'a> InferenceContext<'a> {
260 }; 260 };
261 sig_tys.push(ret_ty.clone()); 261 sig_tys.push(ret_ty.clone());
262 let sig_ty = TyKind::Function(FnPointer { 262 let sig_ty = TyKind::Function(FnPointer {
263 num_args: sig_tys.len() - 1, 263 num_binders: 0,
264 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, 264 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
265 substs: Substitution::from_iter(&Interner, sig_tys.clone()), 265 substitution: FnSubst(Substitution::from_iter(&Interner, sig_tys.clone())),
266 }) 266 })
267 .intern(&Interner); 267 .intern(&Interner);
268 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); 268 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index c90a16720..2f9523325 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -7,7 +7,7 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
7 7
8use super::{DomainGoal, InferenceContext}; 8use super::{DomainGoal, InferenceContext};
9use crate::{ 9use crate::{
10 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, 10 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSubst,
11 InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause, 11 InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause,
12}; 12};
13 13
@@ -308,8 +308,8 @@ impl InferenceTable {
308 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) 308 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2))
309 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) 309 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2))
310 | ( 310 | (
311 TyKind::Function(FnPointer { substs: substs1, .. }), 311 TyKind::Function(FnPointer { substitution: FnSubst(substs1), .. }),
312 TyKind::Function(FnPointer { substs: substs2, .. }), 312 TyKind::Function(FnPointer { substitution: FnSubst(substs2), .. }),
313 ) 313 )
314 | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2)) 314 | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2))
315 | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2)) 315 | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2))
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index f74b22b58..c3ec12352 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -142,10 +142,11 @@ impl CallableSig {
142 CallableSig { 142 CallableSig {
143 // FIXME: what to do about lifetime params? -> return PolyFnSig 143 // FIXME: what to do about lifetime params? -> return PolyFnSig
144 params_and_return: fn_ptr 144 params_and_return: fn_ptr
145 .substs 145 .substitution
146 .clone() 146 .clone()
147 .shifted_out_to(DebruijnIndex::ONE) 147 .shifted_out_to(DebruijnIndex::ONE)
148 .expect("unexpected lifetime vars in fn ptr") 148 .expect("unexpected lifetime vars in fn ptr")
149 .0
149 .interned() 150 .interned()
150 .iter() 151 .iter()
151 .map(|arg| arg.assert_ty_ref(&Interner).clone()) 152 .map(|arg| arg.assert_ty_ref(&Interner).clone())
@@ -239,9 +240,9 @@ impl Ty {
239 mutability == mutability2 240 mutability == mutability2
240 } 241 }
241 ( 242 (
242 TyKind::Function(FnPointer { num_args, sig, .. }), 243 TyKind::Function(FnPointer { num_binders, sig, .. }),
243 TyKind::Function(FnPointer { num_args: num_args2, sig: sig2, .. }), 244 TyKind::Function(FnPointer { num_binders: num_binders2, sig: sig2, .. }),
244 ) => num_args == num_args2 && sig == sig2, 245 ) => num_binders == num_binders2 && sig == sig2,
245 (TyKind::Tuple(cardinality, _), TyKind::Tuple(cardinality2, _)) => { 246 (TyKind::Tuple(cardinality, _), TyKind::Tuple(cardinality2, _)) => {
246 cardinality == cardinality2 247 cardinality == cardinality2
247 } 248 }
@@ -314,11 +315,11 @@ impl Ty {
314 match self.kind(&Interner) { 315 match self.kind(&Interner) {
315 TyKind::Adt(_, substs) 316 TyKind::Adt(_, substs)
316 | TyKind::FnDef(_, substs) 317 | TyKind::FnDef(_, substs)
317 | TyKind::Function(FnPointer { substs, .. })
318 | TyKind::Tuple(_, substs) 318 | TyKind::Tuple(_, substs)
319 | TyKind::OpaqueType(_, substs) 319 | TyKind::OpaqueType(_, substs)
320 | TyKind::AssociatedType(_, substs) 320 | TyKind::AssociatedType(_, substs)
321 | TyKind::Closure(.., substs) => Some(substs), 321 | TyKind::Closure(.., substs) => Some(substs),
322 TyKind::Function(FnPointer { substitution: substs, .. }) => Some(&substs.0),
322 _ => None, 323 _ => None,
323 } 324 }
324 } 325 }
@@ -327,11 +328,11 @@ impl Ty {
327 match self.interned_mut() { 328 match self.interned_mut() {
328 TyKind::Adt(_, substs) 329 TyKind::Adt(_, substs)
329 | TyKind::FnDef(_, substs) 330 | TyKind::FnDef(_, substs)
330 | TyKind::Function(FnPointer { substs, .. })
331 | TyKind::Tuple(_, substs) 331 | TyKind::Tuple(_, substs)
332 | TyKind::OpaqueType(_, substs) 332 | TyKind::OpaqueType(_, substs)
333 | TyKind::AssociatedType(_, substs) 333 | TyKind::AssociatedType(_, substs)
334 | TyKind::Closure(.., substs) => Some(substs), 334 | TyKind::Closure(.., substs) => Some(substs),
335 TyKind::Function(FnPointer { substitution: substs, .. }) => Some(&mut substs.0),
335 _ => None, 336 _ => None,
336 } 337 }
337 } 338 }
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 6cef8095f..20bb7dd59 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -34,9 +34,9 @@ use crate::{
34 variant_data, Generics, 34 variant_data, Generics,
35 }, 35 },
36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, 36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, 37 FnSubst, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
38 ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty, 38 QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution,
39 TyBuilder, TyKind, TypeWalk, WhereClause, 39 TraitEnvironment, TraitRef, Ty, TyBuilder, TyKind, TypeWalk, WhereClause,
40}; 40};
41 41
42#[derive(Debug)] 42#[derive(Debug)]
@@ -181,9 +181,9 @@ impl<'a> TyLoweringContext<'a> {
181 let substs = 181 let substs =
182 Substitution::from_iter(&Interner, params.iter().map(|tr| self.lower_ty(tr))); 182 Substitution::from_iter(&Interner, params.iter().map(|tr| self.lower_ty(tr)));
183 TyKind::Function(FnPointer { 183 TyKind::Function(FnPointer {
184 num_args: substs.len(&Interner) - 1, 184 num_binders: 0, // FIXME lower `for<'a> fn()` correctly
185 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs }, 185 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
186 substs, 186 substitution: FnSubst(substs),
187 }) 187 })
188 .intern(&Interner) 188 .intern(&Interner)
189 } 189 }
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index d6de844a8..6d65d3eb9 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -46,18 +46,18 @@ impl TyFingerprint {
46 /// have impls: if we have some `struct S`, we can have an `impl S`, but not 46 /// have impls: if we have some `struct S`, we can have an `impl S`, but not
47 /// `impl &S`. Hence, this will return `None` for reference types and such. 47 /// `impl &S`. Hence, this will return `None` for reference types and such.
48 pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 48 pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
49 let fp = match *ty.kind(&Interner) { 49 let fp = match ty.kind(&Interner) {
50 TyKind::Str => TyFingerprint::Str, 50 TyKind::Str => TyFingerprint::Str,
51 TyKind::Never => TyFingerprint::Never, 51 TyKind::Never => TyFingerprint::Never,
52 TyKind::Slice(..) => TyFingerprint::Slice, 52 TyKind::Slice(..) => TyFingerprint::Slice,
53 TyKind::Array(..) => TyFingerprint::Array, 53 TyKind::Array(..) => TyFingerprint::Array,
54 TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar), 54 TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
55 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), 55 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
56 TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), 56 TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(*cardinality),
57 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), 57 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
58 TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(alias_id), 58 TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
59 TyKind::Function(FnPointer { num_args, sig, .. }) => { 59 TyKind::Function(FnPointer { sig, substitution: substs, .. }) => {
60 TyFingerprint::FnPtr(num_args, sig) 60 TyFingerprint::FnPtr(substs.0.len(&Interner) - 1, *sig)
61 } 61 }
62 TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, 62 TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
63 _ => return None, 63 _ => return None,
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 9f10b889f..13d8d1111 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -24,8 +24,8 @@ impl ToChalk for Ty {
24 match self.into_inner() { 24 match self.into_inner() {
25 TyKind::Ref(m, ty) => ref_to_chalk(db, m, ty), 25 TyKind::Ref(m, ty) => ref_to_chalk(db, m, ty),
26 TyKind::Array(ty) => array_to_chalk(db, ty), 26 TyKind::Array(ty) => array_to_chalk(db, ty),
27 TyKind::Function(FnPointer { sig, substs, .. }) => { 27 TyKind::Function(FnPointer { sig, substitution: substs, .. }) => {
28 let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner)); 28 let substitution = chalk_ir::FnSubst(substs.0.to_chalk(db).shifted_in(&Interner));
29 chalk_ir::TyKind::Function(chalk_ir::FnPointer { 29 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
30 num_binders: 0, 30 num_binders: 0,
31 sig, 31 sig,
@@ -132,11 +132,11 @@ impl ToChalk for Ty {
132 .. 132 ..
133 }) => { 133 }) => {
134 assert_eq!(num_binders, 0); 134 assert_eq!(num_binders, 0);
135 let substs: Substitution = from_chalk( 135 let substs = crate::FnSubst(from_chalk(
136 db, 136 db,
137 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), 137 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
138 ); 138 ));
139 TyKind::Function(FnPointer { num_args: (substs.len(&Interner) - 1), sig, substs }) 139 TyKind::Function(FnPointer { num_binders, sig, substitution: substs })
140 } 140 }
141 chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx), 141 chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx),
142 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Error, 142 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Error,
diff --git a/crates/hir_ty/src/types.rs b/crates/hir_ty/src/types.rs
index 4a626d5e7..d4e07a6b8 100644
--- a/crates/hir_ty/src/types.rs
+++ b/crates/hir_ty/src/types.rs
@@ -11,7 +11,7 @@ use smallvec::SmallVec;
11 11
12use crate::{ 12use crate::{
13 AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId, 13 AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId,
14 InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, TypeWalk, VariableKinds, 14 InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, TypeWalk, VariableKind, VariableKinds,
15}; 15};
16 16
17#[derive(Clone, PartialEq, Eq, Debug, Hash)] 17#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -43,9 +43,36 @@ pub struct DynTy {
43 43
44#[derive(Clone, PartialEq, Eq, Debug, Hash)] 44#[derive(Clone, PartialEq, Eq, Debug, Hash)]
45pub struct FnPointer { 45pub struct FnPointer {
46 pub num_args: usize, 46 pub num_binders: usize,
47 pub sig: FnSig, 47 pub sig: FnSig,
48 pub substs: Substitution, 48 pub substitution: FnSubst,
49}
50/// A wrapper for the substs on a Fn.
51#[derive(Clone, PartialEq, Eq, Debug, Hash)]
52pub struct FnSubst(pub Substitution);
53
54impl FnPointer {
55 /// Represent the current `Fn` as if it was wrapped in `Binders`
56 pub fn into_binders(self, interner: &Interner) -> Binders<FnSubst> {
57 Binders::new(
58 VariableKinds::from_iter(
59 interner,
60 (0..self.num_binders).map(|_| VariableKind::Lifetime),
61 ),
62 self.substitution,
63 )
64 }
65
66 /// Represent the current `Fn` as if it was wrapped in `Binders`
67 pub fn as_binders(&self, interner: &Interner) -> Binders<&FnSubst> {
68 Binders::new(
69 VariableKinds::from_iter(
70 interner,
71 (0..self.num_binders).map(|_| VariableKind::Lifetime),
72 ),
73 &self.substitution,
74 )
75 }
49} 76}
50 77
51#[derive(Clone, PartialEq, Eq, Debug, Hash)] 78#[derive(Clone, PartialEq, Eq, Debug, Hash)]
diff --git a/crates/hir_ty/src/walk.rs b/crates/hir_ty/src/walk.rs
index b85e6ab4d..963eb12c8 100644
--- a/crates/hir_ty/src/walk.rs
+++ b/crates/hir_ty/src/walk.rs
@@ -6,8 +6,9 @@ use std::mem;
6use chalk_ir::DebruijnIndex; 6use chalk_ir::DebruijnIndex;
7 7
8use crate::{ 8use crate::{
9 utils::make_mut_slice, AliasEq, AliasTy, Binders, CallableSig, GenericArg, GenericArgData, 9 utils::make_mut_slice, AliasEq, AliasTy, Binders, CallableSig, FnSubst, GenericArg,
10 Interner, OpaqueTy, ProjectionTy, Substitution, TraitRef, Ty, TyKind, WhereClause, 10 GenericArgData, Interner, OpaqueTy, ProjectionTy, Substitution, TraitRef, Ty, TyKind,
11 WhereClause,
11}; 12};
12 13
13/// This allows walking structures that contain types to do something with those 14/// This allows walking structures that contain types to do something with those
@@ -381,3 +382,17 @@ impl TypeWalk for AliasEq {
381 } 382 }
382 } 383 }
383} 384}
385
386impl TypeWalk for FnSubst {
387 fn walk(&self, f: &mut impl FnMut(&Ty)) {
388 self.0.walk(f)
389 }
390
391 fn walk_mut_binders(
392 &mut self,
393 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
394 binders: DebruijnIndex,
395 ) {
396 self.0.walk_mut_binders(f, binders)
397 }
398}