aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/traits
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/traits')
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs110
1 files changed, 70 insertions, 40 deletions
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 00aaf65d9..ad7c11a5a 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -4,8 +4,8 @@ use std::sync::Arc;
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{ 6use chalk_ir::{
7 cast::Cast, Identifier, ImplId, Parameter, PlaceholderIndex, TypeId, TypeKindId, TypeName, 7 cast::Cast, family::ChalkIr, Identifier, ImplId, Parameter, PlaceholderIndex, TypeId,
8 UniverseIndex, 8 TypeKindId, TypeName, UniverseIndex,
9}; 9};
10use chalk_rust_ir::{AssociatedTyDatum, ImplDatum, StructDatum, TraitDatum}; 10use chalk_rust_ir::{AssociatedTyDatum, ImplDatum, StructDatum, TraitDatum};
11 11
@@ -38,8 +38,8 @@ where
38} 38}
39 39
40impl ToChalk for Ty { 40impl ToChalk for Ty {
41 type Chalk = chalk_ir::Ty; 41 type Chalk = chalk_ir::Ty<ChalkIr>;
42 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty { 42 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty<ChalkIr> {
43 match self { 43 match self {
44 Ty::Apply(apply_ty) => { 44 Ty::Apply(apply_ty) => {
45 let name = match apply_ty.ctor { 45 let name = match apply_ty.ctor {
@@ -62,21 +62,21 @@ impl ToChalk for Ty {
62 chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast() 62 chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast()
63 } 63 }
64 Ty::Param { idx, .. } => { 64 Ty::Param { idx, .. } => {
65 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty() 65 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty::<ChalkIr>()
66 } 66 }
67 Ty::Bound(idx) => chalk_ir::Ty::BoundVar(idx as usize), 67 Ty::Bound(idx) => chalk_ir::Ty::BoundVar(idx as usize),
68 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 68 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
69 // FIXME this is clearly incorrect, but probably not too incorrect 69 // FIXME this is clearly incorrect, but probably not too incorrect
70 // and I'm not sure what to actually do with Ty::Unknown 70 // and I'm not sure what to actually do with Ty::Unknown
71 // maybe an alternative would be `for<T> T`? (meaningless in rust, but expressible in chalk's Ty) 71 // maybe an alternative would be `for<T> T`? (meaningless in rust, but expressible in chalk's Ty)
72 // 72 // FIXME use Chalk's Dyn/Opaque once the bugs with that are fixed
73 // FIXME also dyn and impl Trait are currently handled like Unknown because Chalk doesn't have them yet
74 Ty::Unknown | Ty::Dyn(_) | Ty::Opaque(_) => { 73 Ty::Unknown | Ty::Dyn(_) | Ty::Opaque(_) => {
75 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::max_value() }.to_ty() 74 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::max_value() }
75 .to_ty::<ChalkIr>()
76 } 76 }
77 } 77 }
78 } 78 }
79 fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty) -> Self { 79 fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty<ChalkIr>) -> Self {
80 match chalk { 80 match chalk {
81 chalk_ir::Ty::Apply(apply_ty) => { 81 chalk_ir::Ty::Apply(apply_ty) => {
82 // FIXME this is kind of hacky due to the fact that 82 // FIXME this is kind of hacky due to the fact that
@@ -108,18 +108,30 @@ impl ToChalk for Ty {
108 chalk_ir::Ty::ForAll(_) => unimplemented!(), 108 chalk_ir::Ty::ForAll(_) => unimplemented!(),
109 chalk_ir::Ty::BoundVar(idx) => Ty::Bound(idx as u32), 109 chalk_ir::Ty::BoundVar(idx) => Ty::Bound(idx as u32),
110 chalk_ir::Ty::InferenceVar(_iv) => Ty::Unknown, 110 chalk_ir::Ty::InferenceVar(_iv) => Ty::Unknown,
111 chalk_ir::Ty::Dyn(where_clauses) => {
112 assert_eq!(where_clauses.binders.len(), 1);
113 let predicates =
114 where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect();
115 Ty::Dyn(predicates)
116 }
117 chalk_ir::Ty::Opaque(where_clauses) => {
118 assert_eq!(where_clauses.binders.len(), 1);
119 let predicates =
120 where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect();
121 Ty::Opaque(predicates)
122 }
111 } 123 }
112 } 124 }
113} 125}
114 126
115impl ToChalk for Substs { 127impl ToChalk for Substs {
116 type Chalk = Vec<chalk_ir::Parameter>; 128 type Chalk = Vec<chalk_ir::Parameter<ChalkIr>>;
117 129
118 fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter> { 130 fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter<ChalkIr>> {
119 self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect() 131 self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect()
120 } 132 }
121 133
122 fn from_chalk(db: &impl HirDatabase, parameters: Vec<chalk_ir::Parameter>) -> Substs { 134 fn from_chalk(db: &impl HirDatabase, parameters: Vec<chalk_ir::Parameter<ChalkIr>>) -> Substs {
123 let tys = parameters 135 let tys = parameters
124 .into_iter() 136 .into_iter()
125 .map(|p| match p { 137 .map(|p| match p {
@@ -132,15 +144,15 @@ impl ToChalk for Substs {
132} 144}
133 145
134impl ToChalk for TraitRef { 146impl ToChalk for TraitRef {
135 type Chalk = chalk_ir::TraitRef; 147 type Chalk = chalk_ir::TraitRef<ChalkIr>;
136 148
137 fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef { 149 fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<ChalkIr> {
138 let trait_id = self.trait_.to_chalk(db); 150 let trait_id = self.trait_.to_chalk(db);
139 let parameters = self.substs.to_chalk(db); 151 let parameters = self.substs.to_chalk(db);
140 chalk_ir::TraitRef { trait_id, parameters } 152 chalk_ir::TraitRef { trait_id, parameters }
141 } 153 }
142 154
143 fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef) -> Self { 155 fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<ChalkIr>) -> Self {
144 let trait_ = from_chalk(db, trait_ref.trait_id); 156 let trait_ = from_chalk(db, trait_ref.trait_id);
145 let substs = from_chalk(db, trait_ref.parameters); 157 let substs = from_chalk(db, trait_ref.parameters);
146 TraitRef { trait_, substs } 158 TraitRef { trait_, substs }
@@ -196,9 +208,9 @@ impl ToChalk for TypeAlias {
196} 208}
197 209
198impl ToChalk for GenericPredicate { 210impl ToChalk for GenericPredicate {
199 type Chalk = chalk_ir::QuantifiedWhereClause; 211 type Chalk = chalk_ir::QuantifiedWhereClause<ChalkIr>;
200 212
201 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause { 213 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause<ChalkIr> {
202 match self { 214 match self {
203 GenericPredicate::Implemented(trait_ref) => { 215 GenericPredicate::Implemented(trait_ref) => {
204 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) 216 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0)
@@ -221,25 +233,40 @@ impl ToChalk for GenericPredicate {
221 } 233 }
222 234
223 fn from_chalk( 235 fn from_chalk(
224 _db: &impl HirDatabase, 236 db: &impl HirDatabase,
225 _where_clause: chalk_ir::QuantifiedWhereClause, 237 where_clause: chalk_ir::QuantifiedWhereClause<ChalkIr>,
226 ) -> GenericPredicate { 238 ) -> GenericPredicate {
227 // This should never need to be called 239 match where_clause.value {
228 unimplemented!() 240 chalk_ir::WhereClause::Implemented(tr) => {
241 if tr.trait_id == UNKNOWN_TRAIT {
242 // FIXME we need an Error enum on the Chalk side to avoid this
243 return GenericPredicate::Error;
244 }
245 GenericPredicate::Implemented(from_chalk(db, tr))
246 }
247 chalk_ir::WhereClause::ProjectionEq(projection_eq) => {
248 let projection_ty = from_chalk(db, projection_eq.projection);
249 let ty = from_chalk(db, projection_eq.ty);
250 GenericPredicate::Projection(super::ProjectionPredicate { projection_ty, ty })
251 }
252 }
229 } 253 }
230} 254}
231 255
232impl ToChalk for ProjectionTy { 256impl ToChalk for ProjectionTy {
233 type Chalk = chalk_ir::ProjectionTy; 257 type Chalk = chalk_ir::ProjectionTy<ChalkIr>;
234 258
235 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy { 259 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy<ChalkIr> {
236 chalk_ir::ProjectionTy { 260 chalk_ir::ProjectionTy {
237 associated_ty_id: self.associated_ty.to_chalk(db), 261 associated_ty_id: self.associated_ty.to_chalk(db),
238 parameters: self.parameters.to_chalk(db), 262 parameters: self.parameters.to_chalk(db),
239 } 263 }
240 } 264 }
241 265
242 fn from_chalk(db: &impl HirDatabase, projection_ty: chalk_ir::ProjectionTy) -> ProjectionTy { 266 fn from_chalk(
267 db: &impl HirDatabase,
268 projection_ty: chalk_ir::ProjectionTy<ChalkIr>,
269 ) -> ProjectionTy {
243 ProjectionTy { 270 ProjectionTy {
244 associated_ty: from_chalk(db, projection_ty.associated_ty_id), 271 associated_ty: from_chalk(db, projection_ty.associated_ty_id),
245 parameters: from_chalk(db, projection_ty.parameters), 272 parameters: from_chalk(db, projection_ty.parameters),
@@ -248,31 +275,31 @@ impl ToChalk for ProjectionTy {
248} 275}
249 276
250impl ToChalk for super::ProjectionPredicate { 277impl ToChalk for super::ProjectionPredicate {
251 type Chalk = chalk_ir::Normalize; 278 type Chalk = chalk_ir::Normalize<ChalkIr>;
252 279
253 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize { 280 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<ChalkIr> {
254 chalk_ir::Normalize { 281 chalk_ir::Normalize {
255 projection: self.projection_ty.to_chalk(db), 282 projection: self.projection_ty.to_chalk(db),
256 ty: self.ty.to_chalk(db), 283 ty: self.ty.to_chalk(db),
257 } 284 }
258 } 285 }
259 286
260 fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize) -> Self { 287 fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<ChalkIr>) -> Self {
261 unimplemented!() 288 unimplemented!()
262 } 289 }
263} 290}
264 291
265impl ToChalk for Obligation { 292impl ToChalk for Obligation {
266 type Chalk = chalk_ir::DomainGoal; 293 type Chalk = chalk_ir::DomainGoal<ChalkIr>;
267 294
268 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal { 295 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal<ChalkIr> {
269 match self { 296 match self {
270 Obligation::Trait(tr) => tr.to_chalk(db).cast(), 297 Obligation::Trait(tr) => tr.to_chalk(db).cast(),
271 Obligation::Projection(pr) => pr.to_chalk(db).cast(), 298 Obligation::Projection(pr) => pr.to_chalk(db).cast(),
272 } 299 }
273 } 300 }
274 301
275 fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal) -> Self { 302 fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal<ChalkIr>) -> Self {
276 unimplemented!() 303 unimplemented!()
277 } 304 }
278} 305}
@@ -296,16 +323,16 @@ where
296} 323}
297 324
298impl ToChalk for Arc<super::TraitEnvironment> { 325impl ToChalk for Arc<super::TraitEnvironment> {
299 type Chalk = Arc<chalk_ir::Environment>; 326 type Chalk = Arc<chalk_ir::Environment<ChalkIr>>;
300 327
301 fn to_chalk(self, db: &impl HirDatabase) -> Arc<chalk_ir::Environment> { 328 fn to_chalk(self, db: &impl HirDatabase) -> Arc<chalk_ir::Environment<ChalkIr>> {
302 let mut clauses = Vec::new(); 329 let mut clauses = Vec::new();
303 for pred in &self.predicates { 330 for pred in &self.predicates {
304 if pred.is_error() { 331 if pred.is_error() {
305 // for env, we just ignore errors 332 // for env, we just ignore errors
306 continue; 333 continue;
307 } 334 }
308 let program_clause: chalk_ir::ProgramClause = pred.clone().to_chalk(db).cast(); 335 let program_clause: chalk_ir::ProgramClause<ChalkIr> = pred.clone().to_chalk(db).cast();
309 clauses.push(program_clause.into_from_env_clause()); 336 clauses.push(program_clause.into_from_env_clause());
310 } 337 }
311 chalk_ir::Environment::new().add_clauses(clauses) 338 chalk_ir::Environment::new().add_clauses(clauses)
@@ -313,13 +340,16 @@ impl ToChalk for Arc<super::TraitEnvironment> {
313 340
314 fn from_chalk( 341 fn from_chalk(
315 _db: &impl HirDatabase, 342 _db: &impl HirDatabase,
316 _env: Arc<chalk_ir::Environment>, 343 _env: Arc<chalk_ir::Environment<ChalkIr>>,
317 ) -> Arc<super::TraitEnvironment> { 344 ) -> Arc<super::TraitEnvironment> {
318 unimplemented!() 345 unimplemented!()
319 } 346 }
320} 347}
321 348
322impl<T: ToChalk> ToChalk for super::InEnvironment<T> { 349impl<T: ToChalk> ToChalk for super::InEnvironment<T>
350where
351 T::Chalk: chalk_ir::family::HasTypeFamily<TypeFamily = ChalkIr>,
352{
323 type Chalk = chalk_ir::InEnvironment<T::Chalk>; 353 type Chalk = chalk_ir::InEnvironment<T::Chalk>;
324 354
325 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> { 355 fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> {
@@ -351,7 +381,7 @@ fn convert_where_clauses(
351 db: &impl HirDatabase, 381 db: &impl HirDatabase,
352 def: GenericDef, 382 def: GenericDef,
353 substs: &Substs, 383 substs: &Substs,
354) -> Vec<chalk_ir::QuantifiedWhereClause> { 384) -> Vec<chalk_ir::QuantifiedWhereClause<ChalkIr>> {
355 let generic_predicates = db.generic_predicates(def); 385 let generic_predicates = db.generic_predicates(def);
356 let mut result = Vec::with_capacity(generic_predicates.len()); 386 let mut result = Vec::with_capacity(generic_predicates.len());
357 for pred in generic_predicates.iter() { 387 for pred in generic_predicates.iter() {
@@ -384,7 +414,7 @@ where
384 fn impls_for_trait( 414 fn impls_for_trait(
385 &self, 415 &self,
386 trait_id: chalk_ir::TraitId, 416 trait_id: chalk_ir::TraitId,
387 parameters: &[Parameter], 417 parameters: &[Parameter<ChalkIr>],
388 ) -> Vec<ImplId> { 418 ) -> Vec<ImplId> {
389 debug!("impls_for_trait {:?}", trait_id); 419 debug!("impls_for_trait {:?}", trait_id);
390 if trait_id == UNKNOWN_TRAIT { 420 if trait_id == UNKNOWN_TRAIT {
@@ -430,13 +460,13 @@ where
430 } 460 }
431 fn split_projection<'p>( 461 fn split_projection<'p>(
432 &self, 462 &self,
433 projection: &'p chalk_ir::ProjectionTy, 463 projection: &'p chalk_ir::ProjectionTy<ChalkIr>,
434 ) -> (Arc<AssociatedTyDatum>, &'p [Parameter], &'p [Parameter]) { 464 ) -> (Arc<AssociatedTyDatum>, &'p [Parameter<ChalkIr>], &'p [Parameter<ChalkIr>]) {
435 debug!("split_projection {:?}", projection); 465 debug!("split_projection {:?}", projection);
436 // we don't support GATs, so I think this should always be correct currently 466 // we don't support GATs, so I think this should always be correct currently
437 (self.db.associated_ty_data(projection.associated_ty_id), &projection.parameters, &[]) 467 (self.db.associated_ty_data(projection.associated_ty_id), &projection.parameters, &[])
438 } 468 }
439 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause> { 469 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<ChalkIr>> {
440 vec![] 470 vec![]
441 } 471 }
442 fn local_impls_to_coherence_check( 472 fn local_impls_to_coherence_check(