aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-03-18 20:53:19 +0000
committerFlorian Diebold <[email protected]>2021-03-18 20:53:19 +0000
commit7a7e47eab7323a8e122d9994b2936e50e42a1af2 (patch)
treea2ad2b6faf8c708fc593546df64d489c117b61f2
parentb70bea0d7994cbe7b1e01e6b2e0f4ab3ac2c6fd5 (diff)
Chalkify TraitRef
-rw-r--r--crates/hir/src/lib.rs10
-rw-r--r--crates/hir_ty/src/autoderef.rs5
-rw-r--r--crates/hir_ty/src/display.rs14
-rw-r--r--crates/hir_ty/src/infer.rs5
-rw-r--r--crates/hir_ty/src/infer/coerce.rs6
-rw-r--r--crates/hir_ty/src/infer/expr.rs13
-rw-r--r--crates/hir_ty/src/infer/path.rs12
-rw-r--r--crates/hir_ty/src/infer/unify.rs4
-rw-r--r--crates/hir_ty/src/lib.rs39
-rw-r--r--crates/hir_ty/src/lower.rs22
-rw-r--r--crates/hir_ty/src/method_resolution.rs5
-rw-r--r--crates/hir_ty/src/traits.rs2
-rw-r--r--crates/hir_ty/src/traits/chalk.rs10
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs15
-rw-r--r--crates/hir_ty/src/utils.rs10
15 files changed, 99 insertions, 73 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 95cfde61c..67ec8e82a 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1462,7 +1462,7 @@ impl TypeParam {
1462 .into_iter() 1462 .into_iter()
1463 .filter_map(|pred| match &pred.value { 1463 .filter_map(|pred| match &pred.value {
1464 hir_ty::GenericPredicate::Implemented(trait_ref) => { 1464 hir_ty::GenericPredicate::Implemented(trait_ref) => {
1465 Some(Trait::from(trait_ref.trait_)) 1465 Some(Trait::from(trait_ref.hir_trait_id()))
1466 } 1466 }
1467 _ => None, 1467 _ => None,
1468 }) 1468 })
@@ -1757,8 +1757,8 @@ impl Type {
1757 1757
1758 pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { 1758 pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool {
1759 let trait_ref = hir_ty::TraitRef { 1759 let trait_ref = hir_ty::TraitRef {
1760 trait_: trait_.id, 1760 trait_id: hir_ty::to_chalk_trait_id(trait_.id),
1761 substs: Substitution::build_for_def(db, trait_.id) 1761 substitution: Substitution::build_for_def(db, trait_.id)
1762 .push(self.ty.value.clone()) 1762 .push(self.ty.value.clone())
1763 .fill(args.iter().map(|t| t.ty.value.clone())) 1763 .fill(args.iter().map(|t| t.ty.value.clone()))
1764 .build(), 1764 .build(),
@@ -2023,7 +2023,7 @@ impl Type {
2023 it.into_iter() 2023 it.into_iter()
2024 .filter_map(|pred| match pred { 2024 .filter_map(|pred| match pred {
2025 hir_ty::GenericPredicate::Implemented(trait_ref) => { 2025 hir_ty::GenericPredicate::Implemented(trait_ref) => {
2026 Some(Trait::from(trait_ref.trait_)) 2026 Some(Trait::from(trait_ref.hir_trait_id()))
2027 } 2027 }
2028 _ => None, 2028 _ => None,
2029 }) 2029 })
@@ -2067,7 +2067,7 @@ impl Type {
2067 match pred { 2067 match pred {
2068 GenericPredicate::Implemented(trait_ref) => { 2068 GenericPredicate::Implemented(trait_ref) => {
2069 cb(type_.clone()); 2069 cb(type_.clone());
2070 walk_substs(db, type_, &trait_ref.substs, cb); 2070 walk_substs(db, type_, &trait_ref.substitution, cb);
2071 } 2071 }
2072 _ => (), 2072 _ => (),
2073 } 2073 }
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index bd2ff5d38..ad4e6f23b 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -12,7 +12,7 @@ use log::{info, warn};
12 12
13use crate::{ 13use crate::{
14 db::HirDatabase, 14 db::HirDatabase,
15 to_assoc_type_id, 15 to_assoc_type_id, to_chalk_trait_id,
16 traits::{InEnvironment, Solution}, 16 traits::{InEnvironment, Solution},
17 utils::generics, 17 utils::generics,
18 BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substitution, TraitRef, Ty, TyKind, 18 BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substitution, TraitRef, Ty, TyKind,
@@ -68,7 +68,8 @@ fn deref_by_trait(
68 Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build(); 68 Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build();
69 69
70 // Check that the type implements Deref at all 70 // Check that the type implements Deref at all
71 let trait_ref = TraitRef { trait_: deref_trait, substs: parameters.clone() }; 71 let trait_ref =
72 TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() };
72 let implements_goal = Canonical { 73 let implements_goal = Canonical {
73 kinds: ty.value.kinds.clone(), 74 kinds: ty.value.kinds.clone(),
74 value: InEnvironment { 75 value: InEnvironment {
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 7ce0f864c..c6b4f37e5 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -344,7 +344,7 @@ impl HirDisplay for Ty {
344 }; 344 };
345 345
346 if let [GenericPredicate::Implemented(trait_ref), _] = predicates.as_ref() { 346 if let [GenericPredicate::Implemented(trait_ref), _] = predicates.as_ref() {
347 let trait_ = trait_ref.trait_; 347 let trait_ = trait_ref.hir_trait_id();
348 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) { 348 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) {
349 return write!(f, "{}", ty_display); 349 return write!(f, "{}", ty_display);
350 } 350 }
@@ -670,7 +670,7 @@ fn write_bounds_like_dyn_trait(
670 for p in predicates.iter() { 670 for p in predicates.iter() {
671 match p { 671 match p {
672 GenericPredicate::Implemented(trait_ref) => { 672 GenericPredicate::Implemented(trait_ref) => {
673 let trait_ = trait_ref.trait_; 673 let trait_ = trait_ref.hir_trait_id();
674 if !is_fn_trait { 674 if !is_fn_trait {
675 is_fn_trait = fn_traits(f.db.upcast(), trait_).any(|it| it == trait_); 675 is_fn_trait = fn_traits(f.db.upcast(), trait_).any(|it| it == trait_);
676 } 676 }
@@ -685,7 +685,7 @@ fn write_bounds_like_dyn_trait(
685 // existential) here, which is the only thing that's 685 // existential) here, which is the only thing that's
686 // possible in actual Rust, and hence don't print it 686 // possible in actual Rust, and hence don't print it
687 write!(f, "{}", f.db.trait_data(trait_).name)?; 687 write!(f, "{}", f.db.trait_data(trait_).name)?;
688 if let [_, params @ ..] = &*trait_ref.substs.0 { 688 if let [_, params @ ..] = &*trait_ref.substitution.0 {
689 if is_fn_trait { 689 if is_fn_trait {
690 if let Some(args) = params.first().and_then(|it| it.as_tuple()) { 690 if let Some(args) = params.first().and_then(|it| it.as_tuple()) {
691 write!(f, "(")?; 691 write!(f, "(")?;
@@ -745,16 +745,16 @@ impl TraitRef {
745 return write!(f, "{}", TYPE_HINT_TRUNCATION); 745 return write!(f, "{}", TYPE_HINT_TRUNCATION);
746 } 746 }
747 747
748 self.substs[0].hir_fmt(f)?; 748 self.substitution[0].hir_fmt(f)?;
749 if use_as { 749 if use_as {
750 write!(f, " as ")?; 750 write!(f, " as ")?;
751 } else { 751 } else {
752 write!(f, ": ")?; 752 write!(f, ": ")?;
753 } 753 }
754 write!(f, "{}", f.db.trait_data(self.trait_).name)?; 754 write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?;
755 if self.substs.len() > 1 { 755 if self.substitution.len() > 1 {
756 write!(f, "<")?; 756 write!(f, "<")?;
757 f.write_joined(&self.substs[1..], ", ")?; 757 f.write_joined(&self.substitution[1..], ", ")?;
758 write!(f, ">")?; 758 write!(f, ">")?;
759 } 759 }
760 Ok(()) 760 Ok(())
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 2610c9279..b6ae4fc65 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -42,7 +42,7 @@ use super::{
42}; 42};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
45 to_assoc_type_id, AliasTy, Interner, TyKind, 45 to_assoc_type_id, to_chalk_trait_id, AliasTy, Interner, TyKind,
46}; 46};
47 47
48pub(crate) use unify::unify; 48pub(crate) use unify::unify;
@@ -394,7 +394,8 @@ impl<'a> InferenceContext<'a> {
394 .push(inner_ty) 394 .push(inner_ty)
395 .fill(params.iter().cloned()) 395 .fill(params.iter().cloned())
396 .build(); 396 .build();
397 let trait_ref = TraitRef { trait_, substs: substs.clone() }; 397 let trait_ref =
398 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() };
398 let projection = ProjectionPredicate { 399 let projection = ProjectionPredicate {
399 ty: ty.clone(), 400 ty: ty.clone(),
400 projection_ty: ProjectionTy { 401 projection_ty: ProjectionTy {
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index b1f98c507..b86474ed4 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -8,7 +8,8 @@ use chalk_ir::{Mutability, TyVariableKind};
8use hir_def::lang_item::LangItemTarget; 8use hir_def::lang_item::LangItemTarget;
9 9
10use crate::{ 10use crate::{
11 autoderef, traits::Solution, Interner, Obligation, Substitution, TraitRef, Ty, TyKind, 11 autoderef, to_chalk_trait_id, traits::Solution, Interner, Obligation, Substitution, TraitRef,
12 Ty, TyKind,
12}; 13};
13 14
14use super::{InEnvironment, InferenceContext}; 15use super::{InEnvironment, InferenceContext};
@@ -140,7 +141,8 @@ impl<'a> InferenceContext<'a> {
140 .push(from_ty.clone()) 141 .push(from_ty.clone())
141 .push(to_ty.clone()) 142 .push(to_ty.clone())
142 .build(); 143 .build();
143 let trait_ref = TraitRef { trait_: coerce_unsized_trait, substs }; 144 let trait_ref =
145 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs };
144 let goal = InEnvironment::new(self.trait_env.clone(), Obligation::Trait(trait_ref)); 146 let goal = InEnvironment::new(self.trait_env.clone(), Obligation::Trait(trait_ref));
145 147
146 let canonicalizer = self.canonicalizer(); 148 let canonicalizer = self.canonicalizer();
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 0be8c5a90..93548b6c0 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -18,7 +18,7 @@ use crate::{
18 lower::lower_to_chalk_mutability, 18 lower::lower_to_chalk_mutability,
19 method_resolution, op, 19 method_resolution, op,
20 primitive::{self, UintTy}, 20 primitive::{self, UintTy},
21 to_assoc_type_id, 21 to_assoc_type_id, to_chalk_trait_id,
22 traits::{chalk::from_chalk, FnTrait, InEnvironment}, 22 traits::{chalk::from_chalk, FnTrait, InEnvironment},
23 utils::{generics, variant_data, Generics}, 23 utils::{generics, variant_data, Generics},
24 AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar, 24 AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar,
@@ -90,8 +90,10 @@ impl<'a> InferenceContext<'a> {
90 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 90 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 91
92 let trait_env = Arc::clone(&self.trait_env); 92 let trait_env = Arc::clone(&self.trait_env);
93 let implements_fn_trait = 93 let implements_fn_trait = Obligation::Trait(TraitRef {
94 Obligation::Trait(TraitRef { trait_: fn_once_trait, substs: substs.clone() }); 94 trait_id: to_chalk_trait_id(fn_once_trait),
95 substitution: substs.clone(),
96 });
95 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment { 97 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
96 value: implements_fn_trait.clone(), 98 value: implements_fn_trait.clone(),
97 environment: trait_env, 99 environment: trait_env,
@@ -948,7 +950,10 @@ impl<'a> InferenceContext<'a> {
948 // construct a TraitDef 950 // construct a TraitDef
949 let substs = 951 let substs =
950 parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); 952 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
951 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); 953 self.obligations.push(Obligation::Trait(TraitRef {
954 trait_id: to_chalk_trait_id(trait_),
955 substitution: substs,
956 }));
952 } 957 }
953 } 958 }
954 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} 959 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index ea01d6238..e15135fc1 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -9,7 +9,9 @@ use hir_def::{
9}; 9};
10use hir_expand::name::Name; 10use hir_expand::name::Name;
11 11
12use crate::{method_resolution, Interner, Substitution, Ty, TyKind, ValueTyDefId}; 12use crate::{
13 method_resolution, to_chalk_trait_id, Interner, Substitution, Ty, TyKind, ValueTyDefId,
14};
13 15
14use super::{ExprOrPatId, InferenceContext, TraitRef}; 16use super::{ExprOrPatId, InferenceContext, TraitRef};
15 17
@@ -165,7 +167,7 @@ impl<'a> InferenceContext<'a> {
165 segment: PathSegment<'_>, 167 segment: PathSegment<'_>,
166 id: ExprOrPatId, 168 id: ExprOrPatId,
167 ) -> Option<(ValueNs, Option<Substitution>)> { 169 ) -> Option<(ValueNs, Option<Substitution>)> {
168 let trait_ = trait_ref.trait_; 170 let trait_ = trait_ref.hir_trait_id();
169 let item = 171 let item =
170 self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id)).find_map(|item| { 172 self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id)).find_map(|item| {
171 match item { 173 match item {
@@ -200,7 +202,7 @@ impl<'a> InferenceContext<'a> {
200 }; 202 };
201 203
202 self.write_assoc_resolution(id, item); 204 self.write_assoc_resolution(id, item);
203 Some((def, Some(trait_ref.substs))) 205 Some((def, Some(trait_ref.substitution)))
204 } 206 }
205 207
206 fn resolve_ty_assoc_item( 208 fn resolve_ty_assoc_item(
@@ -255,8 +257,8 @@ impl<'a> InferenceContext<'a> {
255 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 257 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
256 .build(); 258 .build();
257 self.obligations.push(super::Obligation::Trait(TraitRef { 259 self.obligations.push(super::Obligation::Trait(TraitRef {
258 trait_, 260 trait_id: to_chalk_trait_id(trait_),
259 substs: trait_substs.clone(), 261 substitution: trait_substs.clone(),
260 })); 262 }));
261 Some(trait_substs) 263 Some(trait_substs)
262 } 264 }
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index b2d4f67b3..f5ea09698 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -390,9 +390,9 @@ impl InferenceTable {
390 ) -> bool { 390 ) -> bool {
391 match (pred1, pred2) { 391 match (pred1, pred2) {
392 (GenericPredicate::Implemented(tr1), GenericPredicate::Implemented(tr2)) 392 (GenericPredicate::Implemented(tr1), GenericPredicate::Implemented(tr2))
393 if tr1.trait_ == tr2.trait_ => 393 if tr1.trait_id == tr2.trait_id =>
394 { 394 {
395 self.unify_substs(&tr1.substs, &tr2.substs, depth + 1) 395 self.unify_substs(&tr1.substitution, &tr2.substitution, depth + 1)
396 } 396 }
397 (GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2)) 397 (GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2))
398 if proj1.projection_ty.associated_ty_id == proj2.projection_ty.associated_ty_id => 398 if proj1.projection_ty.associated_ty_id == proj2.projection_ty.associated_ty_id =>
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 52b498ff7..3859dbfa1 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -58,6 +58,8 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>;
58pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 58pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
59pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; 59pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
60 60
61pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
62
61#[derive(Clone, PartialEq, Eq, Debug, Hash)] 63#[derive(Clone, PartialEq, Eq, Debug, Hash)]
62pub enum Lifetime { 64pub enum Lifetime {
63 Parameter(LifetimeParamId), 65 Parameter(LifetimeParamId),
@@ -81,7 +83,10 @@ pub struct ProjectionTy {
81 83
82impl ProjectionTy { 84impl ProjectionTy {
83 pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef { 85 pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
84 TraitRef { trait_: self.trait_(db), substs: self.substitution.clone() } 86 TraitRef {
87 trait_id: to_chalk_trait_id(self.trait_(db)),
88 substitution: self.substitution.clone(),
89 }
85 } 90 }
86 91
87 fn trait_(&self, db: &dyn HirDatabase) -> TraitId { 92 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
@@ -493,23 +498,25 @@ impl<T: TypeWalk> TypeWalk for Binders<T> {
493} 498}
494 499
495/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. 500/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
496/// Name to be bikeshedded: TraitBound? TraitImplements?
497#[derive(Clone, PartialEq, Eq, Debug, Hash)] 501#[derive(Clone, PartialEq, Eq, Debug, Hash)]
498pub struct TraitRef { 502pub struct TraitRef {
499 /// FIXME name? 503 pub trait_id: ChalkTraitId,
500 pub trait_: TraitId, 504 pub substitution: Substitution,
501 pub substs: Substitution,
502} 505}
503 506
504impl TraitRef { 507impl TraitRef {
505 pub fn self_ty(&self) -> &Ty { 508 pub fn self_type_parameter(&self) -> &Ty {
506 &self.substs[0] 509 &self.substitution[0]
510 }
511
512 pub fn hir_trait_id(&self) -> TraitId {
513 from_chalk_trait_id(self.trait_id)
507 } 514 }
508} 515}
509 516
510impl TypeWalk for TraitRef { 517impl TypeWalk for TraitRef {
511 fn walk(&self, f: &mut impl FnMut(&Ty)) { 518 fn walk(&self, f: &mut impl FnMut(&Ty)) {
512 self.substs.walk(f); 519 self.substitution.walk(f);
513 } 520 }
514 521
515 fn walk_mut_binders( 522 fn walk_mut_binders(
@@ -517,7 +524,7 @@ impl TypeWalk for TraitRef {
517 f: &mut impl FnMut(&mut Ty, DebruijnIndex), 524 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
518 binders: DebruijnIndex, 525 binders: DebruijnIndex,
519 ) { 526 ) {
520 self.substs.walk_mut_binders(f, binders); 527 self.substitution.walk_mut_binders(f, binders);
521 } 528 }
522} 529}
523 530
@@ -784,7 +791,7 @@ impl Ty {
784 791
785 /// If this is a `dyn Trait`, returns that trait. 792 /// If this is a `dyn Trait`, returns that trait.
786 pub fn dyn_trait(&self) -> Option<TraitId> { 793 pub fn dyn_trait(&self) -> Option<TraitId> {
787 self.dyn_trait_ref().map(|it| it.trait_) 794 self.dyn_trait_ref().map(|it| it.trait_id).map(from_chalk_trait_id)
788 } 795 }
789 796
790 fn builtin_deref(&self) -> Option<Ty> { 797 fn builtin_deref(&self) -> Option<Ty> {
@@ -868,8 +875,8 @@ impl Ty {
868 // Parameters will be walked outside, and projection predicate is not used. 875 // Parameters will be walked outside, and projection predicate is not used.
869 // So just provide the Future trait. 876 // So just provide the Future trait.
870 let impl_bound = GenericPredicate::Implemented(TraitRef { 877 let impl_bound = GenericPredicate::Implemented(TraitRef {
871 trait_: future_trait, 878 trait_id: to_chalk_trait_id(future_trait),
872 substs: Substitution::empty(), 879 substitution: Substitution::empty(),
873 }); 880 });
874 Some(vec![impl_bound]) 881 Some(vec![impl_bound])
875 } else { 882 } else {
@@ -1158,3 +1165,11 @@ pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderI
1158 idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), 1165 idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(),
1159 } 1166 }
1160} 1167}
1168
1169pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId {
1170 chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id))
1171}
1172
1173pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId {
1174 salsa::InternKey::from_intern_id(id.0)
1175}
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 462882b2b..5d950a017 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -27,7 +27,7 @@ use stdx::impl_from;
27 27
28use crate::{ 28use crate::{
29 db::HirDatabase, 29 db::HirDatabase,
30 to_assoc_type_id, to_placeholder_idx, 30 to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
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,
@@ -360,7 +360,7 @@ impl<'a> TyLoweringContext<'a> {
360 // FIXME handle type parameters on the segment 360 // FIXME handle type parameters on the segment
361 TyKind::Alias(AliasTy::Projection(ProjectionTy { 361 TyKind::Alias(AliasTy::Projection(ProjectionTy {
362 associated_ty_id: to_assoc_type_id(associated_ty), 362 associated_ty_id: to_assoc_type_id(associated_ty),
363 substitution: super_trait_ref.substs, 363 substitution: super_trait_ref.substitution,
364 })) 364 }))
365 .intern(&Interner) 365 .intern(&Interner)
366 } 366 }
@@ -470,9 +470,9 @@ impl<'a> TyLoweringContext<'a> {
470 "there should be generics if there's a generic param", 470 "there should be generics if there's a generic param",
471 ), 471 ),
472 ); 472 );
473 t.substs.clone().subst_bound_vars(&s) 473 t.substitution.clone().subst_bound_vars(&s)
474 } 474 }
475 TypeParamLoweringMode::Variable => t.substs.clone(), 475 TypeParamLoweringMode::Variable => t.substitution.clone(),
476 }; 476 };
477 // We need to shift in the bound vars, since 477 // We need to shift in the bound vars, since
478 // associated_type_shorthand_candidates does not do that 478 // associated_type_shorthand_candidates does not do that
@@ -641,7 +641,7 @@ impl<'a> TyLoweringContext<'a> {
641 if let Some(self_ty) = explicit_self_ty { 641 if let Some(self_ty) = explicit_self_ty {
642 substs.0[0] = self_ty; 642 substs.0[0] = self_ty;
643 } 643 }
644 TraitRef { trait_: resolved, substs } 644 TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
645 } 645 }
646 646
647 fn lower_trait_ref( 647 fn lower_trait_ref(
@@ -743,7 +743,7 @@ impl<'a> TyLoweringContext<'a> {
743 }; 743 };
744 let projection_ty = ProjectionTy { 744 let projection_ty = ProjectionTy {
745 associated_ty_id: to_assoc_type_id(associated_ty), 745 associated_ty_id: to_assoc_type_id(associated_ty),
746 substitution: super_trait_ref.substs, 746 substitution: super_trait_ref.substitution,
747 }; 747 };
748 let mut preds = SmallVec::with_capacity( 748 let mut preds = SmallVec::with_capacity(
749 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(), 749 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
@@ -820,8 +820,8 @@ pub fn associated_type_shorthand_candidates<R>(
820 == TypeParamProvenance::TraitSelf 820 == TypeParamProvenance::TraitSelf
821 { 821 {
822 let trait_ref = TraitRef { 822 let trait_ref = TraitRef {
823 trait_: trait_id, 823 trait_id: to_chalk_trait_id(trait_id),
824 substs: Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST), 824 substitution: Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST),
825 }; 825 };
826 traits_.push(trait_ref); 826 traits_.push(trait_ref);
827 } 827 }
@@ -832,7 +832,7 @@ pub fn associated_type_shorthand_candidates<R>(
832 }; 832 };
833 833
834 for t in traits_from_env.into_iter().flat_map(move |t| all_super_trait_refs(db, t)) { 834 for t in traits_from_env.into_iter().flat_map(move |t| all_super_trait_refs(db, t)) {
835 let data = db.trait_data(t.trait_); 835 let data = db.trait_data(t.hir_trait_id());
836 836
837 for (name, assoc_id) in &data.items { 837 for (name, assoc_id) in &data.items {
838 match assoc_id { 838 match assoc_id {
@@ -926,7 +926,7 @@ pub(crate) fn trait_environment_query(
926 continue; 926 continue;
927 } 927 }
928 if let GenericPredicate::Implemented(tr) = &pred { 928 if let GenericPredicate::Implemented(tr) = &pred {
929 traits_in_scope.push((tr.self_ty().clone(), tr.trait_)); 929 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id()));
930 } 930 }
931 let program_clause: chalk_ir::ProgramClause<Interner> = 931 let program_clause: chalk_ir::ProgramClause<Interner> =
932 pred.clone().to_chalk(db).cast(&Interner); 932 pred.clone().to_chalk(db).cast(&Interner);
@@ -950,7 +950,7 @@ pub(crate) fn trait_environment_query(
950 // inside consts or type aliases) 950 // inside consts or type aliases)
951 cov_mark::hit!(trait_self_implements_self); 951 cov_mark::hit!(trait_self_implements_self);
952 let substs = Substitution::type_params(db, trait_id); 952 let substs = Substitution::type_params(db, trait_id);
953 let trait_ref = TraitRef { trait_: trait_id, substs }; 953 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
954 let pred = GenericPredicate::Implemented(trait_ref); 954 let pred = GenericPredicate::Implemented(trait_ref);
955 let program_clause: chalk_ir::ProgramClause<Interner> = 955 let program_clause: chalk_ir::ProgramClause<Interner> =
956 pred.clone().to_chalk(db).cast(&Interner); 956 pred.clone().to_chalk(db).cast(&Interner);
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 943d3339b..01b78fb44 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -19,6 +19,7 @@ use crate::{
19 db::HirDatabase, 19 db::HirDatabase,
20 from_foreign_def_id, 20 from_foreign_def_id,
21 primitive::{self, FloatTy, IntTy, UintTy}, 21 primitive::{self, FloatTy, IntTy, UintTy},
22 to_chalk_trait_id,
22 utils::all_super_traits, 23 utils::all_super_traits,
23 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner, 24 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner,
24 Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, 25 Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
@@ -101,7 +102,7 @@ impl TraitImpls {
101 for (_module_id, module_data) in crate_def_map.modules() { 102 for (_module_id, module_data) in crate_def_map.modules() {
102 for impl_id in module_data.scope.impls() { 103 for impl_id in module_data.scope.impls() {
103 let target_trait = match db.impl_trait(impl_id) { 104 let target_trait = match db.impl_trait(impl_id) {
104 Some(tr) => tr.value.trait_, 105 Some(tr) => tr.value.hir_trait_id(),
105 None => continue, 106 None => continue,
106 }; 107 };
107 let self_ty = db.impl_self_ty(impl_id); 108 let self_ty = db.impl_self_ty(impl_id);
@@ -773,7 +774,7 @@ fn generic_implements_goal(
773 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 774 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
774 .build(); 775 .build();
775 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1)); 776 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1));
776 let trait_ref = TraitRef { trait_, substs }; 777 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
777 let obligation = super::Obligation::Trait(trait_ref); 778 let obligation = super::Obligation::Trait(trait_ref);
778 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } 779 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) }
779} 780}
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index 40eb1034e..a7287dea1 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -137,7 +137,7 @@ pub(crate) fn trait_solve_query(
137 goal: Canonical<InEnvironment<Obligation>>, 137 goal: Canonical<InEnvironment<Obligation>>,
138) -> Option<Solution> { 138) -> Option<Solution> {
139 let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value { 139 let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value {
140 Obligation::Trait(it) => db.trait_data(it.trait_).name.to_string(), 140 Obligation::Trait(it) => db.trait_data(it.hir_trait_id()).name.to_string(),
141 Obligation::Projection(_) => "projection".to_string(), 141 Obligation::Projection(_) => "projection".to_string(),
142 }); 142 });
143 log::info!("trait_solve_query({})", goal.value.value.display(db)); 143 log::info!("trait_solve_query({})", goal.value.value.display(db));
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index bef6e7e9c..bac70f5aa 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -19,7 +19,7 @@ use crate::{
19 display::HirDisplay, 19 display::HirDisplay,
20 from_assoc_type_id, 20 from_assoc_type_id,
21 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, 21 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
22 to_assoc_type_id, 22 to_assoc_type_id, to_chalk_trait_id,
23 utils::generics, 23 utils::generics,
24 BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, GenericPredicate, 24 BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, GenericPredicate,
25 ProjectionPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind, 25 ProjectionPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind,
@@ -219,9 +219,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
219 // for<T> <Self> [Future<Self>, Future::Output<Self> = T] 219 // for<T> <Self> [Future<Self>, Future::Output<Self> = T]
220 // ^1 ^0 ^0 ^0 ^1 220 // ^1 ^0 ^0 ^0 ^1
221 let impl_bound = GenericPredicate::Implemented(TraitRef { 221 let impl_bound = GenericPredicate::Implemented(TraitRef {
222 trait_: future_trait, 222 trait_id: to_chalk_trait_id(future_trait),
223 // Self type as the first parameter. 223 // Self type as the first parameter.
224 substs: Substitution::single( 224 substitution: Substitution::single(
225 TyKind::BoundVar(BoundVar { 225 TyKind::BoundVar(BoundVar {
226 debruijn: DebruijnIndex::INNERMOST, 226 debruijn: DebruijnIndex::INNERMOST,
227 index: 0, 227 index: 0,
@@ -546,7 +546,7 @@ fn impl_def_datum(
546 546
547 let generic_params = generics(db.upcast(), impl_id.into()); 547 let generic_params = generics(db.upcast(), impl_id.into());
548 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 548 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
549 let trait_ = trait_ref.trait_; 549 let trait_ = trait_ref.hir_trait_id();
550 let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate { 550 let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate {
551 rust_ir::ImplType::Local 551 rust_ir::ImplType::Local
552 } else { 552 } else {
@@ -614,7 +614,7 @@ fn type_alias_associated_ty_value(
614 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.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
615 615
616 let assoc_ty = db 616 let assoc_ty = db
617 .trait_data(trait_ref.trait_) 617 .trait_data(trait_ref.hir_trait_id())
618 .associated_type_by_name(&type_alias_data.name) 618 .associated_type_by_name(&type_alias_data.name)
619 .expect("assoc ty value should not exist"); // validated when building the impl data as well 619 .expect("assoc ty value should not exist"); // validated when building the impl data as well
620 let ty = db.ty(type_alias.into()); 620 let ty = db.ty(type_alias.into());
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index d969527dc..0086ce1e9 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -239,15 +239,15 @@ impl ToChalk for TraitRef {
239 type Chalk = chalk_ir::TraitRef<Interner>; 239 type Chalk = chalk_ir::TraitRef<Interner>;
240 240
241 fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef<Interner> { 241 fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef<Interner> {
242 let trait_id = self.trait_.to_chalk(db); 242 let trait_id = self.trait_id;
243 let substitution = self.substs.to_chalk(db); 243 let substitution = self.substitution.to_chalk(db);
244 chalk_ir::TraitRef { trait_id, substitution } 244 chalk_ir::TraitRef { trait_id, substitution }
245 } 245 }
246 246
247 fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self { 247 fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self {
248 let trait_ = from_chalk(db, trait_ref.trait_id); 248 let trait_id = trait_ref.trait_id;
249 let substs = from_chalk(db, trait_ref.substitution); 249 let substs = from_chalk(db, trait_ref.substitution);
250 TraitRef { trait_, substs } 250 TraitRef { trait_id, substitution: substs }
251 } 251 }
252} 252}
253 253
@@ -515,17 +515,16 @@ pub(super) fn generic_predicate_to_inline_bound(
515 // We don't have a special type for this, but Chalk does. 515 // We don't have a special type for this, but Chalk does.
516 match pred { 516 match pred {
517 GenericPredicate::Implemented(trait_ref) => { 517 GenericPredicate::Implemented(trait_ref) => {
518 if &trait_ref.substs[0] != self_ty { 518 if &trait_ref.substitution[0] != self_ty {
519 // we can only convert predicates back to type bounds if they 519 // we can only convert predicates back to type bounds if they
520 // have the expected self type 520 // have the expected self type
521 return None; 521 return None;
522 } 522 }
523 let args_no_self = trait_ref.substs[1..] 523 let args_no_self = trait_ref.substitution[1..]
524 .iter() 524 .iter()
525 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 525 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
526 .collect(); 526 .collect();
527 let trait_bound = 527 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
528 rust_ir::TraitBound { trait_id: trait_ref.trait_.to_chalk(db), args_no_self };
529 Some(rust_ir::InlineBound::TraitBound(trait_bound)) 528 Some(rust_ir::InlineBound::TraitBound(trait_bound))
530 } 529 }
531 GenericPredicate::Projection(proj) => { 530 GenericPredicate::Projection(proj) => {
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index 7351e4e54..b66243d48 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -55,9 +55,9 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
55 // lifetime problems, but since there usually shouldn't be more than a 55 // lifetime problems, but since there usually shouldn't be more than a
56 // few direct traits this should be fine (we could even use some kind of 56 // few direct traits this should be fine (we could even use some kind of
57 // SmallVec if performance is a concern) 57 // SmallVec if performance is a concern)
58 let generic_params = db.generic_params(trait_ref.trait_.into()); 58 let generic_params = db.generic_params(trait_ref.hir_trait_id().into());
59 let trait_self = match generic_params.find_trait_self_param() { 59 let trait_self = match generic_params.find_trait_self_param() {
60 Some(p) => TypeParamId { parent: trait_ref.trait_.into(), local_id: p }, 60 Some(p) => TypeParamId { parent: trait_ref.hir_trait_id().into(), local_id: p },
61 None => return Vec::new(), 61 None => return Vec::new(),
62 }; 62 };
63 db.generic_predicates_for_param(trait_self) 63 db.generic_predicates_for_param(trait_self)
@@ -68,7 +68,7 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
68 _ => None, 68 _ => None,
69 }) 69 })
70 }) 70 })
71 .map(|pred| pred.subst(&trait_ref.substs)) 71 .map(|pred| pred.subst(&trait_ref.substitution))
72 .collect() 72 .collect()
73} 73}
74 74
@@ -108,7 +108,7 @@ pub(super) fn all_super_trait_refs(db: &dyn HirDatabase, trait_ref: TraitRef) ->
108 // yeah this is quadratic, but trait hierarchies should be flat 108 // yeah this is quadratic, but trait hierarchies should be flat
109 // enough that this doesn't matter 109 // enough that this doesn't matter
110 for tt in direct_super_trait_refs(db, t) { 110 for tt in direct_super_trait_refs(db, t) {
111 if !result.iter().any(|tr| tr.trait_ == tt.trait_) { 111 if !result.iter().any(|tr| tr.trait_id == tt.trait_id) {
112 result.push(tt); 112 result.push(tt);
113 } 113 }
114 } 114 }
@@ -123,7 +123,7 @@ pub(super) fn associated_type_by_name_including_super_traits(
123 name: &Name, 123 name: &Name,
124) -> Option<(TraitRef, TypeAliasId)> { 124) -> Option<(TraitRef, TypeAliasId)> {
125 all_super_trait_refs(db, trait_ref).into_iter().find_map(|t| { 125 all_super_trait_refs(db, trait_ref).into_iter().find_map(|t| {
126 let assoc_type = db.trait_data(t.trait_).associated_type_by_name(name)?; 126 let assoc_type = db.trait_data(t.hir_trait_id()).associated_type_by_name(name)?;
127 Some((t, assoc_type)) 127 Some((t, assoc_type))
128 }) 128 })
129} 129}