diff options
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 3 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 44 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 23 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 43 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 17 | ||||
-rw-r--r-- | crates/hir_ty/src/types.rs | 36 | ||||
-rw-r--r-- | crates/hir_ty/src/walk.rs | 8 |
9 files changed, 104 insertions, 84 deletions
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index 8169b759f..db278d0db 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
@@ -245,7 +245,8 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
245 | Some(callee) => callee, | 245 | Some(callee) => callee, |
246 | None => return, | 246 | None => return, |
247 | }; | 247 | }; |
248 | let sig = db.callable_item_signature(callee.into()).value; | 248 | let sig = |
249 | db.callable_item_signature(callee.into()).into_value_and_skipped_binders().0; | ||
249 | 250 | ||
250 | (sig, args) | 251 | (sig, args) |
251 | } | 252 | } |
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 1108e5a10..2e178e5a8 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -353,7 +353,7 @@ impl HirDisplay for Ty { | |||
353 | .as_ref() | 353 | .as_ref() |
354 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 354 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
355 | let bounds = data.subst(parameters); | 355 | let bounds = data.subst(parameters); |
356 | bounds.value | 356 | bounds.into_value_and_skipped_binders().0 |
357 | } else { | 357 | } else { |
358 | Vec::new() | 358 | Vec::new() |
359 | } | 359 | } |
@@ -543,7 +543,7 @@ impl HirDisplay for Ty { | |||
543 | .as_ref() | 543 | .as_ref() |
544 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 544 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
545 | let bounds = data.subst(¶meters); | 545 | let bounds = data.subst(¶meters); |
546 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 546 | write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?; |
547 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution | 547 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution |
548 | } | 548 | } |
549 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { | 549 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { |
@@ -630,7 +630,7 @@ impl HirDisplay for Ty { | |||
630 | .as_ref() | 630 | .as_ref() |
631 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 631 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
632 | let bounds = data.subst(&opaque_ty.substitution); | 632 | let bounds = data.subst(&opaque_ty.substitution); |
633 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 633 | write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?; |
634 | } | 634 | } |
635 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { | 635 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { |
636 | write!(f, "{{async block}}")?; | 636 | write!(f, "{{async block}}")?; |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index adfdcaa37..61b5cf269 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -118,49 +118,27 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> { | |||
118 | } | 118 | } |
119 | 119 | ||
120 | impl<T> Binders<T> { | 120 | impl<T> Binders<T> { |
121 | pub fn new(num_binders: usize, value: T) -> Self { | ||
122 | Self { num_binders, value } | ||
123 | } | ||
124 | |||
125 | pub fn wrap_empty(value: T) -> Self | 121 | pub fn wrap_empty(value: T) -> Self |
126 | where | 122 | where |
127 | T: TypeWalk, | 123 | T: TypeWalk, |
128 | { | 124 | { |
129 | Self { num_binders: 0, value: value.shift_bound_vars(DebruijnIndex::ONE) } | 125 | Binders::empty(&Interner, value.shift_bound_vars(DebruijnIndex::ONE)) |
130 | } | ||
131 | |||
132 | pub fn as_ref(&self) -> Binders<&T> { | ||
133 | Binders { num_binders: self.num_binders, value: &self.value } | ||
134 | } | ||
135 | |||
136 | pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> { | ||
137 | Binders { num_binders: self.num_binders, value: f(self.value) } | ||
138 | } | ||
139 | |||
140 | pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { | ||
141 | Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) | ||
142 | } | ||
143 | |||
144 | pub fn skip_binders(&self) -> &T { | ||
145 | &self.value | ||
146 | } | ||
147 | |||
148 | pub fn into_value_and_skipped_binders(self) -> (T, usize) { | ||
149 | (self.value, self.num_binders) | ||
150 | } | 126 | } |
151 | } | 127 | } |
152 | 128 | ||
153 | impl<T: Clone> Binders<&T> { | 129 | impl<T: Clone> Binders<&T> { |
154 | pub fn cloned(&self) -> Binders<T> { | 130 | pub fn cloned(&self) -> Binders<T> { |
155 | Binders { num_binders: self.num_binders, value: self.value.clone() } | 131 | let (value, binders) = self.into_value_and_skipped_binders(); |
132 | Binders::new(binders, value.clone()) | ||
156 | } | 133 | } |
157 | } | 134 | } |
158 | 135 | ||
159 | impl<T: TypeWalk> Binders<T> { | 136 | impl<T: TypeWalk> Binders<T> { |
160 | /// Substitutes all variables. | 137 | /// Substitutes all variables. |
161 | pub fn subst(self, subst: &Substitution) -> T { | 138 | pub fn subst(self, subst: &Substitution) -> T { |
162 | assert_eq!(subst.len(&Interner), self.num_binders); | 139 | let (value, binders) = self.into_value_and_skipped_binders(); |
163 | self.value.subst_bound_vars(subst) | 140 | assert_eq!(subst.len(&Interner), binders); |
141 | value.subst_bound_vars(subst) | ||
164 | } | 142 | } |
165 | } | 143 | } |
166 | 144 | ||
@@ -334,12 +312,12 @@ impl Ty { | |||
334 | /// If this is a `dyn Trait` type, this returns the `Trait` part. | 312 | /// If this is a `dyn Trait` type, this returns the `Trait` part. |
335 | fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 313 | fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
336 | match self.kind(&Interner) { | 314 | match self.kind(&Interner) { |
337 | TyKind::Dyn(dyn_ty) => { | 315 | TyKind::Dyn(dyn_ty) => dyn_ty.bounds.skip_binders().interned().get(0).and_then(|b| { |
338 | dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() { | 316 | match b.skip_binders() { |
339 | WhereClause::Implemented(trait_ref) => Some(trait_ref), | 317 | WhereClause::Implemented(trait_ref) => Some(trait_ref), |
340 | _ => None, | 318 | _ => None, |
341 | }) | 319 | } |
342 | } | 320 | }), |
343 | _ => None, | 321 | _ => None, |
344 | } | 322 | } |
345 | } | 323 | } |
@@ -459,7 +437,7 @@ impl Ty { | |||
459 | ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(), | 437 | ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(), |
460 | }; | 438 | }; |
461 | 439 | ||
462 | predicates.map(|it| it.value) | 440 | predicates.map(|it| it.into_value_and_skipped_binders().0) |
463 | } | 441 | } |
464 | TyKind::Placeholder(idx) => { | 442 | TyKind::Placeholder(idx) => { |
465 | let id = from_placeholder_idx(db, *idx); | 443 | let id = from_placeholder_idx(db, *idx); |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index e9e4e69ad..19465b2ed 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -832,12 +832,15 @@ pub fn associated_type_shorthand_candidates<R>( | |||
832 | 832 | ||
833 | match res { | 833 | match res { |
834 | // FIXME: how to correctly handle higher-ranked bounds here? | 834 | // FIXME: how to correctly handle higher-ranked bounds here? |
835 | TypeNs::SelfType(impl_id) => { | 835 | TypeNs::SelfType(impl_id) => search( |
836 | search(db.impl_trait(impl_id)?.value.shift_bound_vars_out(DebruijnIndex::ONE)) | 836 | db.impl_trait(impl_id)? |
837 | } | 837 | .into_value_and_skipped_binders() |
838 | .0 | ||
839 | .shift_bound_vars_out(DebruijnIndex::ONE), | ||
840 | ), | ||
838 | TypeNs::GenericParam(param_id) => { | 841 | TypeNs::GenericParam(param_id) => { |
839 | let predicates = db.generic_predicates_for_param(param_id); | 842 | let predicates = db.generic_predicates_for_param(param_id); |
840 | let res = predicates.iter().find_map(|pred| match &pred.value.value { | 843 | let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() { |
841 | // FIXME: how to correctly handle higher-ranked bounds here? | 844 | // FIXME: how to correctly handle higher-ranked bounds here? |
842 | WhereClause::Implemented(tr) => { | 845 | WhereClause::Implemented(tr) => { |
843 | search(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE)) | 846 | search(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE)) |
@@ -1088,8 +1091,8 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS | |||
1088 | let ctx = | 1091 | let ctx = |
1089 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1092 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1090 | let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); | 1093 | let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); |
1091 | let ret = type_for_adt(db, def.into()); | 1094 | let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders(); |
1092 | Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) | 1095 | Binders::new(binders, CallableSig::from_params_and_return(params, ret, false)) |
1093 | } | 1096 | } |
1094 | 1097 | ||
1095 | /// Build the type of a tuple struct constructor. | 1098 | /// Build the type of a tuple struct constructor. |
@@ -1114,8 +1117,8 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) | |||
1114 | let ctx = | 1117 | let ctx = |
1115 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1118 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1116 | let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); | 1119 | let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); |
1117 | let ret = type_for_adt(db, def.parent.into()); | 1120 | let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders(); |
1118 | Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) | 1121 | Binders::new(binders, CallableSig::from_params_and_return(params, ret, false)) |
1119 | } | 1122 | } |
1120 | 1123 | ||
1121 | /// Build the type of a tuple enum variant constructor. | 1124 | /// Build the type of a tuple enum variant constructor. |
@@ -1267,9 +1270,9 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option< | |||
1267 | let resolver = impl_id.resolver(db.upcast()); | 1270 | let resolver = impl_id.resolver(db.upcast()); |
1268 | let ctx = | 1271 | let ctx = |
1269 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1272 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1270 | let self_ty = db.impl_self_ty(impl_id); | 1273 | let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders(); |
1271 | let target_trait = impl_data.target_trait.as_ref()?; | 1274 | let target_trait = impl_data.target_trait.as_ref()?; |
1272 | Some(Binders::new(self_ty.num_binders, ctx.lower_trait_ref(target_trait, Some(self_ty.value))?)) | 1275 | Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?)) |
1273 | } | 1276 | } |
1274 | 1277 | ||
1275 | pub(crate) fn return_type_impl_traits( | 1278 | pub(crate) fn return_type_impl_traits( |
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 6ace970d1..ad5022808 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -102,11 +102,11 @@ impl TraitImpls { | |||
102 | for (_module_id, module_data) in crate_def_map.modules() { | 102 | for (_module_id, module_data) in crate_def_map.modules() { |
103 | for impl_id in module_data.scope.impls() { | 103 | for impl_id in module_data.scope.impls() { |
104 | let target_trait = match db.impl_trait(impl_id) { | 104 | let target_trait = match db.impl_trait(impl_id) { |
105 | Some(tr) => tr.value.hir_trait_id(), | 105 | Some(tr) => tr.skip_binders().hir_trait_id(), |
106 | None => continue, | 106 | None => continue, |
107 | }; | 107 | }; |
108 | let self_ty = db.impl_self_ty(impl_id); | 108 | let self_ty = db.impl_self_ty(impl_id); |
109 | let self_ty_fp = TyFingerprint::for_impl(&self_ty.value); | 109 | let self_ty_fp = TyFingerprint::for_impl(self_ty.skip_binders()); |
110 | impls | 110 | impls |
111 | .map | 111 | .map |
112 | .entry(target_trait) | 112 | .entry(target_trait) |
@@ -201,7 +201,7 @@ impl InherentImpls { | |||
201 | } | 201 | } |
202 | 202 | ||
203 | let self_ty = db.impl_self_ty(impl_id); | 203 | let self_ty = db.impl_self_ty(impl_id); |
204 | if let Some(fp) = TyFingerprint::for_impl(&self_ty.value) { | 204 | if let Some(fp) = TyFingerprint::for_impl(self_ty.skip_binders()) { |
205 | map.entry(fp).or_default().push(impl_id); | 205 | map.entry(fp).or_default().push(impl_id); |
206 | } | 206 | } |
207 | } | 207 | } |
@@ -774,7 +774,7 @@ fn transform_receiver_ty( | |||
774 | AssocContainerId::ModuleId(_) => unreachable!(), | 774 | AssocContainerId::ModuleId(_) => unreachable!(), |
775 | }; | 775 | }; |
776 | let sig = db.callable_item_signature(function_id.into()); | 776 | let sig = db.callable_item_signature(function_id.into()); |
777 | Some(sig.value.params()[0].clone().subst_bound_vars(&substs)) | 777 | Some(sig.map(|s| s.params()[0].clone()).subst(&substs)) |
778 | } | 778 | } |
779 | 779 | ||
780 | pub fn implements_trait( | 780 | pub fn implements_trait( |
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs index b7388b98c..47867f77e 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/traits/chalk.rs | |||
@@ -184,10 +184,15 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
184 | .db | 184 | .db |
185 | .return_type_impl_traits(func) | 185 | .return_type_impl_traits(func) |
186 | .expect("impl trait id without impl traits"); | 186 | .expect("impl trait id without impl traits"); |
187 | let data = &datas.value.impl_traits[idx as usize]; | 187 | let data = &datas.skip_binders().impl_traits[idx as usize]; |
188 | let bound = OpaqueTyDatumBound { | 188 | let bound = OpaqueTyDatumBound { |
189 | bounds: make_binders( | 189 | bounds: make_binders( |
190 | data.bounds.value.iter().cloned().map(|b| b.to_chalk(self.db)).collect(), | 190 | data.bounds |
191 | .skip_binders() | ||
192 | .iter() | ||
193 | .cloned() | ||
194 | .map(|b| b.to_chalk(self.db)) | ||
195 | .collect(), | ||
191 | 1, | 196 | 1, |
192 | ), | 197 | ), |
193 | where_clauses: make_binders(vec![], 0), | 198 | where_clauses: make_binders(vec![], 0), |
@@ -535,7 +540,8 @@ fn impl_def_datum( | |||
535 | .impl_trait(impl_id) | 540 | .impl_trait(impl_id) |
536 | // ImplIds for impls where the trait ref can't be resolved should never reach Chalk | 541 | // ImplIds for impls where the trait ref can't be resolved should never reach Chalk |
537 | .expect("invalid impl passed to Chalk") | 542 | .expect("invalid impl passed to Chalk") |
538 | .value; | 543 | .into_value_and_skipped_binders() |
544 | .0; | ||
539 | let impl_data = db.impl_data(impl_id); | 545 | let impl_data = db.impl_data(impl_id); |
540 | 546 | ||
541 | let generic_params = generics(db.upcast(), impl_id.into()); | 547 | let generic_params = generics(db.upcast(), impl_id.into()); |
@@ -605,18 +611,22 @@ fn type_alias_associated_ty_value( | |||
605 | _ => panic!("assoc ty value should be in impl"), | 611 | _ => panic!("assoc ty value should be in impl"), |
606 | }; | 612 | }; |
607 | 613 | ||
608 | let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved | 614 | let trait_ref = db |
615 | .impl_trait(impl_id) | ||
616 | .expect("assoc ty value should not exist") | ||
617 | .into_value_and_skipped_binders() | ||
618 | .0; // we don't return any assoc ty values if the impl'd trait can't be resolved | ||
609 | 619 | ||
610 | let assoc_ty = db | 620 | let assoc_ty = db |
611 | .trait_data(trait_ref.hir_trait_id()) | 621 | .trait_data(trait_ref.hir_trait_id()) |
612 | .associated_type_by_name(&type_alias_data.name) | 622 | .associated_type_by_name(&type_alias_data.name) |
613 | .expect("assoc ty value should not exist"); // validated when building the impl data as well | 623 | .expect("assoc ty value should not exist"); // validated when building the impl data as well |
614 | let ty = db.ty(type_alias.into()); | 624 | let (ty, binders) = db.ty(type_alias.into()).into_value_and_skipped_binders(); |
615 | let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; | 625 | let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; |
616 | let value = rust_ir::AssociatedTyValue { | 626 | let value = rust_ir::AssociatedTyValue { |
617 | impl_id: impl_id.to_chalk(db), | 627 | impl_id: impl_id.to_chalk(db), |
618 | associated_ty_id: to_assoc_type_id(assoc_ty), | 628 | associated_ty_id: to_assoc_type_id(assoc_ty), |
619 | value: make_binders(value_bound, ty.num_binders), | 629 | value: make_binders(value_bound, binders), |
620 | }; | 630 | }; |
621 | Arc::new(value) | 631 | Arc::new(value) |
622 | } | 632 | } |
@@ -628,20 +638,15 @@ pub(crate) fn fn_def_datum_query( | |||
628 | ) -> Arc<FnDefDatum> { | 638 | ) -> Arc<FnDefDatum> { |
629 | let callable_def: CallableDefId = from_chalk(db, fn_def_id); | 639 | let callable_def: CallableDefId = from_chalk(db, fn_def_id); |
630 | let generic_params = generics(db.upcast(), callable_def.into()); | 640 | let generic_params = generics(db.upcast(), callable_def.into()); |
631 | let sig = db.callable_item_signature(callable_def); | 641 | let (sig, binders) = db.callable_item_signature(callable_def).into_value_and_skipped_binders(); |
632 | let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST); | 642 | let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST); |
633 | let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars); | 643 | let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars); |
634 | let bound = rust_ir::FnDefDatumBound { | 644 | let bound = rust_ir::FnDefDatumBound { |
635 | // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway | 645 | // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway |
636 | inputs_and_output: make_binders( | 646 | inputs_and_output: make_binders( |
637 | rust_ir::FnDefInputsAndOutputDatum { | 647 | rust_ir::FnDefInputsAndOutputDatum { |
638 | argument_types: sig | 648 | argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(db)).collect(), |
639 | .value | 649 | return_type: sig.ret().clone().to_chalk(db), |
640 | .params() | ||
641 | .iter() | ||
642 | .map(|ty| ty.clone().to_chalk(db)) | ||
643 | .collect(), | ||
644 | return_type: sig.value.ret().clone().to_chalk(db), | ||
645 | } | 650 | } |
646 | .shifted_in(&Interner), | 651 | .shifted_in(&Interner), |
647 | 0, | 652 | 0, |
@@ -650,12 +655,8 @@ pub(crate) fn fn_def_datum_query( | |||
650 | }; | 655 | }; |
651 | let datum = FnDefDatum { | 656 | let datum = FnDefDatum { |
652 | id: fn_def_id, | 657 | id: fn_def_id, |
653 | sig: chalk_ir::FnSig { | 658 | sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: sig.is_varargs }, |
654 | abi: (), | 659 | binders: make_binders(bound, binders), |
655 | safety: chalk_ir::Safety::Safe, | ||
656 | variadic: sig.value.is_varargs, | ||
657 | }, | ||
658 | binders: make_binders(bound, sig.num_binders), | ||
659 | }; | 660 | }; |
660 | Arc::new(datum) | 661 | Arc::new(datum) |
661 | } | 662 | } |
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 67e88ebf4..72458f367 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -93,12 +93,13 @@ impl ToChalk for Ty { | |||
93 | TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), | 93 | TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), |
94 | TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"), | 94 | TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"), |
95 | TyKind::Dyn(dyn_ty) => { | 95 | TyKind::Dyn(dyn_ty) => { |
96 | let (bounds, binders) = dyn_ty.bounds.into_value_and_skipped_binders(); | ||
96 | let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( | 97 | let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( |
97 | &Interner, | 98 | &Interner, |
98 | dyn_ty.bounds.value.interned().iter().cloned().map(|p| p.to_chalk(db)), | 99 | bounds.interned().iter().cloned().map(|p| p.to_chalk(db)), |
99 | ); | 100 | ); |
100 | let bounded_ty = chalk_ir::DynTy { | 101 | let bounded_ty = chalk_ir::DynTy { |
101 | bounds: make_binders(where_clauses, 1), | 102 | bounds: make_binders(where_clauses, binders), |
102 | lifetime: LifetimeData::Static.intern(&Interner), | 103 | lifetime: LifetimeData::Static.intern(&Interner), |
103 | }; | 104 | }; |
104 | chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner) | 105 | chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner) |
@@ -486,13 +487,14 @@ where | |||
486 | type Chalk = chalk_ir::Binders<T::Chalk>; | 487 | type Chalk = chalk_ir::Binders<T::Chalk>; |
487 | 488 | ||
488 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> { | 489 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> { |
490 | let (value, binders) = self.into_value_and_skipped_binders(); | ||
489 | chalk_ir::Binders::new( | 491 | chalk_ir::Binders::new( |
490 | chalk_ir::VariableKinds::from_iter( | 492 | chalk_ir::VariableKinds::from_iter( |
491 | &Interner, | 493 | &Interner, |
492 | std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)) | 494 | std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)) |
493 | .take(self.num_binders), | 495 | .take(binders), |
494 | ), | 496 | ), |
495 | self.value.to_chalk(db), | 497 | value.to_chalk(db), |
496 | ) | 498 | ) |
497 | } | 499 | } |
498 | 500 | ||
@@ -537,7 +539,8 @@ pub(super) fn generic_predicate_to_inline_bound( | |||
537 | // An InlineBound is like a GenericPredicate, except the self type is left out. | 539 | // An InlineBound is like a GenericPredicate, except the self type is left out. |
538 | // We don't have a special type for this, but Chalk does. | 540 | // We don't have a special type for this, but Chalk does. |
539 | let self_ty_shifted_in = self_ty.clone().shift_bound_vars(DebruijnIndex::ONE); | 541 | let self_ty_shifted_in = self_ty.clone().shift_bound_vars(DebruijnIndex::ONE); |
540 | match &pred.value { | 542 | let (pred, binders) = pred.as_ref().into_value_and_skipped_binders(); |
543 | match pred { | ||
541 | WhereClause::Implemented(trait_ref) => { | 544 | WhereClause::Implemented(trait_ref) => { |
542 | if trait_ref.self_type_parameter(&Interner) != &self_ty_shifted_in { | 545 | if trait_ref.self_type_parameter(&Interner) != &self_ty_shifted_in { |
543 | // we can only convert predicates back to type bounds if they | 546 | // we can only convert predicates back to type bounds if they |
@@ -549,7 +552,7 @@ pub(super) fn generic_predicate_to_inline_bound( | |||
549 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) | 552 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) |
550 | .collect(); | 553 | .collect(); |
551 | let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; | 554 | let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; |
552 | Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), pred.num_binders)) | 555 | Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), binders)) |
553 | } | 556 | } |
554 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { | 557 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { |
555 | if projection_ty.self_type_parameter(&Interner) != &self_ty_shifted_in { | 558 | if projection_ty.self_type_parameter(&Interner) != &self_ty_shifted_in { |
@@ -566,7 +569,7 @@ pub(super) fn generic_predicate_to_inline_bound( | |||
566 | associated_ty_id: projection_ty.associated_ty_id, | 569 | associated_ty_id: projection_ty.associated_ty_id, |
567 | parameters: Vec::new(), // FIXME we don't support generic associated types yet | 570 | parameters: Vec::new(), // FIXME we don't support generic associated types yet |
568 | }; | 571 | }; |
569 | Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), pred.num_binders)) | 572 | Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), binders)) |
570 | } | 573 | } |
571 | _ => None, | 574 | _ => None, |
572 | } | 575 | } |
diff --git a/crates/hir_ty/src/types.rs b/crates/hir_ty/src/types.rs index bac086318..0e3dd511f 100644 --- a/crates/hir_ty/src/types.rs +++ b/crates/hir_ty/src/types.rs | |||
@@ -299,7 +299,41 @@ impl Substitution { | |||
299 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 299 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
300 | pub struct Binders<T> { | 300 | pub struct Binders<T> { |
301 | pub num_binders: usize, | 301 | pub num_binders: usize, |
302 | pub value: T, | 302 | value: T, |
303 | } | ||
304 | |||
305 | impl<T> Binders<T> { | ||
306 | pub fn new(num_binders: usize, value: T) -> Self { | ||
307 | Self { num_binders, value } | ||
308 | } | ||
309 | |||
310 | pub fn empty(_interner: &Interner, value: T) -> Self { | ||
311 | Self { num_binders: 0, value } | ||
312 | } | ||
313 | |||
314 | pub fn as_ref(&self) -> Binders<&T> { | ||
315 | Binders { num_binders: self.num_binders, value: &self.value } | ||
316 | } | ||
317 | |||
318 | pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> { | ||
319 | Binders { num_binders: self.num_binders, value: f(self.value) } | ||
320 | } | ||
321 | |||
322 | pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { | ||
323 | Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) | ||
324 | } | ||
325 | |||
326 | pub fn skip_binders(&self) -> &T { | ||
327 | &self.value | ||
328 | } | ||
329 | |||
330 | pub fn into_value_and_skipped_binders(self) -> (T, usize) { | ||
331 | (self.value, self.num_binders) | ||
332 | } | ||
333 | |||
334 | pub fn skip_binders_mut(&mut self) -> &mut T { | ||
335 | &mut self.value | ||
336 | } | ||
303 | } | 337 | } |
304 | 338 | ||
305 | /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. | 339 | /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. |
diff --git a/crates/hir_ty/src/walk.rs b/crates/hir_ty/src/walk.rs index 5dfd59746..b1e22da0a 100644 --- a/crates/hir_ty/src/walk.rs +++ b/crates/hir_ty/src/walk.rs | |||
@@ -139,7 +139,7 @@ impl TypeWalk for Ty { | |||
139 | } | 139 | } |
140 | } | 140 | } |
141 | TyKind::Dyn(dyn_ty) => { | 141 | TyKind::Dyn(dyn_ty) => { |
142 | for p in dyn_ty.bounds.value.interned().iter() { | 142 | for p in dyn_ty.bounds.skip_binders().interned().iter() { |
143 | p.walk(f); | 143 | p.walk(f); |
144 | } | 144 | } |
145 | } | 145 | } |
@@ -167,7 +167,7 @@ impl TypeWalk for Ty { | |||
167 | p_ty.substitution.walk_mut_binders(f, binders); | 167 | p_ty.substitution.walk_mut_binders(f, binders); |
168 | } | 168 | } |
169 | TyKind::Dyn(dyn_ty) => { | 169 | TyKind::Dyn(dyn_ty) => { |
170 | for p in make_mut_slice(dyn_ty.bounds.value.interned_mut()) { | 170 | for p in make_mut_slice(dyn_ty.bounds.skip_binders_mut().interned_mut()) { |
171 | p.walk_mut_binders(f, binders.shifted_in()); | 171 | p.walk_mut_binders(f, binders.shifted_in()); |
172 | } | 172 | } |
173 | } | 173 | } |
@@ -294,7 +294,7 @@ impl TypeWalk for Substitution { | |||
294 | 294 | ||
295 | impl<T: TypeWalk> TypeWalk for Binders<T> { | 295 | impl<T: TypeWalk> TypeWalk for Binders<T> { |
296 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 296 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
297 | self.value.walk(f); | 297 | self.skip_binders().walk(f); |
298 | } | 298 | } |
299 | 299 | ||
300 | fn walk_mut_binders( | 300 | fn walk_mut_binders( |
@@ -302,7 +302,7 @@ impl<T: TypeWalk> TypeWalk for Binders<T> { | |||
302 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | 302 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), |
303 | binders: DebruijnIndex, | 303 | binders: DebruijnIndex, |
304 | ) { | 304 | ) { |
305 | self.value.walk_mut_binders(f, binders.shifted_in()) | 305 | self.skip_binders_mut().walk_mut_binders(f, binders.shifted_in()) |
306 | } | 306 | } |
307 | } | 307 | } |
308 | 308 | ||