diff options
author | Florian Diebold <[email protected]> | 2021-04-05 21:32:58 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-04-05 22:00:50 +0100 |
commit | 1ae967bf8e01262f1ace1c06f6670f09fcf92fd2 (patch) | |
tree | db440a2bdd6148bc292bd20397f389671f8cb48c /crates | |
parent | edc59d897d56815e8b9814cdc4ff084100e4f3b4 (diff) |
Fix shifting of binders in FnPointer
- don't shift in/out for Chalk mapping (we want to have the same
binders now)
- do shift in when creating the signature for a closure (though it
shouldn't matter much)
- do shift in when lowering a `fn()` type
- correctly deal with the implied binder in TypeWalk
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 5 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 9 | ||||
-rw-r--r-- | crates/hir_ty/src/walk.rs | 13 |
4 files changed, 23 insertions, 10 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index a2a7236a8..ff564106b 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -23,7 +23,7 @@ use crate::{ | |||
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, FnSubst, InEnvironment, Interner, | 25 | AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner, |
26 | ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind, | 26 | ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeWalk, |
27 | }; | 27 | }; |
28 | 28 | ||
29 | use super::{ | 29 | use super::{ |
@@ -262,7 +262,9 @@ impl<'a> InferenceContext<'a> { | |||
262 | let sig_ty = TyKind::Function(FnPointer { | 262 | let sig_ty = TyKind::Function(FnPointer { |
263 | num_binders: 0, | 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 | substitution: FnSubst(Substitution::from_iter(&Interner, sig_tys.clone())), | 265 | substitution: FnSubst( |
266 | Substitution::from_iter(&Interner, sig_tys.clone()).shifted_in(&Interner), | ||
267 | ), | ||
266 | }) | 268 | }) |
267 | .intern(&Interner); | 269 | .intern(&Interner); |
268 | let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); | 270 | let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 20bb7dd59..3cbb6ad54 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -178,8 +178,9 @@ impl<'a> TyLoweringContext<'a> { | |||
178 | } | 178 | } |
179 | TypeRef::Placeholder => TyKind::Error.intern(&Interner), | 179 | TypeRef::Placeholder => TyKind::Error.intern(&Interner), |
180 | TypeRef::Fn(params, is_varargs) => { | 180 | TypeRef::Fn(params, is_varargs) => { |
181 | let substs = | 181 | let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { |
182 | Substitution::from_iter(&Interner, params.iter().map(|tr| self.lower_ty(tr))); | 182 | Substitution::from_iter(&Interner, params.iter().map(|tr| ctx.lower_ty(tr))) |
183 | }); | ||
183 | TyKind::Function(FnPointer { | 184 | TyKind::Function(FnPointer { |
184 | num_binders: 0, // FIXME lower `for<'a> fn()` correctly | 185 | num_binders: 0, // FIXME lower `for<'a> fn()` correctly |
185 | sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs }, | 186 | sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs }, |
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 13d8d1111..3047fbacb 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | //! Chalk (in both directions); plus some helper functions for more specialized | 3 | //! Chalk (in both directions); plus some helper functions for more specialized |
4 | //! conversions. | 4 | //! conversions. |
5 | 5 | ||
6 | use chalk_ir::{cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData}; | 6 | use chalk_ir::{cast::Cast, interner::HasInterner, LifetimeData}; |
7 | use chalk_solve::rust_ir; | 7 | use chalk_solve::rust_ir; |
8 | 8 | ||
9 | use base_db::salsa::InternKey; | 9 | use base_db::salsa::InternKey; |
@@ -25,7 +25,7 @@ impl ToChalk for Ty { | |||
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, substitution: substs, .. }) => { | 27 | TyKind::Function(FnPointer { sig, substitution: substs, .. }) => { |
28 | let substitution = chalk_ir::FnSubst(substs.0.to_chalk(db).shifted_in(&Interner)); | 28 | let substitution = chalk_ir::FnSubst(substs.0.to_chalk(db)); |
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,10 +132,7 @@ impl ToChalk for Ty { | |||
132 | .. | 132 | .. |
133 | }) => { | 133 | }) => { |
134 | assert_eq!(num_binders, 0); | 134 | assert_eq!(num_binders, 0); |
135 | let substs = crate::FnSubst(from_chalk( | 135 | let substs = crate::FnSubst(from_chalk(db, substitution.0)); |
136 | db, | ||
137 | substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), | ||
138 | )); | ||
139 | TyKind::Function(FnPointer { num_binders, sig, substitution: substs }) | 136 | TyKind::Function(FnPointer { num_binders, sig, substitution: substs }) |
140 | } | 137 | } |
141 | chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx), | 138 | chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx), |
diff --git a/crates/hir_ty/src/walk.rs b/crates/hir_ty/src/walk.rs index 963eb12c8..e1e77ba37 100644 --- a/crates/hir_ty/src/walk.rs +++ b/crates/hir_ty/src/walk.rs | |||
@@ -92,6 +92,13 @@ pub trait TypeWalk { | |||
92 | self | 92 | self |
93 | } | 93 | } |
94 | 94 | ||
95 | fn shifted_in(self, _interner: &Interner) -> Self | ||
96 | where | ||
97 | Self: Sized, | ||
98 | { | ||
99 | self.shifted_in_from(DebruijnIndex::ONE) | ||
100 | } | ||
101 | |||
95 | /// Shifts up debruijn indices of `TyKind::Bound` vars by `n`. | 102 | /// Shifts up debruijn indices of `TyKind::Bound` vars by `n`. |
96 | fn shifted_in_from(self, n: DebruijnIndex) -> Self | 103 | fn shifted_in_from(self, n: DebruijnIndex) -> Self |
97 | where | 104 | where |
@@ -149,6 +156,9 @@ impl TypeWalk for Ty { | |||
149 | TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => { | 156 | TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => { |
150 | ty.walk(f); | 157 | ty.walk(f); |
151 | } | 158 | } |
159 | TyKind::Function(fn_pointer) => { | ||
160 | fn_pointer.substitution.0.walk(f); | ||
161 | } | ||
152 | _ => { | 162 | _ => { |
153 | if let Some(substs) = self.substs() { | 163 | if let Some(substs) = self.substs() { |
154 | for t in substs.iter(&Interner) { | 164 | for t in substs.iter(&Interner) { |
@@ -180,6 +190,9 @@ impl TypeWalk for Ty { | |||
180 | TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => { | 190 | TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => { |
181 | ty.walk_mut_binders(f, binders); | 191 | ty.walk_mut_binders(f, binders); |
182 | } | 192 | } |
193 | TyKind::Function(fn_pointer) => { | ||
194 | fn_pointer.substitution.0.walk_mut_binders(f, binders.shifted_in()); | ||
195 | } | ||
183 | _ => { | 196 | _ => { |
184 | if let Some(substs) = self.substs_mut() { | 197 | if let Some(substs) = self.substs_mut() { |
185 | substs.walk_mut_binders(f, binders); | 198 | substs.walk_mut_binders(f, binders); |