aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/traits/chalk.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk.rs')
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs141
1 files changed, 72 insertions, 69 deletions
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 555930c9b..4974c565b 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -3,7 +3,7 @@ use std::{fmt, sync::Arc};
3 3
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{cast::Cast, Parameter, PlaceholderIndex, TypeName, UniverseIndex}; 6use chalk_ir::{cast::Cast, GoalData, Parameter, PlaceholderIndex, TypeName, UniverseIndex};
7 7
8use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId}; 8use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId};
9use ra_db::{ 9use ra_db::{
@@ -14,7 +14,7 @@ use ra_db::{
14use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; 14use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
15use crate::{ 15use crate::{
16 db::HirDatabase, display::HirDisplay, utils::generics, ApplicationTy, GenericPredicate, 16 db::HirDatabase, display::HirDisplay, utils::generics, ApplicationTy, GenericPredicate,
17 ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, 17 ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
18}; 18};
19 19
20#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] 20#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
@@ -24,6 +24,8 @@ impl chalk_ir::family::TypeFamily for TypeFamily {
24 type InternedType = Box<chalk_ir::TyData<Self>>; 24 type InternedType = Box<chalk_ir::TyData<Self>>;
25 type InternedLifetime = chalk_ir::LifetimeData<Self>; 25 type InternedLifetime = chalk_ir::LifetimeData<Self>;
26 type InternedParameter = chalk_ir::ParameterData<Self>; 26 type InternedParameter = chalk_ir::ParameterData<Self>;
27 type InternedGoal = Arc<GoalData<Self>>;
28 type InternedSubstitution = Vec<Parameter<Self>>;
27 type DefId = InternId; 29 type DefId = InternId;
28 30
29 // FIXME: implement these 31 // FIXME: implement these
@@ -48,8 +50,8 @@ impl chalk_ir::family::TypeFamily for TypeFamily {
48 None 50 None
49 } 51 }
50 52
51 fn debug_projection( 53 fn debug_alias(
52 _projection: &chalk_ir::ProjectionTy<Self>, 54 _projection: &chalk_ir::AliasTy<Self>,
53 _fmt: &mut fmt::Formatter<'_>, 55 _fmt: &mut fmt::Formatter<'_>,
54 ) -> Option<fmt::Result> { 56 ) -> Option<fmt::Result> {
55 None 57 None
@@ -78,6 +80,24 @@ impl chalk_ir::family::TypeFamily for TypeFamily {
78 fn parameter_data(parameter: &chalk_ir::ParameterData<Self>) -> &chalk_ir::ParameterData<Self> { 80 fn parameter_data(parameter: &chalk_ir::ParameterData<Self>) -> &chalk_ir::ParameterData<Self> {
79 parameter 81 parameter
80 } 82 }
83
84 fn intern_goal(goal: GoalData<Self>) -> Arc<GoalData<Self>> {
85 Arc::new(goal)
86 }
87
88 fn goal_data(goal: &Arc<GoalData<Self>>) -> &GoalData<Self> {
89 goal
90 }
91
92 fn intern_substitution<E>(
93 data: impl IntoIterator<Item = Result<Parameter<Self>, E>>,
94 ) -> Result<Vec<Parameter<Self>>, E> {
95 data.into_iter().collect()
96 }
97
98 fn substitution_data(substitution: &Vec<Parameter<Self>>) -> &[Parameter<Self>] {
99 substitution
100 }
81} 101}
82 102
83impl chalk_ir::family::HasTypeFamily for TypeFamily { 103impl chalk_ir::family::HasTypeFamily for TypeFamily {
@@ -114,17 +134,21 @@ impl ToChalk for Ty {
114 match self { 134 match self {
115 Ty::Apply(apply_ty) => { 135 Ty::Apply(apply_ty) => {
116 let name = apply_ty.ctor.to_chalk(db); 136 let name = apply_ty.ctor.to_chalk(db);
117 let parameters = apply_ty.parameters.to_chalk(db); 137 let substitution = apply_ty.parameters.to_chalk(db);
118 chalk_ir::ApplicationTy { name, parameters }.cast().intern() 138 chalk_ir::ApplicationTy { name, substitution }.cast().intern()
119 } 139 }
120 Ty::Projection(proj_ty) => { 140 Ty::Projection(proj_ty) => {
121 let associated_ty_id = proj_ty.associated_ty.to_chalk(db); 141 let associated_ty_id = proj_ty.associated_ty.to_chalk(db);
122 let parameters = proj_ty.parameters.to_chalk(db); 142 let substitution = proj_ty.parameters.to_chalk(db);
123 chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast().intern() 143 chalk_ir::AliasTy { associated_ty_id, substitution }.cast().intern()
124 } 144 }
125 Ty::Param { idx, .. } => { 145 Ty::Param(id) => {
126 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize } 146 let interned_id = db.intern_type_param_id(id);
127 .to_ty::<TypeFamily>() 147 PlaceholderIndex {
148 ui: UniverseIndex::ROOT,
149 idx: interned_id.as_intern_id().as_usize(),
150 }
151 .to_ty::<TypeFamily>()
128 } 152 }
129 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(), 153 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(),
130 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 154 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
@@ -135,23 +159,13 @@ impl ToChalk for Ty {
135 .cloned() 159 .cloned()
136 .map(|p| p.to_chalk(db)) 160 .map(|p| p.to_chalk(db))
137 .collect(); 161 .collect();
138 let bounded_ty = chalk_ir::BoundedTy { bounds: make_binders(where_clauses, 1) }; 162 let bounded_ty = chalk_ir::DynTy { bounds: make_binders(where_clauses, 1) };
139 chalk_ir::TyData::Dyn(bounded_ty).intern() 163 chalk_ir::TyData::Dyn(bounded_ty).intern()
140 } 164 }
141 Ty::Opaque(predicates) => { 165 Ty::Opaque(_) | Ty::Unknown => {
142 let where_clauses = predicates 166 let substitution = chalk_ir::Substitution::empty();
143 .iter()
144 .filter(|p| !p.is_error())
145 .cloned()
146 .map(|p| p.to_chalk(db))
147 .collect();
148 let bounded_ty = chalk_ir::BoundedTy { bounds: make_binders(where_clauses, 1) };
149 chalk_ir::TyData::Opaque(bounded_ty).intern()
150 }
151 Ty::Unknown => {
152 let parameters = Vec::new();
153 let name = TypeName::Error; 167 let name = TypeName::Error;
154 chalk_ir::ApplicationTy { name, parameters }.cast().intern() 168 chalk_ir::ApplicationTy { name, substitution }.cast().intern()
155 } 169 }
156 } 170 }
157 } 171 }
@@ -161,20 +175,23 @@ impl ToChalk for Ty {
161 TypeName::Error => Ty::Unknown, 175 TypeName::Error => Ty::Unknown,
162 _ => { 176 _ => {
163 let ctor = from_chalk(db, apply_ty.name); 177 let ctor = from_chalk(db, apply_ty.name);
164 let parameters = from_chalk(db, apply_ty.parameters); 178 let parameters = from_chalk(db, apply_ty.substitution);
165 Ty::Apply(ApplicationTy { ctor, parameters }) 179 Ty::Apply(ApplicationTy { ctor, parameters })
166 } 180 }
167 }, 181 },
168 chalk_ir::TyData::Placeholder(idx) => { 182 chalk_ir::TyData::Placeholder(idx) => {
169 assert_eq!(idx.ui, UniverseIndex::ROOT); 183 assert_eq!(idx.ui, UniverseIndex::ROOT);
170 Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() } 184 let interned_id = crate::db::GlobalTypeParamId::from_intern_id(
185 crate::salsa::InternId::from(idx.idx),
186 );
187 Ty::Param(db.lookup_intern_type_param_id(interned_id))
171 } 188 }
172 chalk_ir::TyData::Projection(proj) => { 189 chalk_ir::TyData::Alias(proj) => {
173 let associated_ty = from_chalk(db, proj.associated_ty_id); 190 let associated_ty = from_chalk(db, proj.associated_ty_id);
174 let parameters = from_chalk(db, proj.parameters); 191 let parameters = from_chalk(db, proj.substitution);
175 Ty::Projection(ProjectionTy { associated_ty, parameters }) 192 Ty::Projection(ProjectionTy { associated_ty, parameters })
176 } 193 }
177 chalk_ir::TyData::ForAll(_) => unimplemented!(), 194 chalk_ir::TyData::Function(_) => unimplemented!(),
178 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx as u32), 195 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx as u32),
179 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown, 196 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown,
180 chalk_ir::TyData::Dyn(where_clauses) => { 197 chalk_ir::TyData::Dyn(where_clauses) => {
@@ -183,27 +200,18 @@ impl ToChalk for Ty {
183 where_clauses.bounds.value.into_iter().map(|c| from_chalk(db, c)).collect(); 200 where_clauses.bounds.value.into_iter().map(|c| from_chalk(db, c)).collect();
184 Ty::Dyn(predicates) 201 Ty::Dyn(predicates)
185 } 202 }
186 chalk_ir::TyData::Opaque(where_clauses) => {
187 assert_eq!(where_clauses.bounds.binders.len(), 1);
188 let predicates =
189 where_clauses.bounds.value.into_iter().map(|c| from_chalk(db, c)).collect();
190 Ty::Opaque(predicates)
191 }
192 } 203 }
193 } 204 }
194} 205}
195 206
196impl ToChalk for Substs { 207impl ToChalk for Substs {
197 type Chalk = Vec<chalk_ir::Parameter<TypeFamily>>; 208 type Chalk = chalk_ir::Substitution<TypeFamily>;
198 209
199 fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter<TypeFamily>> { 210 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Substitution<TypeFamily> {
200 self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect() 211 chalk_ir::Substitution::from(self.iter().map(|ty| ty.clone().to_chalk(db)))
201 } 212 }
202 213
203 fn from_chalk( 214 fn from_chalk(db: &impl HirDatabase, parameters: chalk_ir::Substitution<TypeFamily>) -> Substs {
204 db: &impl HirDatabase,
205 parameters: Vec<chalk_ir::Parameter<TypeFamily>>,
206 ) -> Substs {
207 let tys = parameters 215 let tys = parameters
208 .into_iter() 216 .into_iter()
209 .map(|p| match p.ty() { 217 .map(|p| match p.ty() {
@@ -220,13 +228,13 @@ impl ToChalk for TraitRef {
220 228
221 fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<TypeFamily> { 229 fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<TypeFamily> {
222 let trait_id = self.trait_.to_chalk(db); 230 let trait_id = self.trait_.to_chalk(db);
223 let parameters = self.substs.to_chalk(db); 231 let substitution = self.substs.to_chalk(db);
224 chalk_ir::TraitRef { trait_id, parameters } 232 chalk_ir::TraitRef { trait_id, substitution }
225 } 233 }
226 234
227 fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<TypeFamily>) -> Self { 235 fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<TypeFamily>) -> Self {
228 let trait_ = from_chalk(db, trait_ref.trait_id); 236 let trait_ = from_chalk(db, trait_ref.trait_id);
229 let substs = from_chalk(db, trait_ref.parameters); 237 let substs = from_chalk(db, trait_ref.substitution);
230 TraitRef { trait_, substs } 238 TraitRef { trait_, substs }
231 } 239 }
232} 240}
@@ -317,8 +325,8 @@ impl ToChalk for GenericPredicate {
317 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) 325 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0)
318 } 326 }
319 GenericPredicate::Projection(projection_pred) => make_binders( 327 GenericPredicate::Projection(projection_pred) => make_binders(
320 chalk_ir::WhereClause::ProjectionEq(chalk_ir::ProjectionEq { 328 chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq {
321 projection: projection_pred.projection_ty.to_chalk(db), 329 alias: projection_pred.projection_ty.to_chalk(db),
322 ty: projection_pred.ty.to_chalk(db), 330 ty: projection_pred.ty.to_chalk(db),
323 }), 331 }),
324 0, 332 0,
@@ -335,8 +343,8 @@ impl ToChalk for GenericPredicate {
335 chalk_ir::WhereClause::Implemented(tr) => { 343 chalk_ir::WhereClause::Implemented(tr) => {
336 GenericPredicate::Implemented(from_chalk(db, tr)) 344 GenericPredicate::Implemented(from_chalk(db, tr))
337 } 345 }
338 chalk_ir::WhereClause::ProjectionEq(projection_eq) => { 346 chalk_ir::WhereClause::AliasEq(projection_eq) => {
339 let projection_ty = from_chalk(db, projection_eq.projection); 347 let projection_ty = from_chalk(db, projection_eq.alias);
340 let ty = from_chalk(db, projection_eq.ty); 348 let ty = from_chalk(db, projection_eq.ty);
341 GenericPredicate::Projection(super::ProjectionPredicate { projection_ty, ty }) 349 GenericPredicate::Projection(super::ProjectionPredicate { projection_ty, ty })
342 } 350 }
@@ -345,22 +353,22 @@ impl ToChalk for GenericPredicate {
345} 353}
346 354
347impl ToChalk for ProjectionTy { 355impl ToChalk for ProjectionTy {
348 type Chalk = chalk_ir::ProjectionTy<TypeFamily>; 356 type Chalk = chalk_ir::AliasTy<TypeFamily>;
349 357
350 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy<TypeFamily> { 358 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::AliasTy<TypeFamily> {
351 chalk_ir::ProjectionTy { 359 chalk_ir::AliasTy {
352 associated_ty_id: self.associated_ty.to_chalk(db), 360 associated_ty_id: self.associated_ty.to_chalk(db),
353 parameters: self.parameters.to_chalk(db), 361 substitution: self.parameters.to_chalk(db),
354 } 362 }
355 } 363 }
356 364
357 fn from_chalk( 365 fn from_chalk(
358 db: &impl HirDatabase, 366 db: &impl HirDatabase,
359 projection_ty: chalk_ir::ProjectionTy<TypeFamily>, 367 projection_ty: chalk_ir::AliasTy<TypeFamily>,
360 ) -> ProjectionTy { 368 ) -> ProjectionTy {
361 ProjectionTy { 369 ProjectionTy {
362 associated_ty: from_chalk(db, projection_ty.associated_ty_id), 370 associated_ty: from_chalk(db, projection_ty.associated_ty_id),
363 parameters: from_chalk(db, projection_ty.parameters), 371 parameters: from_chalk(db, projection_ty.substitution),
364 } 372 }
365 } 373 }
366} 374}
@@ -369,10 +377,7 @@ impl ToChalk for super::ProjectionPredicate {
369 type Chalk = chalk_ir::Normalize<TypeFamily>; 377 type Chalk = chalk_ir::Normalize<TypeFamily>;
370 378
371 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<TypeFamily> { 379 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<TypeFamily> {
372 chalk_ir::Normalize { 380 chalk_ir::Normalize { alias: self.projection_ty.to_chalk(db), ty: self.ty.to_chalk(db) }
373 projection: self.projection_ty.to_chalk(db),
374 ty: self.ty.to_chalk(db),
375 }
376 } 381 }
377 382
378 fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<TypeFamily>) -> Self { 383 fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<TypeFamily>) -> Self {
@@ -522,7 +527,7 @@ fn convert_where_clauses(
522 let generic_predicates = db.generic_predicates(def); 527 let generic_predicates = db.generic_predicates(def);
523 let mut result = Vec::with_capacity(generic_predicates.len()); 528 let mut result = Vec::with_capacity(generic_predicates.len());
524 for pred in generic_predicates.iter() { 529 for pred in generic_predicates.iter() {
525 if pred.is_error() { 530 if pred.value.is_error() {
526 // skip errored predicates completely 531 // skip errored predicates completely
527 continue; 532 continue;
528 } 533 }
@@ -711,12 +716,12 @@ fn impl_block_datum(
711 let trait_ref = db 716 let trait_ref = db
712 .impl_trait(impl_id) 717 .impl_trait(impl_id)
713 // ImplIds for impls where the trait ref can't be resolved should never reach Chalk 718 // ImplIds for impls where the trait ref can't be resolved should never reach Chalk
714 .expect("invalid impl passed to Chalk"); 719 .expect("invalid impl passed to Chalk")
720 .value;
715 let impl_data = db.impl_data(impl_id); 721 let impl_data = db.impl_data(impl_id);
716 722
717 let generic_params = generics(db, impl_id.into()); 723 let generic_params = generics(db, impl_id.into());
718 let bound_vars = Substs::bound_vars(&generic_params); 724 let bound_vars = Substs::bound_vars(&generic_params);
719 let trait_ref = trait_ref.subst(&bound_vars);
720 let trait_ = trait_ref.trait_; 725 let trait_ = trait_ref.trait_;
721 let impl_type = if impl_id.lookup(db).container.module(db).krate == krate { 726 let impl_type = if impl_id.lookup(db).container.module(db).krate == krate {
722 chalk_rust_ir::ImplType::Local 727 chalk_rust_ir::ImplType::Local
@@ -791,20 +796,18 @@ fn type_alias_associated_ty_value(
791 _ => panic!("assoc ty value should be in impl"), 796 _ => panic!("assoc ty value should be in impl"),
792 }; 797 };
793 798
794 let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist"); // we don't return any assoc ty values if the impl'd trait can't be resolved 799 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
795 800
796 let assoc_ty = db 801 let assoc_ty = db
797 .trait_data(trait_ref.trait_) 802 .trait_data(trait_ref.trait_)
798 .associated_type_by_name(&type_alias_data.name) 803 .associated_type_by_name(&type_alias_data.name)
799 .expect("assoc ty value should not exist"); // validated when building the impl data as well 804 .expect("assoc ty value should not exist"); // validated when building the impl data as well
800 let generic_params = generics(db, impl_id.into()); 805 let ty = db.ty(type_alias.into());
801 let bound_vars = Substs::bound_vars(&generic_params); 806 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) };
802 let ty = db.ty(type_alias.into()).subst(&bound_vars);
803 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) };
804 let value = chalk_rust_ir::AssociatedTyValue { 807 let value = chalk_rust_ir::AssociatedTyValue {
805 impl_id: Impl::ImplBlock(impl_id.into()).to_chalk(db), 808 impl_id: Impl::ImplBlock(impl_id.into()).to_chalk(db),
806 associated_ty_id: assoc_ty.to_chalk(db), 809 associated_ty_id: assoc_ty.to_chalk(db),
807 value: make_binders(value_bound, bound_vars.len()), 810 value: make_binders(value_bound, ty.num_binders),
808 }; 811 };
809 Arc::new(value) 812 Arc::new(value)
810} 813}