diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-04-05 18:25:19 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-04-05 18:25:19 +0100 |
commit | c91b5376835ab54cd4bca02953625ef1f1fabeba (patch) | |
tree | 390be0ec3c0a57db5188b06c86f0a7df0242b01c /crates/hir_ty | |
parent | 467a5c6cd13af6ccb76e9ebdb35f96fc10fb438f (diff) | |
parent | a316d583600e11ee1fcc8027a838efafe435f03c (diff) |
Merge #8348
8348: Make `Binders` more like Chalk r=flodiebold a=flodiebold
Working towards #8313.
- hide `value`
- use `VariableKinds`
- adjust `subst` to be like Chalk's `substitute`
- also clean up some other `TypeWalk` stuff to prepare for it being replaced by Chalk's `Fold`
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/builder.rs | 7 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 3 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 18 | ||||
-rw-r--r-- | crates/hir_ty/src/infer.rs | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 18 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 9 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/path.rs | 7 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 21 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 75 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 135 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 10 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 47 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 33 | ||||
-rw-r--r-- | crates/hir_ty/src/types.rs | 69 | ||||
-rw-r--r-- | crates/hir_ty/src/utils.rs | 12 | ||||
-rw-r--r-- | crates/hir_ty/src/walk.rs | 30 |
16 files changed, 284 insertions, 218 deletions
diff --git a/crates/hir_ty/src/builder.rs b/crates/hir_ty/src/builder.rs index 372621f73..9b2c6975a 100644 --- a/crates/hir_ty/src/builder.rs +++ b/crates/hir_ty/src/builder.rs | |||
@@ -139,7 +139,8 @@ impl TyBuilder<hir_def::AdtId> { | |||
139 | } else { | 139 | } else { |
140 | // each default can depend on the previous parameters | 140 | // each default can depend on the previous parameters |
141 | let subst_so_far = Substitution::intern(self.vec.clone()); | 141 | let subst_so_far = Substitution::intern(self.vec.clone()); |
142 | self.vec.push(default_ty.clone().subst(&subst_so_far).cast(&Interner)); | 142 | self.vec |
143 | .push(default_ty.clone().substitute(&Interner, &subst_so_far).cast(&Interner)); | ||
143 | } | 144 | } |
144 | } | 145 | } |
145 | self | 146 | self |
@@ -194,13 +195,13 @@ impl TyBuilder<TypeAliasId> { | |||
194 | 195 | ||
195 | impl<T: TypeWalk + HasInterner<Interner = Interner>> TyBuilder<Binders<T>> { | 196 | impl<T: TypeWalk + HasInterner<Interner = Interner>> TyBuilder<Binders<T>> { |
196 | fn subst_binders(b: Binders<T>) -> Self { | 197 | fn subst_binders(b: Binders<T>) -> Self { |
197 | let param_count = b.num_binders; | 198 | let param_count = b.binders.len(&Interner); |
198 | TyBuilder::new(b, param_count) | 199 | TyBuilder::new(b, param_count) |
199 | } | 200 | } |
200 | 201 | ||
201 | pub fn build(self) -> T { | 202 | pub fn build(self) -> T { |
202 | let (b, subst) = self.build_internal(); | 203 | let (b, subst) = self.build_internal(); |
203 | b.subst(&subst) | 204 | b.substitute(&Interner, &subst) |
204 | } | 205 | } |
205 | } | 206 | } |
206 | 207 | ||
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..f31e6b108 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -352,8 +352,8 @@ impl HirDisplay for Ty { | |||
352 | let data = (*datas) | 352 | let data = (*datas) |
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.substitute(&Interner, parameters); |
356 | bounds.value | 356 | bounds.into_value_and_skipped_binders().0 |
357 | } else { | 357 | } else { |
358 | Vec::new() | 358 | Vec::new() |
359 | } | 359 | } |
@@ -397,7 +397,7 @@ impl HirDisplay for Ty { | |||
397 | } | 397 | } |
398 | TyKind::FnDef(def, parameters) => { | 398 | TyKind::FnDef(def, parameters) => { |
399 | let def = from_chalk(f.db, *def); | 399 | let def = from_chalk(f.db, *def); |
400 | let sig = f.db.callable_item_signature(def).subst(parameters); | 400 | let sig = f.db.callable_item_signature(def).substitute(&Interner, parameters); |
401 | match def { | 401 | match def { |
402 | CallableDefId::FunctionId(ff) => { | 402 | CallableDefId::FunctionId(ff) => { |
403 | write!(f, "fn {}", f.db.function_data(ff).name)? | 403 | write!(f, "fn {}", f.db.function_data(ff).name)? |
@@ -482,7 +482,7 @@ impl HirDisplay for Ty { | |||
482 | (_, Some(default_parameter)) => { | 482 | (_, Some(default_parameter)) => { |
483 | let actual_default = default_parameter | 483 | let actual_default = default_parameter |
484 | .clone() | 484 | .clone() |
485 | .subst(¶meters.prefix(i)); | 485 | .substitute(&Interner, ¶meters.prefix(i)); |
486 | if parameter.assert_ty_ref(&Interner) != &actual_default | 486 | if parameter.assert_ty_ref(&Interner) != &actual_default |
487 | { | 487 | { |
488 | default_from = i + 1; | 488 | default_from = i + 1; |
@@ -542,8 +542,8 @@ impl HirDisplay for Ty { | |||
542 | let data = (*datas) | 542 | let data = (*datas) |
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.substitute(&Interner, ¶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(..) => { |
@@ -595,7 +595,7 @@ impl HirDisplay for Ty { | |||
595 | let bounds = | 595 | let bounds = |
596 | f.db.generic_predicates(id.parent) | 596 | f.db.generic_predicates(id.parent) |
597 | .into_iter() | 597 | .into_iter() |
598 | .map(|pred| pred.clone().subst(&substs)) | 598 | .map(|pred| pred.clone().substitute(&Interner, &substs)) |
599 | .filter(|wc| match &wc.skip_binders() { | 599 | .filter(|wc| match &wc.skip_binders() { |
600 | WhereClause::Implemented(tr) => { | 600 | WhereClause::Implemented(tr) => { |
601 | tr.self_type_parameter(&Interner) == self | 601 | tr.self_type_parameter(&Interner) == self |
@@ -629,8 +629,8 @@ impl HirDisplay for Ty { | |||
629 | let data = (*datas) | 629 | let data = (*datas) |
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.substitute(&Interner, &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/infer.rs b/crates/hir_ty/src/infer.rs index 6151e48cd..1c3faf5cb 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -470,25 +470,25 @@ impl<'a> InferenceContext<'a> { | |||
470 | TypeNs::AdtId(AdtId::StructId(strukt)) => { | 470 | TypeNs::AdtId(AdtId::StructId(strukt)) => { |
471 | let substs = ctx.substs_from_path(path, strukt.into(), true); | 471 | let substs = ctx.substs_from_path(path, strukt.into(), true); |
472 | let ty = self.db.ty(strukt.into()); | 472 | let ty = self.db.ty(strukt.into()); |
473 | let ty = self.insert_type_vars(ty.subst(&substs)); | 473 | let ty = self.insert_type_vars(ty.substitute(&Interner, &substs)); |
474 | forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) | 474 | forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) |
475 | } | 475 | } |
476 | TypeNs::AdtId(AdtId::UnionId(u)) => { | 476 | TypeNs::AdtId(AdtId::UnionId(u)) => { |
477 | let substs = ctx.substs_from_path(path, u.into(), true); | 477 | let substs = ctx.substs_from_path(path, u.into(), true); |
478 | let ty = self.db.ty(u.into()); | 478 | let ty = self.db.ty(u.into()); |
479 | let ty = self.insert_type_vars(ty.subst(&substs)); | 479 | let ty = self.insert_type_vars(ty.substitute(&Interner, &substs)); |
480 | forbid_unresolved_segments((ty, Some(u.into())), unresolved) | 480 | forbid_unresolved_segments((ty, Some(u.into())), unresolved) |
481 | } | 481 | } |
482 | TypeNs::EnumVariantId(var) => { | 482 | TypeNs::EnumVariantId(var) => { |
483 | let substs = ctx.substs_from_path(path, var.into(), true); | 483 | let substs = ctx.substs_from_path(path, var.into(), true); |
484 | let ty = self.db.ty(var.parent.into()); | 484 | let ty = self.db.ty(var.parent.into()); |
485 | let ty = self.insert_type_vars(ty.subst(&substs)); | 485 | let ty = self.insert_type_vars(ty.substitute(&Interner, &substs)); |
486 | forbid_unresolved_segments((ty, Some(var.into())), unresolved) | 486 | forbid_unresolved_segments((ty, Some(var.into())), unresolved) |
487 | } | 487 | } |
488 | TypeNs::SelfType(impl_id) => { | 488 | TypeNs::SelfType(impl_id) => { |
489 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); | 489 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); |
490 | let substs = generics.type_params_subst(self.db); | 490 | let substs = generics.type_params_subst(self.db); |
491 | let ty = self.db.impl_self_ty(impl_id).subst(&substs); | 491 | let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs); |
492 | match unresolved { | 492 | match unresolved { |
493 | None => { | 493 | None => { |
494 | let variant = ty_variant(&ty); | 494 | let variant = ty_variant(&ty); |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index ccaae53e9..6966d26e7 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -419,7 +419,7 @@ impl<'a> InferenceContext<'a> { | |||
419 | self.result.record_field_resolutions.insert(field.expr, field_def); | 419 | self.result.record_field_resolutions.insert(field.expr, field_def); |
420 | } | 420 | } |
421 | let field_ty = field_def.map_or(self.err_ty(), |it| { | 421 | let field_ty = field_def.map_or(self.err_ty(), |it| { |
422 | field_types[it.local_id].clone().subst(&substs) | 422 | field_types[it.local_id].clone().substitute(&Interner, &substs) |
423 | }); | 423 | }); |
424 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); | 424 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); |
425 | } | 425 | } |
@@ -462,7 +462,7 @@ impl<'a> InferenceContext<'a> { | |||
462 | Some( | 462 | Some( |
463 | self.db.field_types((*s).into())[field.local_id] | 463 | self.db.field_types((*s).into())[field.local_id] |
464 | .clone() | 464 | .clone() |
465 | .subst(¶meters), | 465 | .substitute(&Interner, ¶meters), |
466 | ) | 466 | ) |
467 | } else { | 467 | } else { |
468 | None | 468 | None |
@@ -476,7 +476,7 @@ impl<'a> InferenceContext<'a> { | |||
476 | Some( | 476 | Some( |
477 | self.db.field_types((*u).into())[field.local_id] | 477 | self.db.field_types((*u).into())[field.local_id] |
478 | .clone() | 478 | .clone() |
479 | .subst(¶meters), | 479 | .substitute(&Interner, ¶meters), |
480 | ) | 480 | ) |
481 | } else { | 481 | } else { |
482 | None | 482 | None |
@@ -849,10 +849,10 @@ impl<'a> InferenceContext<'a> { | |||
849 | self.write_method_resolution(tgt_expr, func); | 849 | self.write_method_resolution(tgt_expr, func); |
850 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) | 850 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) |
851 | } | 851 | } |
852 | None => (receiver_ty, Binders::new(0, self.err_ty()), None), | 852 | None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None), |
853 | }; | 853 | }; |
854 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); | 854 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); |
855 | let method_ty = method_ty.subst(&substs); | 855 | let method_ty = method_ty.substitute(&Interner, &substs); |
856 | let method_ty = self.insert_type_vars(method_ty); | 856 | let method_ty = self.insert_type_vars(method_ty); |
857 | self.register_obligations_for_call(&method_ty); | 857 | self.register_obligations_for_call(&method_ty); |
858 | let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { | 858 | let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { |
@@ -949,9 +949,11 @@ impl<'a> InferenceContext<'a> { | |||
949 | let def: CallableDefId = from_chalk(self.db, *fn_def); | 949 | let def: CallableDefId = from_chalk(self.db, *fn_def); |
950 | let generic_predicates = self.db.generic_predicates(def.into()); | 950 | let generic_predicates = self.db.generic_predicates(def.into()); |
951 | for predicate in generic_predicates.iter() { | 951 | for predicate in generic_predicates.iter() { |
952 | let (predicate, binders) = | 952 | let (predicate, binders) = predicate |
953 | predicate.clone().subst(parameters).into_value_and_skipped_binders(); | 953 | .clone() |
954 | always!(binders == 0); // quantified where clauses not yet handled | 954 | .substitute(&Interner, parameters) |
955 | .into_value_and_skipped_binders(); | ||
956 | always!(binders.len(&Interner) == 0); // quantified where clauses not yet handled | ||
955 | self.push_obligation(predicate.cast(&Interner)); | 957 | self.push_obligation(predicate.cast(&Interner)); |
956 | } | 958 | } |
957 | // add obligation for trait implementation, if this is a trait method | 959 | // add obligation for trait implementation, if this is a trait method |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index 469f37dd9..252ae914a 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -49,7 +49,9 @@ impl<'a> InferenceContext<'a> { | |||
49 | let expected_ty = var_data | 49 | let expected_ty = var_data |
50 | .as_ref() | 50 | .as_ref() |
51 | .and_then(|d| d.field(&Name::new_tuple_field(i))) | 51 | .and_then(|d| d.field(&Name::new_tuple_field(i))) |
52 | .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs)); | 52 | .map_or(self.err_ty(), |field| { |
53 | field_tys[field].clone().substitute(&Interner, &substs) | ||
54 | }); | ||
53 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 55 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
54 | self.infer_pat(subpat, &expected_ty, default_bm); | 56 | self.infer_pat(subpat, &expected_ty, default_bm); |
55 | } | 57 | } |
@@ -83,8 +85,9 @@ impl<'a> InferenceContext<'a> { | |||
83 | self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); | 85 | self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); |
84 | } | 86 | } |
85 | 87 | ||
86 | let expected_ty = matching_field | 88 | let expected_ty = matching_field.map_or(self.err_ty(), |field| { |
87 | .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs)); | 89 | field_tys[field].clone().substitute(&Interner, &substs) |
90 | }); | ||
88 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 91 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
89 | self.infer_pat(subpat.pat, &expected_ty, default_bm); | 92 | self.infer_pat(subpat.pat, &expected_ty, default_bm); |
90 | } | 93 | } |
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index 89d78e781..14f705173 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs | |||
@@ -81,9 +81,9 @@ impl<'a> InferenceContext<'a> { | |||
81 | ValueNs::ImplSelf(impl_id) => { | 81 | ValueNs::ImplSelf(impl_id) => { |
82 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); | 82 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); |
83 | let substs = generics.type_params_subst(self.db); | 83 | let substs = generics.type_params_subst(self.db); |
84 | let ty = self.db.impl_self_ty(impl_id).subst(&substs); | 84 | let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs); |
85 | if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { | 85 | if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { |
86 | let ty = self.db.value_ty(struct_id.into()).subst(&substs); | 86 | let ty = self.db.value_ty(struct_id.into()).substitute(&Interner, &substs); |
87 | return Some(ty); | 87 | return Some(ty); |
88 | } else { | 88 | } else { |
89 | // FIXME: diagnostic, invalid Self reference | 89 | // FIXME: diagnostic, invalid Self reference |
@@ -243,7 +243,8 @@ impl<'a> InferenceContext<'a> { | |||
243 | let impl_substs = TyBuilder::subst_for_def(self.db, impl_id) | 243 | let impl_substs = TyBuilder::subst_for_def(self.db, impl_id) |
244 | .fill(iter::repeat_with(|| self.table.new_type_var())) | 244 | .fill(iter::repeat_with(|| self.table.new_type_var())) |
245 | .build(); | 245 | .build(); |
246 | let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs); | 246 | let impl_self_ty = |
247 | self.db.impl_self_ty(impl_id).substitute(&Interner, &impl_substs); | ||
247 | self.unify(&impl_self_ty, &ty); | 248 | self.unify(&impl_self_ty, &ty); |
248 | Some(impl_substs) | 249 | Some(impl_substs) |
249 | } | 250 | } |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 8370f2e1c..c90a16720 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -108,19 +108,22 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
108 | } | 108 | } |
109 | 109 | ||
110 | impl<T> Canonicalized<T> { | 110 | impl<T> Canonicalized<T> { |
111 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { | 111 | pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty { |
112 | ty.walk_mut_binders( | 112 | ty.fold_binders( |
113 | &mut |ty, binders| { | 113 | &mut |ty, binders| { |
114 | if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { | 114 | if let TyKind::BoundVar(bound) = ty.kind(&Interner) { |
115 | if bound.debruijn >= binders { | 115 | if bound.debruijn >= binders { |
116 | let (v, k) = self.free_vars[bound.index]; | 116 | let (v, k) = self.free_vars[bound.index]; |
117 | *ty = TyKind::InferenceVar(v, k).intern(&Interner); | 117 | TyKind::InferenceVar(v, k).intern(&Interner) |
118 | } else { | ||
119 | ty | ||
118 | } | 120 | } |
121 | } else { | ||
122 | ty | ||
119 | } | 123 | } |
120 | }, | 124 | }, |
121 | DebruijnIndex::INNERMOST, | 125 | DebruijnIndex::INNERMOST, |
122 | ); | 126 | ) |
123 | ty | ||
124 | } | 127 | } |
125 | 128 | ||
126 | pub(super) fn apply_solution( | 129 | pub(super) fn apply_solution( |
@@ -149,7 +152,7 @@ impl<T> Canonicalized<T> { | |||
149 | // eagerly replace projections in the type; we may be getting types | 152 | // eagerly replace projections in the type; we may be getting types |
150 | // e.g. from where clauses where this hasn't happened yet | 153 | // e.g. from where clauses where this hasn't happened yet |
151 | let ty = ctx.normalize_associated_types_in( | 154 | let ty = ctx.normalize_associated_types_in( |
152 | ty.assert_ty_ref(&Interner).clone().subst_bound_vars(&new_vars), | 155 | new_vars.apply(ty.assert_ty_ref(&Interner).clone(), &Interner), |
153 | ); | 156 | ); |
154 | ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); | 157 | ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); |
155 | } | 158 | } |
@@ -170,8 +173,8 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { | |||
170 | // fallback to Unknown in the end (kind of hacky, as below) | 173 | // fallback to Unknown in the end (kind of hacky, as below) |
171 | .map(|_| table.new_type_var()), | 174 | .map(|_| table.new_type_var()), |
172 | ); | 175 | ); |
173 | let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars); | 176 | let ty1_with_vars = vars.apply(tys.value.0.clone(), &Interner); |
174 | let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars); | 177 | let ty2_with_vars = vars.apply(tys.value.1.clone(), &Interner); |
175 | if !table.unify(&ty1_with_vars, &ty2_with_vars) { | 178 | if !table.unify(&ty1_with_vars, &ty2_with_vars) { |
176 | return None; | 179 | return None; |
177 | } | 180 | } |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index adfdcaa37..daf379ef8 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -66,6 +66,8 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>; | |||
66 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | 66 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; |
67 | pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; | 67 | pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; |
68 | 68 | ||
69 | pub type VariableKind = chalk_ir::VariableKind<Interner>; | ||
70 | pub type VariableKinds = chalk_ir::VariableKinds<Interner>; | ||
69 | pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; | 71 | pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; |
70 | 72 | ||
71 | pub type ChalkTraitId = chalk_ir::TraitId<Interner>; | 73 | pub type ChalkTraitId = chalk_ir::TraitId<Interner>; |
@@ -118,52 +120,34 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> { | |||
118 | } | 120 | } |
119 | 121 | ||
120 | impl<T> Binders<T> { | 122 | 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 | 123 | pub fn wrap_empty(value: T) -> Self |
126 | where | 124 | where |
127 | T: TypeWalk, | 125 | T: TypeWalk, |
128 | { | 126 | { |
129 | Self { num_binders: 0, value: value.shift_bound_vars(DebruijnIndex::ONE) } | 127 | Binders::empty(&Interner, value.shifted_in_from(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 | } | ||
151 | } | ||
152 | |||
153 | impl<T: Clone> Binders<&T> { | ||
154 | pub fn cloned(&self) -> Binders<T> { | ||
155 | Binders { num_binders: self.num_binders, value: self.value.clone() } | ||
156 | } | 128 | } |
157 | } | 129 | } |
158 | 130 | ||
159 | impl<T: TypeWalk> Binders<T> { | 131 | impl<T: TypeWalk> Binders<T> { |
160 | /// Substitutes all variables. | 132 | /// Substitutes all variables. |
161 | pub fn subst(self, subst: &Substitution) -> T { | 133 | pub fn substitute(self, interner: &Interner, subst: &Substitution) -> T { |
162 | assert_eq!(subst.len(&Interner), self.num_binders); | 134 | let (value, binders) = self.into_value_and_skipped_binders(); |
163 | self.value.subst_bound_vars(subst) | 135 | assert_eq!(subst.len(interner), binders.len(interner)); |
136 | value.subst_bound_vars(subst) | ||
164 | } | 137 | } |
165 | } | 138 | } |
166 | 139 | ||
140 | pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> { | ||
141 | Binders::new( | ||
142 | VariableKinds::from_iter( | ||
143 | &Interner, | ||
144 | std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)) | ||
145 | .take(num_vars), | ||
146 | ), | ||
147 | value, | ||
148 | ) | ||
149 | } | ||
150 | |||
167 | impl TraitRef { | 151 | impl TraitRef { |
168 | pub fn self_type_parameter(&self, interner: &Interner) -> &Ty { | 152 | pub fn self_type_parameter(&self, interner: &Interner) -> &Ty { |
169 | &self.substitution.at(interner, 0).assert_ty_ref(interner) | 153 | &self.substitution.at(interner, 0).assert_ty_ref(interner) |
@@ -225,7 +209,8 @@ impl CallableSig { | |||
225 | params_and_return: fn_ptr | 209 | params_and_return: fn_ptr |
226 | .substs | 210 | .substs |
227 | .clone() | 211 | .clone() |
228 | .shift_bound_vars_out(DebruijnIndex::ONE) | 212 | .shifted_out_to(DebruijnIndex::ONE) |
213 | .expect("unexpected lifetime vars in fn ptr") | ||
229 | .interned() | 214 | .interned() |
230 | .iter() | 215 | .iter() |
231 | .map(|arg| arg.assert_ty_ref(&Interner).clone()) | 216 | .map(|arg| arg.assert_ty_ref(&Interner).clone()) |
@@ -334,12 +319,12 @@ impl Ty { | |||
334 | /// If this is a `dyn Trait` type, this returns the `Trait` part. | 319 | /// If this is a `dyn Trait` type, this returns the `Trait` part. |
335 | fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 320 | fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
336 | match self.kind(&Interner) { | 321 | match self.kind(&Interner) { |
337 | TyKind::Dyn(dyn_ty) => { | 322 | 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() { | 323 | match b.skip_binders() { |
339 | WhereClause::Implemented(trait_ref) => Some(trait_ref), | 324 | WhereClause::Implemented(trait_ref) => Some(trait_ref), |
340 | _ => None, | 325 | _ => None, |
341 | }) | 326 | } |
342 | } | 327 | }), |
343 | _ => None, | 328 | _ => None, |
344 | } | 329 | } |
345 | } | 330 | } |
@@ -378,7 +363,7 @@ impl Ty { | |||
378 | TyKind::FnDef(def, parameters) => { | 363 | TyKind::FnDef(def, parameters) => { |
379 | let callable_def = db.lookup_intern_callable_def((*def).into()); | 364 | let callable_def = db.lookup_intern_callable_def((*def).into()); |
380 | let sig = db.callable_item_signature(callable_def); | 365 | let sig = db.callable_item_signature(callable_def); |
381 | Some(sig.subst(¶meters)) | 366 | Some(sig.substitute(&Interner, ¶meters)) |
382 | } | 367 | } |
383 | TyKind::Closure(.., substs) => { | 368 | TyKind::Closure(.., substs) => { |
384 | let sig_param = substs.at(&Interner, 0).assert_ty_ref(&Interner); | 369 | let sig_param = substs.at(&Interner, 0).assert_ty_ref(&Interner); |
@@ -429,8 +414,8 @@ impl Ty { | |||
429 | // This is only used by type walking. | 414 | // This is only used by type walking. |
430 | // Parameters will be walked outside, and projection predicate is not used. | 415 | // Parameters will be walked outside, and projection predicate is not used. |
431 | // So just provide the Future trait. | 416 | // So just provide the Future trait. |
432 | let impl_bound = Binders::new( | 417 | let impl_bound = Binders::empty( |
433 | 0, | 418 | &Interner, |
434 | WhereClause::Implemented(TraitRef { | 419 | WhereClause::Implemented(TraitRef { |
435 | trait_id: to_chalk_trait_id(future_trait), | 420 | trait_id: to_chalk_trait_id(future_trait), |
436 | substitution: Substitution::empty(&Interner), | 421 | substitution: Substitution::empty(&Interner), |
@@ -452,14 +437,14 @@ impl Ty { | |||
452 | let data = (*it) | 437 | let data = (*it) |
453 | .as_ref() | 438 | .as_ref() |
454 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 439 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
455 | data.subst(&opaque_ty.substitution) | 440 | data.substitute(&Interner, &opaque_ty.substitution) |
456 | }) | 441 | }) |
457 | } | 442 | } |
458 | // It always has an parameter for Future::Output type. | 443 | // It always has an parameter for Future::Output type. |
459 | ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(), | 444 | ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(), |
460 | }; | 445 | }; |
461 | 446 | ||
462 | predicates.map(|it| it.value) | 447 | predicates.map(|it| it.into_value_and_skipped_binders().0) |
463 | } | 448 | } |
464 | TyKind::Placeholder(idx) => { | 449 | TyKind::Placeholder(idx) => { |
465 | let id = from_placeholder_idx(db, *idx); | 450 | let id = from_placeholder_idx(db, *idx); |
@@ -471,7 +456,7 @@ impl Ty { | |||
471 | let predicates = db | 456 | let predicates = db |
472 | .generic_predicates(id.parent) | 457 | .generic_predicates(id.parent) |
473 | .into_iter() | 458 | .into_iter() |
474 | .map(|pred| pred.clone().subst(&substs)) | 459 | .map(|pred| pred.clone().substitute(&Interner, &substs)) |
475 | .filter(|wc| match &wc.skip_binders() { | 460 | .filter(|wc| match &wc.skip_binders() { |
476 | WhereClause::Implemented(tr) => { | 461 | WhereClause::Implemented(tr) => { |
477 | tr.self_type_parameter(&Interner) == self | 462 | tr.self_type_parameter(&Interner) == self |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index e9e4e69ad..48c26f471 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -31,7 +31,7 @@ use crate::{ | |||
31 | traits::chalk::{Interner, ToChalk}, | 31 | traits::chalk::{Interner, ToChalk}, |
32 | utils::{ | 32 | utils::{ |
33 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, | 33 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, |
34 | variant_data, | 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 | ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, |
@@ -196,7 +196,7 @@ impl<'a> TyLoweringContext<'a> { | |||
196 | bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)), | 196 | bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)), |
197 | ) | 197 | ) |
198 | }); | 198 | }); |
199 | let bounds = Binders::new(1, bounds); | 199 | let bounds = crate::make_only_type_binders(1, bounds); |
200 | TyKind::Dyn(DynTy { bounds }).intern(&Interner) | 200 | TyKind::Dyn(DynTy { bounds }).intern(&Interner) |
201 | } | 201 | } |
202 | TypeRef::ImplTrait(bounds) => { | 202 | TypeRef::ImplTrait(bounds) => { |
@@ -209,9 +209,9 @@ impl<'a> TyLoweringContext<'a> { | |||
209 | // this dance is to make sure the data is in the right | 209 | // this dance is to make sure the data is in the right |
210 | // place even if we encounter more opaque types while | 210 | // place even if we encounter more opaque types while |
211 | // lowering the bounds | 211 | // lowering the bounds |
212 | self.opaque_type_data | 212 | self.opaque_type_data.borrow_mut().push(ReturnTypeImplTrait { |
213 | .borrow_mut() | 213 | bounds: crate::make_only_type_binders(1, Vec::new()), |
214 | .push(ReturnTypeImplTrait { bounds: Binders::new(1, Vec::new()) }); | 214 | }); |
215 | // We don't want to lower the bounds inside the binders | 215 | // We don't want to lower the bounds inside the binders |
216 | // we're currently in, because they don't end up inside | 216 | // we're currently in, because they don't end up inside |
217 | // those binders. E.g. when we have `impl Trait<impl | 217 | // those binders. E.g. when we have `impl Trait<impl |
@@ -380,7 +380,7 @@ impl<'a> TyLoweringContext<'a> { | |||
380 | TyKind::Error.intern(&Interner) | 380 | TyKind::Error.intern(&Interner) |
381 | } else { | 381 | } else { |
382 | let dyn_ty = DynTy { | 382 | let dyn_ty = DynTy { |
383 | bounds: Binders::new( | 383 | bounds: crate::make_only_type_binders( |
384 | 1, | 384 | 1, |
385 | QuantifiedWhereClauses::from_iter( | 385 | QuantifiedWhereClauses::from_iter( |
386 | &Interner, | 386 | &Interner, |
@@ -414,7 +414,7 @@ impl<'a> TyLoweringContext<'a> { | |||
414 | TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db), | 414 | TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db), |
415 | TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders), | 415 | TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders), |
416 | }; | 416 | }; |
417 | self.db.impl_self_ty(impl_id).subst(&substs) | 417 | self.db.impl_self_ty(impl_id).substitute(&Interner, &substs) |
418 | } | 418 | } |
419 | TypeNs::AdtSelfType(adt) => { | 419 | TypeNs::AdtSelfType(adt) => { |
420 | let generics = generics(self.db.upcast(), adt.into()); | 420 | let generics = generics(self.db.upcast(), adt.into()); |
@@ -422,7 +422,7 @@ impl<'a> TyLoweringContext<'a> { | |||
422 | TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db), | 422 | TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db), |
423 | TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders), | 423 | TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders), |
424 | }; | 424 | }; |
425 | self.db.ty(adt.into()).subst(&substs) | 425 | self.db.ty(adt.into()).substitute(&Interner, &substs) |
426 | } | 426 | } |
427 | 427 | ||
428 | TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args), | 428 | TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args), |
@@ -477,13 +477,13 @@ impl<'a> TyLoweringContext<'a> { | |||
477 | ), | 477 | ), |
478 | ); | 478 | ); |
479 | let s = generics.type_params_subst(self.db); | 479 | let s = generics.type_params_subst(self.db); |
480 | t.substitution.clone().subst_bound_vars(&s) | 480 | s.apply(t.substitution.clone(), &Interner) |
481 | } | 481 | } |
482 | TypeParamLoweringMode::Variable => t.substitution.clone(), | 482 | TypeParamLoweringMode::Variable => t.substitution.clone(), |
483 | }; | 483 | }; |
484 | // We need to shift in the bound vars, since | 484 | // We need to shift in the bound vars, since |
485 | // associated_type_shorthand_candidates does not do that | 485 | // associated_type_shorthand_candidates does not do that |
486 | let substs = substs.shift_bound_vars(self.in_binders); | 486 | let substs = substs.shifted_in_from(self.in_binders); |
487 | // FIXME handle type parameters on the segment | 487 | // FIXME handle type parameters on the segment |
488 | return Some( | 488 | return Some( |
489 | TyKind::Alias(AliasTy::Projection(ProjectionTy { | 489 | TyKind::Alias(AliasTy::Projection(ProjectionTy { |
@@ -516,7 +516,7 @@ impl<'a> TyLoweringContext<'a> { | |||
516 | TyDefId::TypeAliasId(it) => Some(it.into()), | 516 | TyDefId::TypeAliasId(it) => Some(it.into()), |
517 | }; | 517 | }; |
518 | let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None); | 518 | let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None); |
519 | self.db.ty(typeable).subst(&substs) | 519 | self.db.ty(typeable).substitute(&Interner, &substs) |
520 | } | 520 | } |
521 | 521 | ||
522 | /// Collect generic arguments from a path into a `Substs`. See also | 522 | /// Collect generic arguments from a path into a `Substs`. See also |
@@ -620,7 +620,7 @@ impl<'a> TyLoweringContext<'a> { | |||
620 | for default_ty in defaults.iter().skip(substs.len()) { | 620 | for default_ty in defaults.iter().skip(substs.len()) { |
621 | // each default can depend on the previous parameters | 621 | // each default can depend on the previous parameters |
622 | let substs_so_far = Substitution::from_iter(&Interner, substs.clone()); | 622 | let substs_so_far = Substitution::from_iter(&Interner, substs.clone()); |
623 | substs.push(default_ty.clone().subst(&substs_so_far)); | 623 | substs.push(default_ty.clone().substitute(&Interner, &substs_so_far)); |
624 | } | 624 | } |
625 | } | 625 | } |
626 | } | 626 | } |
@@ -787,7 +787,7 @@ impl<'a> TyLoweringContext<'a> { | |||
787 | let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { | 787 | let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { |
788 | bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect() | 788 | bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect() |
789 | }); | 789 | }); |
790 | ReturnTypeImplTrait { bounds: Binders::new(1, predicates) } | 790 | ReturnTypeImplTrait { bounds: crate::make_only_type_binders(1, predicates) } |
791 | } | 791 | } |
792 | } | 792 | } |
793 | 793 | ||
@@ -831,17 +831,20 @@ pub fn associated_type_shorthand_candidates<R>( | |||
831 | }; | 831 | }; |
832 | 832 | ||
833 | match res { | 833 | match res { |
834 | // FIXME: how to correctly handle higher-ranked bounds here? | 834 | TypeNs::SelfType(impl_id) => search( |
835 | TypeNs::SelfType(impl_id) => { | 835 | // we're _in_ the impl -- the binders get added back later. Correct, |
836 | search(db.impl_trait(impl_id)?.value.shift_bound_vars_out(DebruijnIndex::ONE)) | 836 | // but it would be nice to make this more explicit |
837 | } | 837 | db.impl_trait(impl_id)?.into_value_and_skipped_binders().0, |
838 | ), | ||
838 | TypeNs::GenericParam(param_id) => { | 839 | TypeNs::GenericParam(param_id) => { |
839 | let predicates = db.generic_predicates_for_param(param_id); | 840 | let predicates = db.generic_predicates_for_param(param_id); |
840 | let res = predicates.iter().find_map(|pred| match &pred.value.value { | 841 | let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() { |
841 | // FIXME: how to correctly handle higher-ranked bounds here? | 842 | // FIXME: how to correctly handle higher-ranked bounds here? |
842 | WhereClause::Implemented(tr) => { | 843 | WhereClause::Implemented(tr) => search( |
843 | search(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE)) | 844 | tr.clone() |
844 | } | 845 | .shifted_out_to(DebruijnIndex::ONE) |
846 | .expect("FIXME unexpected higher-ranked trait bound"), | ||
847 | ), | ||
845 | _ => None, | 848 | _ => None, |
846 | }); | 849 | }); |
847 | if let res @ Some(_) = res { | 850 | if let res @ Some(_) = res { |
@@ -881,7 +884,7 @@ pub(crate) fn field_types_query( | |||
881 | let ctx = | 884 | let ctx = |
882 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 885 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
883 | for (field_id, field_data) in var_data.fields().iter() { | 886 | for (field_id, field_data) in var_data.fields().iter() { |
884 | res.insert(field_id, Binders::new(generics.len(), ctx.lower_ty(&field_data.type_ref))) | 887 | res.insert(field_id, make_binders(&generics, ctx.lower_ty(&field_data.type_ref))) |
885 | } | 888 | } |
886 | Arc::new(res) | 889 | Arc::new(res) |
887 | } | 890 | } |
@@ -915,9 +918,7 @@ pub(crate) fn generic_predicates_for_param_query( | |||
915 | }, | 918 | }, |
916 | WherePredicate::Lifetime { .. } => false, | 919 | WherePredicate::Lifetime { .. } => false, |
917 | }) | 920 | }) |
918 | .flat_map(|pred| { | 921 | .flat_map(|pred| ctx.lower_where_predicate(pred, true).map(|p| make_binders(&generics, p))) |
919 | ctx.lower_where_predicate(pred, true).map(|p| Binders::new(generics.len(), p)) | ||
920 | }) | ||
921 | .collect() | 922 | .collect() |
922 | } | 923 | } |
923 | 924 | ||
@@ -988,9 +989,7 @@ pub(crate) fn generic_predicates_query( | |||
988 | let generics = generics(db.upcast(), def); | 989 | let generics = generics(db.upcast(), def); |
989 | resolver | 990 | resolver |
990 | .where_predicates_in_scope() | 991 | .where_predicates_in_scope() |
991 | .flat_map(|pred| { | 992 | .flat_map(|pred| ctx.lower_where_predicate(pred, false).map(|p| make_binders(&generics, p))) |
992 | ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p)) | ||
993 | }) | ||
994 | .collect() | 993 | .collect() |
995 | } | 994 | } |
996 | 995 | ||
@@ -1012,22 +1011,24 @@ pub(crate) fn generic_defaults_query( | |||
1012 | p.default.as_ref().map_or(TyKind::Error.intern(&Interner), |t| ctx.lower_ty(t)); | 1011 | p.default.as_ref().map_or(TyKind::Error.intern(&Interner), |t| ctx.lower_ty(t)); |
1013 | 1012 | ||
1014 | // Each default can only refer to previous parameters. | 1013 | // Each default can only refer to previous parameters. |
1015 | ty.walk_mut_binders( | 1014 | ty = ty.fold_binders( |
1016 | &mut |ty, binders| match ty.interned_mut() { | 1015 | &mut |ty, binders| match ty.kind(&Interner) { |
1017 | TyKind::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { | 1016 | TyKind::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { |
1018 | if *index >= idx { | 1017 | if *index >= idx { |
1019 | // type variable default referring to parameter coming | 1018 | // type variable default referring to parameter coming |
1020 | // after it. This is forbidden (FIXME: report | 1019 | // after it. This is forbidden (FIXME: report |
1021 | // diagnostic) | 1020 | // diagnostic) |
1022 | *ty = TyKind::Error.intern(&Interner); | 1021 | TyKind::Error.intern(&Interner) |
1022 | } else { | ||
1023 | ty | ||
1023 | } | 1024 | } |
1024 | } | 1025 | } |
1025 | _ => {} | 1026 | _ => ty, |
1026 | }, | 1027 | }, |
1027 | DebruijnIndex::INNERMOST, | 1028 | DebruijnIndex::INNERMOST, |
1028 | ); | 1029 | ); |
1029 | 1030 | ||
1030 | Binders::new(idx, ty) | 1031 | crate::make_only_type_binders(idx, ty) |
1031 | }) | 1032 | }) |
1032 | .collect(); | 1033 | .collect(); |
1033 | 1034 | ||
@@ -1040,14 +1041,13 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { | |||
1040 | let ctx_params = TyLoweringContext::new(db, &resolver) | 1041 | let ctx_params = TyLoweringContext::new(db, &resolver) |
1041 | .with_impl_trait_mode(ImplTraitLoweringMode::Variable) | 1042 | .with_impl_trait_mode(ImplTraitLoweringMode::Variable) |
1042 | .with_type_param_mode(TypeParamLoweringMode::Variable); | 1043 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
1043 | let params = data.params.iter().map(|tr| (&ctx_params).lower_ty(tr)).collect::<Vec<_>>(); | 1044 | let params = data.params.iter().map(|tr| ctx_params.lower_ty(tr)).collect::<Vec<_>>(); |
1044 | let ctx_ret = TyLoweringContext::new(db, &resolver) | 1045 | let ctx_ret = TyLoweringContext::new(db, &resolver) |
1045 | .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) | 1046 | .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) |
1046 | .with_type_param_mode(TypeParamLoweringMode::Variable); | 1047 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
1047 | let ret = (&ctx_ret).lower_ty(&data.ret_type); | 1048 | let ret = ctx_ret.lower_ty(&data.ret_type); |
1048 | let generics = generics(db.upcast(), def.into()); | 1049 | let generics = generics(db.upcast(), def.into()); |
1049 | let num_binders = generics.len(); | 1050 | make_binders(&generics, CallableSig::from_params_and_return(params, ret, data.is_varargs())) |
1050 | Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs())) | ||
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | /// Build the declared type of a function. This should not need to look at the | 1053 | /// Build the declared type of a function. This should not need to look at the |
@@ -1055,8 +1055,8 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { | |||
1055 | fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { | 1055 | fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { |
1056 | let generics = generics(db.upcast(), def.into()); | 1056 | let generics = generics(db.upcast(), def.into()); |
1057 | let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); | 1057 | let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); |
1058 | Binders::new( | 1058 | make_binders( |
1059 | substs.len(&Interner), | 1059 | &generics, |
1060 | TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner), | 1060 | TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner), |
1061 | ) | 1061 | ) |
1062 | } | 1062 | } |
@@ -1069,7 +1069,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> { | |||
1069 | let ctx = | 1069 | let ctx = |
1070 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1070 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1071 | 1071 | ||
1072 | Binders::new(generics.len(), ctx.lower_ty(&data.type_ref)) | 1072 | make_binders(&generics, ctx.lower_ty(&data.type_ref)) |
1073 | } | 1073 | } |
1074 | 1074 | ||
1075 | /// Build the declared type of a static. | 1075 | /// Build the declared type of a static. |
@@ -1078,7 +1078,7 @@ fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> { | |||
1078 | let resolver = def.resolver(db.upcast()); | 1078 | let resolver = def.resolver(db.upcast()); |
1079 | let ctx = TyLoweringContext::new(db, &resolver); | 1079 | let ctx = TyLoweringContext::new(db, &resolver); |
1080 | 1080 | ||
1081 | Binders::new(0, ctx.lower_ty(&data.type_ref)) | 1081 | Binders::empty(&Interner, ctx.lower_ty(&data.type_ref)) |
1082 | } | 1082 | } |
1083 | 1083 | ||
1084 | fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { | 1084 | fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { |
@@ -1088,8 +1088,8 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS | |||
1088 | let ctx = | 1088 | let ctx = |
1089 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1089 | 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<_>>(); | 1090 | let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); |
1091 | let ret = type_for_adt(db, def.into()); | 1091 | 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)) | 1092 | Binders::new(binders, CallableSig::from_params_and_return(params, ret, false)) |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | /// Build the type of a tuple struct constructor. | 1095 | /// Build the type of a tuple struct constructor. |
@@ -1100,8 +1100,8 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T | |||
1100 | } | 1100 | } |
1101 | let generics = generics(db.upcast(), def.into()); | 1101 | let generics = generics(db.upcast(), def.into()); |
1102 | let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); | 1102 | let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); |
1103 | Binders::new( | 1103 | make_binders( |
1104 | substs.len(&Interner), | 1104 | &generics, |
1105 | TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner), | 1105 | TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner), |
1106 | ) | 1106 | ) |
1107 | } | 1107 | } |
@@ -1114,8 +1114,8 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) | |||
1114 | let ctx = | 1114 | let ctx = |
1115 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1115 | 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<_>>(); | 1116 | let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); |
1117 | let ret = type_for_adt(db, def.parent.into()); | 1117 | 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)) | 1118 | Binders::new(binders, CallableSig::from_params_and_return(params, ret, false)) |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | /// Build the type of a tuple enum variant constructor. | 1121 | /// Build the type of a tuple enum variant constructor. |
@@ -1127,17 +1127,17 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) - | |||
1127 | } | 1127 | } |
1128 | let generics = generics(db.upcast(), def.parent.into()); | 1128 | let generics = generics(db.upcast(), def.parent.into()); |
1129 | let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); | 1129 | let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); |
1130 | Binders::new( | 1130 | make_binders( |
1131 | substs.len(&Interner), | 1131 | &generics, |
1132 | TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner), | 1132 | TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner), |
1133 | ) | 1133 | ) |
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { | 1136 | fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { |
1137 | let generics = generics(db.upcast(), adt.into()); | ||
1137 | let b = TyBuilder::adt(db, adt); | 1138 | let b = TyBuilder::adt(db, adt); |
1138 | let num_binders = b.remaining(); | ||
1139 | let ty = b.fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build(); | 1139 | let ty = b.fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build(); |
1140 | Binders::new(num_binders, ty) | 1140 | make_binders(&generics, ty) |
1141 | } | 1141 | } |
1142 | 1142 | ||
1143 | fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { | 1143 | fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { |
@@ -1146,11 +1146,11 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { | |||
1146 | let ctx = | 1146 | let ctx = |
1147 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1147 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1148 | if db.type_alias_data(t).is_extern { | 1148 | if db.type_alias_data(t).is_extern { |
1149 | Binders::new(0, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(&Interner)) | 1149 | Binders::empty(&Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(&Interner)) |
1150 | } else { | 1150 | } else { |
1151 | let type_ref = &db.type_alias_data(t).type_ref; | 1151 | let type_ref = &db.type_alias_data(t).type_ref; |
1152 | let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error)); | 1152 | let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error)); |
1153 | Binders::new(generics.len(), inner) | 1153 | make_binders(&generics, inner) |
1154 | } | 1154 | } |
1155 | } | 1155 | } |
1156 | 1156 | ||
@@ -1209,19 +1209,21 @@ impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for V | |||
1209 | /// namespace. | 1209 | /// namespace. |
1210 | pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> { | 1210 | pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> { |
1211 | match def { | 1211 | match def { |
1212 | TyDefId::BuiltinType(it) => Binders::new(0, TyBuilder::builtin(it)), | 1212 | TyDefId::BuiltinType(it) => Binders::empty(&Interner, TyBuilder::builtin(it)), |
1213 | TyDefId::AdtId(it) => type_for_adt(db, it), | 1213 | TyDefId::AdtId(it) => type_for_adt(db, it), |
1214 | TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), | 1214 | TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), |
1215 | } | 1215 | } |
1216 | } | 1216 | } |
1217 | 1217 | ||
1218 | pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> { | 1218 | pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> { |
1219 | let num_binders = match *def { | 1219 | let generics = match *def { |
1220 | TyDefId::BuiltinType(_) => 0, | 1220 | TyDefId::BuiltinType(_) => { |
1221 | TyDefId::AdtId(it) => generics(db.upcast(), it.into()).len(), | 1221 | return Binders::empty(&Interner, TyKind::Error.intern(&Interner)) |
1222 | TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()).len(), | 1222 | } |
1223 | TyDefId::AdtId(it) => generics(db.upcast(), it.into()), | ||
1224 | TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()), | ||
1223 | }; | 1225 | }; |
1224 | Binders::new(num_binders, TyKind::Error.intern(&Interner)) | 1226 | make_binders(&generics, TyKind::Error.intern(&Interner)) |
1225 | } | 1227 | } |
1226 | 1228 | ||
1227 | pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> { | 1229 | pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> { |
@@ -1241,7 +1243,7 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde | |||
1241 | let generics = generics(db.upcast(), impl_id.into()); | 1243 | let generics = generics(db.upcast(), impl_id.into()); |
1242 | let ctx = | 1244 | let ctx = |
1243 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1245 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1244 | Binders::new(generics.len(), ctx.lower_ty(&impl_data.self_ty)) | 1246 | make_binders(&generics, ctx.lower_ty(&impl_data.self_ty)) |
1245 | } | 1247 | } |
1246 | 1248 | ||
1247 | pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { | 1249 | pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { |
@@ -1259,7 +1261,7 @@ pub(crate) fn impl_self_ty_recover( | |||
1259 | impl_id: &ImplId, | 1261 | impl_id: &ImplId, |
1260 | ) -> Binders<Ty> { | 1262 | ) -> Binders<Ty> { |
1261 | let generics = generics(db.upcast(), (*impl_id).into()); | 1263 | let generics = generics(db.upcast(), (*impl_id).into()); |
1262 | Binders::new(generics.len(), TyKind::Error.intern(&Interner)) | 1264 | make_binders(&generics, TyKind::Error.intern(&Interner)) |
1263 | } | 1265 | } |
1264 | 1266 | ||
1265 | pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { | 1267 | pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { |
@@ -1267,9 +1269,9 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option< | |||
1267 | let resolver = impl_id.resolver(db.upcast()); | 1269 | let resolver = impl_id.resolver(db.upcast()); |
1268 | let ctx = | 1270 | let ctx = |
1269 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1271 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1270 | let self_ty = db.impl_self_ty(impl_id); | 1272 | 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()?; | 1273 | 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))?)) | 1274 | Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?)) |
1273 | } | 1275 | } |
1274 | 1276 | ||
1275 | pub(crate) fn return_type_impl_traits( | 1277 | pub(crate) fn return_type_impl_traits( |
@@ -1284,13 +1286,12 @@ pub(crate) fn return_type_impl_traits( | |||
1284 | .with_type_param_mode(TypeParamLoweringMode::Variable); | 1286 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
1285 | let _ret = (&ctx_ret).lower_ty(&data.ret_type); | 1287 | let _ret = (&ctx_ret).lower_ty(&data.ret_type); |
1286 | let generics = generics(db.upcast(), def.into()); | 1288 | let generics = generics(db.upcast(), def.into()); |
1287 | let num_binders = generics.len(); | ||
1288 | let return_type_impl_traits = | 1289 | let return_type_impl_traits = |
1289 | ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() }; | 1290 | ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() }; |
1290 | if return_type_impl_traits.impl_traits.is_empty() { | 1291 | if return_type_impl_traits.impl_traits.is_empty() { |
1291 | None | 1292 | None |
1292 | } else { | 1293 | } else { |
1293 | Some(Arc::new(Binders::new(num_binders, return_type_impl_traits))) | 1294 | Some(Arc::new(make_binders(&generics, return_type_impl_traits))) |
1294 | } | 1295 | } |
1295 | } | 1296 | } |
1296 | 1297 | ||
@@ -1300,3 +1301,7 @@ pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mut | |||
1300 | hir_def::type_ref::Mutability::Mut => Mutability::Mut, | 1301 | hir_def::type_ref::Mutability::Mut => Mutability::Mut, |
1301 | } | 1302 | } |
1302 | } | 1303 | } |
1304 | |||
1305 | fn make_binders<T>(generics: &Generics, value: T) -> Binders<T> { | ||
1306 | crate::make_only_type_binders(generics.len(), value) | ||
1307 | } | ||
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 6ace970d1..19a1fa793 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 | } |
@@ -712,7 +712,7 @@ pub(crate) fn inherent_impl_substs( | |||
712 | let vars = TyBuilder::subst_for_def(db, impl_id) | 712 | let vars = TyBuilder::subst_for_def(db, impl_id) |
713 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner)) | 713 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner)) |
714 | .build(); | 714 | .build(); |
715 | let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); | 715 | let self_ty_with_vars = db.impl_self_ty(impl_id).substitute(&Interner, &vars); |
716 | let mut kinds = self_ty.binders.interned().to_vec(); | 716 | let mut kinds = self_ty.binders.interned().to_vec(); |
717 | kinds.extend( | 717 | kinds.extend( |
718 | iter::repeat(chalk_ir::WithKind::new( | 718 | iter::repeat(chalk_ir::WithKind::new( |
@@ -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()).substitute(&Interner, &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..dff87ef70 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/traits/chalk.rs | |||
@@ -184,16 +184,21 @@ 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 (datas, binders) = (*datas).as_ref().into_value_and_skipped_binders(); |
188 | let data = &datas.impl_traits[idx as usize]; | ||
188 | let bound = OpaqueTyDatumBound { | 189 | let bound = OpaqueTyDatumBound { |
189 | bounds: make_binders( | 190 | bounds: make_binders( |
190 | data.bounds.value.iter().cloned().map(|b| b.to_chalk(self.db)).collect(), | 191 | data.bounds |
192 | .skip_binders() | ||
193 | .iter() | ||
194 | .cloned() | ||
195 | .map(|b| b.to_chalk(self.db)) | ||
196 | .collect(), | ||
191 | 1, | 197 | 1, |
192 | ), | 198 | ), |
193 | where_clauses: make_binders(vec![], 0), | 199 | where_clauses: make_binders(vec![], 0), |
194 | }; | 200 | }; |
195 | let num_vars = datas.num_binders; | 201 | chalk_ir::Binders::new(binders, bound) |
196 | make_binders(bound, num_vars) | ||
197 | } | 202 | } |
198 | crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => { | 203 | crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => { |
199 | if let Some((future_trait, future_output)) = self | 204 | if let Some((future_trait, future_output)) = self |
@@ -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: chalk_ir::Binders::new(binders, value_bound), |
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: chalk_ir::Binders::new(binders, bound), |
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..c3b148cab 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: chalk_ir::Binders::new(binders, where_clauses), |
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) |
@@ -148,7 +149,7 @@ impl ToChalk for Ty { | |||
148 | .map(|c| from_chalk(db, c.clone())); | 149 | .map(|c| from_chalk(db, c.clone())); |
149 | TyKind::Dyn(crate::DynTy { | 150 | TyKind::Dyn(crate::DynTy { |
150 | bounds: crate::Binders::new( | 151 | bounds: crate::Binders::new( |
151 | 1, | 152 | where_clauses.bounds.binders.clone(), |
152 | crate::QuantifiedWhereClauses::from_iter(&Interner, bounds), | 153 | crate::QuantifiedWhereClauses::from_iter(&Interner, bounds), |
153 | ), | 154 | ), |
154 | }) | 155 | }) |
@@ -486,19 +487,13 @@ 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> { |
489 | chalk_ir::Binders::new( | 490 | let (value, binders) = self.into_value_and_skipped_binders(); |
490 | chalk_ir::VariableKinds::from_iter( | 491 | chalk_ir::Binders::new(binders, value.to_chalk(db)) |
491 | &Interner, | ||
492 | std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)) | ||
493 | .take(self.num_binders), | ||
494 | ), | ||
495 | self.value.to_chalk(db), | ||
496 | ) | ||
497 | } | 492 | } |
498 | 493 | ||
499 | fn from_chalk(db: &dyn HirDatabase, binders: chalk_ir::Binders<T::Chalk>) -> crate::Binders<T> { | 494 | fn from_chalk(db: &dyn HirDatabase, binders: chalk_ir::Binders<T::Chalk>) -> crate::Binders<T> { |
500 | let (v, b) = binders.into_value_and_skipped_binders(); | 495 | let (v, b) = binders.into_value_and_skipped_binders(); |
501 | crate::Binders::new(b.len(&Interner), from_chalk(db, v)) | 496 | crate::Binders::new(b, from_chalk(db, v)) |
502 | } | 497 | } |
503 | } | 498 | } |
504 | 499 | ||
@@ -524,7 +519,7 @@ pub(super) fn convert_where_clauses( | |||
524 | let generic_predicates = db.generic_predicates(def); | 519 | let generic_predicates = db.generic_predicates(def); |
525 | let mut result = Vec::with_capacity(generic_predicates.len()); | 520 | let mut result = Vec::with_capacity(generic_predicates.len()); |
526 | for pred in generic_predicates.iter() { | 521 | for pred in generic_predicates.iter() { |
527 | result.push(pred.clone().subst(substs).to_chalk(db)); | 522 | result.push(pred.clone().substitute(&Interner, substs).to_chalk(db)); |
528 | } | 523 | } |
529 | result | 524 | result |
530 | } | 525 | } |
@@ -536,8 +531,9 @@ pub(super) fn generic_predicate_to_inline_bound( | |||
536 | ) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> { | 531 | ) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> { |
537 | // An InlineBound is like a GenericPredicate, except the self type is left out. | 532 | // 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. | 533 | // 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); | 534 | let self_ty_shifted_in = self_ty.clone().shifted_in_from(DebruijnIndex::ONE); |
540 | match &pred.value { | 535 | let (pred, binders) = pred.as_ref().into_value_and_skipped_binders(); |
536 | match pred { | ||
541 | WhereClause::Implemented(trait_ref) => { | 537 | WhereClause::Implemented(trait_ref) => { |
542 | if trait_ref.self_type_parameter(&Interner) != &self_ty_shifted_in { | 538 | if trait_ref.self_type_parameter(&Interner) != &self_ty_shifted_in { |
543 | // we can only convert predicates back to type bounds if they | 539 | // we can only convert predicates back to type bounds if they |
@@ -549,7 +545,7 @@ pub(super) fn generic_predicate_to_inline_bound( | |||
549 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) | 545 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) |
550 | .collect(); | 546 | .collect(); |
551 | let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; | 547 | 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)) | 548 | Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound))) |
553 | } | 549 | } |
554 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { | 550 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { |
555 | if projection_ty.self_type_parameter(&Interner) != &self_ty_shifted_in { | 551 | if projection_ty.self_type_parameter(&Interner) != &self_ty_shifted_in { |
@@ -566,7 +562,10 @@ pub(super) fn generic_predicate_to_inline_bound( | |||
566 | associated_ty_id: projection_ty.associated_ty_id, | 562 | associated_ty_id: projection_ty.associated_ty_id, |
567 | parameters: Vec::new(), // FIXME we don't support generic associated types yet | 563 | parameters: Vec::new(), // FIXME we don't support generic associated types yet |
568 | }; | 564 | }; |
569 | Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), pred.num_binders)) | 565 | Some(chalk_ir::Binders::new( |
566 | binders, | ||
567 | rust_ir::InlineBound::AliasEqBound(alias_eq_bound), | ||
568 | )) | ||
570 | } | 569 | } |
571 | _ => None, | 570 | _ => None, |
572 | } | 571 | } |
diff --git a/crates/hir_ty/src/types.rs b/crates/hir_ty/src/types.rs index bac086318..46c705a76 100644 --- a/crates/hir_ty/src/types.rs +++ b/crates/hir_ty/src/types.rs | |||
@@ -12,7 +12,7 @@ use smallvec::SmallVec; | |||
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId, | 14 | AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId, |
15 | InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, | 15 | InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, TypeWalk, VariableKinds, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 18 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
@@ -286,7 +286,11 @@ impl Substitution { | |||
286 | Substitution(elements.into_iter().casted(interner).collect()) | 286 | Substitution(elements.into_iter().casted(interner).collect()) |
287 | } | 287 | } |
288 | 288 | ||
289 | // We can hopefully add this to Chalk | 289 | pub fn apply<T: TypeWalk>(&self, value: T, _interner: &Interner) -> T { |
290 | value.subst_bound_vars(self) | ||
291 | } | ||
292 | |||
293 | // Temporary helper functions, to be removed | ||
290 | pub fn intern(interned: SmallVec<[GenericArg; 2]>) -> Substitution { | 294 | pub fn intern(interned: SmallVec<[GenericArg; 2]>) -> Substitution { |
291 | Substitution(interned) | 295 | Substitution(interned) |
292 | } | 296 | } |
@@ -296,10 +300,65 @@ impl Substitution { | |||
296 | } | 300 | } |
297 | } | 301 | } |
298 | 302 | ||
299 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 303 | #[derive(Clone, PartialEq, Eq, Hash)] |
300 | pub struct Binders<T> { | 304 | pub struct Binders<T> { |
301 | pub num_binders: usize, | 305 | /// The binders that quantify over the value. |
302 | pub value: T, | 306 | pub binders: VariableKinds, |
307 | value: T, | ||
308 | } | ||
309 | |||
310 | impl<T> Binders<T> { | ||
311 | pub fn new(binders: VariableKinds, value: T) -> Self { | ||
312 | Self { binders, value } | ||
313 | } | ||
314 | |||
315 | pub fn empty(_interner: &Interner, value: T) -> Self { | ||
316 | crate::make_only_type_binders(0, value) | ||
317 | } | ||
318 | |||
319 | pub fn as_ref(&self) -> Binders<&T> { | ||
320 | Binders { binders: self.binders.clone(), value: &self.value } | ||
321 | } | ||
322 | |||
323 | pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> { | ||
324 | Binders { binders: self.binders, value: f(self.value) } | ||
325 | } | ||
326 | |||
327 | pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { | ||
328 | Some(Binders { binders: self.binders, value: f(self.value)? }) | ||
329 | } | ||
330 | |||
331 | pub fn skip_binders(&self) -> &T { | ||
332 | &self.value | ||
333 | } | ||
334 | |||
335 | pub fn into_value_and_skipped_binders(self) -> (T, VariableKinds) { | ||
336 | (self.value, self.binders) | ||
337 | } | ||
338 | |||
339 | /// Returns the number of binders. | ||
340 | pub fn len(&self, interner: &Interner) -> usize { | ||
341 | self.binders.len(interner) | ||
342 | } | ||
343 | |||
344 | // Temporary helper function, to be removed | ||
345 | pub fn skip_binders_mut(&mut self) -> &mut T { | ||
346 | &mut self.value | ||
347 | } | ||
348 | } | ||
349 | |||
350 | impl<T: Clone> Binders<&T> { | ||
351 | pub fn cloned(&self) -> Binders<T> { | ||
352 | Binders::new(self.binders.clone(), self.value.clone()) | ||
353 | } | ||
354 | } | ||
355 | |||
356 | impl<T: std::fmt::Debug> std::fmt::Debug for Binders<T> { | ||
357 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { | ||
358 | let Binders { ref binders, ref value } = *self; | ||
359 | write!(fmt, "for{:?} ", binders.inner_debug(&Interner))?; | ||
360 | std::fmt::Debug::fmt(value, fmt) | ||
361 | } | ||
303 | } | 362 | } |
304 | 363 | ||
305 | /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. | 364 | /// 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/utils.rs b/crates/hir_ty/src/utils.rs index df0ea4368..d11708299 100644 --- a/crates/hir_ty/src/utils.rs +++ b/crates/hir_ty/src/utils.rs | |||
@@ -66,13 +66,15 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr | |||
66 | .filter_map(|pred| { | 66 | .filter_map(|pred| { |
67 | pred.as_ref().filter_map(|pred| match pred.skip_binders() { | 67 | pred.as_ref().filter_map(|pred| match pred.skip_binders() { |
68 | // FIXME: how to correctly handle higher-ranked bounds here? | 68 | // FIXME: how to correctly handle higher-ranked bounds here? |
69 | WhereClause::Implemented(tr) => { | 69 | WhereClause::Implemented(tr) => Some( |
70 | Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE)) | 70 | tr.clone() |
71 | } | 71 | .shifted_out_to(DebruijnIndex::ONE) |
72 | .expect("FIXME unexpected higher-ranked trait bound"), | ||
73 | ), | ||
72 | _ => None, | 74 | _ => None, |
73 | }) | 75 | }) |
74 | }) | 76 | }) |
75 | .map(|pred| pred.subst(&trait_ref.substitution)) | 77 | .map(|pred| pred.substitute(&Interner, &trait_ref.substitution)) |
76 | .collect() | 78 | .collect() |
77 | } | 79 | } |
78 | 80 | ||
@@ -103,6 +105,8 @@ pub(super) fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<Tra | |||
103 | /// we have `Self: Trait<u32, i32>` and `Trait<T, U>: OtherTrait<U>` we'll get | 105 | /// we have `Self: Trait<u32, i32>` and `Trait<T, U>: OtherTrait<U>` we'll get |
104 | /// `Self: OtherTrait<i32>`. | 106 | /// `Self: OtherTrait<i32>`. |
105 | pub(super) fn all_super_trait_refs(db: &dyn HirDatabase, trait_ref: TraitRef) -> Vec<TraitRef> { | 107 | pub(super) fn all_super_trait_refs(db: &dyn HirDatabase, trait_ref: TraitRef) -> Vec<TraitRef> { |
108 | // FIXME: replace by Chalk's `super_traits`, maybe make this a query | ||
109 | |||
106 | // we need to take care a bit here to avoid infinite loops in case of cycles | 110 | // we need to take care a bit here to avoid infinite loops in case of cycles |
107 | // (i.e. if we have `trait A: B; trait B: A;`) | 111 | // (i.e. if we have `trait A: B; trait B: A;`) |
108 | let mut result = vec![trait_ref]; | 112 | let mut result = vec![trait_ref]; |
diff --git a/crates/hir_ty/src/walk.rs b/crates/hir_ty/src/walk.rs index 5dfd59746..b85e6ab4d 100644 --- a/crates/hir_ty/src/walk.rs +++ b/crates/hir_ty/src/walk.rs | |||
@@ -82,7 +82,7 @@ pub trait TypeWalk { | |||
82 | *ty = substs.interned()[bound.index] | 82 | *ty = substs.interned()[bound.index] |
83 | .assert_ty_ref(&Interner) | 83 | .assert_ty_ref(&Interner) |
84 | .clone() | 84 | .clone() |
85 | .shift_bound_vars(binders); | 85 | .shifted_in_from(binders); |
86 | } | 86 | } |
87 | } | 87 | } |
88 | }, | 88 | }, |
@@ -92,7 +92,7 @@ pub trait TypeWalk { | |||
92 | } | 92 | } |
93 | 93 | ||
94 | /// Shifts up debruijn indices of `TyKind::Bound` vars by `n`. | 94 | /// Shifts up debruijn indices of `TyKind::Bound` vars by `n`. |
95 | fn shift_bound_vars(self, n: DebruijnIndex) -> Self | 95 | fn shifted_in_from(self, n: DebruijnIndex) -> Self |
96 | where | 96 | where |
97 | Self: Sized, | 97 | Self: Sized, |
98 | { | 98 | { |
@@ -108,20 +108,22 @@ pub trait TypeWalk { | |||
108 | } | 108 | } |
109 | 109 | ||
110 | /// Shifts debruijn indices of `TyKind::Bound` vars out (down) by `n`. | 110 | /// Shifts debruijn indices of `TyKind::Bound` vars out (down) by `n`. |
111 | fn shift_bound_vars_out(self, n: DebruijnIndex) -> Self | 111 | fn shifted_out_to(self, n: DebruijnIndex) -> Option<Self> |
112 | where | 112 | where |
113 | Self: Sized + std::fmt::Debug, | 113 | Self: Sized + std::fmt::Debug, |
114 | { | 114 | { |
115 | self.fold_binders( | 115 | Some(self.fold_binders( |
116 | &mut |ty, binders| match ty.kind(&Interner) { | 116 | &mut |ty, binders| { |
117 | TyKind::BoundVar(bound) if bound.debruijn >= binders => { | 117 | match ty.kind(&Interner) { |
118 | TyKind::BoundVar(bound.shifted_out_to(n).unwrap_or(bound.clone())) | 118 | TyKind::BoundVar(bound) if bound.debruijn >= binders => { |
119 | .intern(&Interner) | 119 | TyKind::BoundVar(bound.shifted_out_to(n).unwrap_or(bound.clone())) |
120 | .intern(&Interner) | ||
121 | } | ||
122 | _ => ty, | ||
120 | } | 123 | } |
121 | _ => ty, | ||
122 | }, | 124 | }, |
123 | DebruijnIndex::INNERMOST, | 125 | DebruijnIndex::INNERMOST, |
124 | ) | 126 | )) |
125 | } | 127 | } |
126 | } | 128 | } |
127 | 129 | ||
@@ -139,7 +141,7 @@ impl TypeWalk for Ty { | |||
139 | } | 141 | } |
140 | } | 142 | } |
141 | TyKind::Dyn(dyn_ty) => { | 143 | TyKind::Dyn(dyn_ty) => { |
142 | for p in dyn_ty.bounds.value.interned().iter() { | 144 | for p in dyn_ty.bounds.skip_binders().interned().iter() { |
143 | p.walk(f); | 145 | p.walk(f); |
144 | } | 146 | } |
145 | } | 147 | } |
@@ -167,7 +169,7 @@ impl TypeWalk for Ty { | |||
167 | p_ty.substitution.walk_mut_binders(f, binders); | 169 | p_ty.substitution.walk_mut_binders(f, binders); |
168 | } | 170 | } |
169 | TyKind::Dyn(dyn_ty) => { | 171 | TyKind::Dyn(dyn_ty) => { |
170 | for p in make_mut_slice(dyn_ty.bounds.value.interned_mut()) { | 172 | for p in make_mut_slice(dyn_ty.bounds.skip_binders_mut().interned_mut()) { |
171 | p.walk_mut_binders(f, binders.shifted_in()); | 173 | p.walk_mut_binders(f, binders.shifted_in()); |
172 | } | 174 | } |
173 | } | 175 | } |
@@ -294,7 +296,7 @@ impl TypeWalk for Substitution { | |||
294 | 296 | ||
295 | impl<T: TypeWalk> TypeWalk for Binders<T> { | 297 | impl<T: TypeWalk> TypeWalk for Binders<T> { |
296 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 298 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
297 | self.value.walk(f); | 299 | self.skip_binders().walk(f); |
298 | } | 300 | } |
299 | 301 | ||
300 | fn walk_mut_binders( | 302 | fn walk_mut_binders( |
@@ -302,7 +304,7 @@ impl<T: TypeWalk> TypeWalk for Binders<T> { | |||
302 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | 304 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), |
303 | binders: DebruijnIndex, | 305 | binders: DebruijnIndex, |
304 | ) { | 306 | ) { |
305 | self.value.walk_mut_binders(f, binders.shifted_in()) | 307 | self.skip_binders_mut().walk_mut_binders(f, binders.shifted_in()) |
306 | } | 308 | } |
307 | } | 309 | } |
308 | 310 | ||