aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/traits
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-04-05 17:24:18 +0100
committerFlorian Diebold <[email protected]>2020-04-05 18:23:18 +0100
commit952714685a7c0e0a1c9970839ce307806adaa176 (patch)
tree2d002aa05d91133886bb592ba79e4c9238e37343 /crates/ra_hir_ty/src/traits
parent3659502816134b45448799acf428055e40fdf4fc (diff)
Upgrade Chalk again
The big change here is counting binders, not variables (https://github.com/rust-lang/chalk/pull/360). We have to adapt to the same scheme for our `Ty::Bound`. It's mostly fine though, even makes some things more clear.
Diffstat (limited to 'crates/ra_hir_ty/src/traits')
-rw-r--r--crates/ra_hir_ty/src/traits/builtin.rs53
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs30
2 files changed, 53 insertions, 30 deletions
diff --git a/crates/ra_hir_ty/src/traits/builtin.rs b/crates/ra_hir_ty/src/traits/builtin.rs
index 73e3c5c78..ccab246bf 100644
--- a/crates/ra_hir_ty/src/traits/builtin.rs
+++ b/crates/ra_hir_ty/src/traits/builtin.rs
@@ -8,7 +8,8 @@ use super::{AssocTyValue, Impl, UnsizeToSuperTraitObjectData};
8use crate::{ 8use crate::{
9 db::HirDatabase, 9 db::HirDatabase,
10 utils::{all_super_traits, generics}, 10 utils::{all_super_traits, generics},
11 ApplicationTy, Binders, GenericPredicate, Substs, TraitRef, Ty, TypeCtor, 11 ApplicationTy, Binders, BoundVar, DebruijnIndex, GenericPredicate, Substs, TraitRef, Ty,
12 TypeCtor, TypeWalk,
12}; 13};
13 14
14pub(super) struct BuiltinImplData { 15pub(super) struct BuiltinImplData {
@@ -164,11 +165,15 @@ fn closure_fn_trait_impl_datum(
164 165
165 let arg_ty = Ty::apply( 166 let arg_ty = Ty::apply(
166 TypeCtor::Tuple { cardinality: num_args }, 167 TypeCtor::Tuple { cardinality: num_args },
167 Substs::builder(num_args as usize).fill_with_bound_vars(0).build(), 168 Substs::builder(num_args as usize)
169 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
170 .build(),
168 ); 171 );
169 let sig_ty = Ty::apply( 172 let sig_ty = Ty::apply(
170 TypeCtor::FnPtr { num_args }, 173 TypeCtor::FnPtr { num_args },
171 Substs::builder(num_args as usize + 1).fill_with_bound_vars(0).build(), 174 Substs::builder(num_args as usize + 1)
175 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
176 .build(),
172 ); 177 );
173 178
174 let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty); 179 let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty);
@@ -203,7 +208,7 @@ fn closure_fn_trait_output_assoc_ty_value(
203 } 208 }
204 }; 209 };
205 210
206 let output_ty = Ty::Bound(num_args.into()); 211 let output_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, num_args.into()));
207 212
208 let fn_once_trait = 213 let fn_once_trait =
209 get_fn_trait(db, krate, super::FnTrait::FnOnce).expect("assoc ty value should not exist"); 214 get_fn_trait(db, krate, super::FnTrait::FnOnce).expect("assoc ty value should not exist");
@@ -241,7 +246,7 @@ fn array_unsize_impl_datum(db: &dyn HirDatabase, krate: CrateId) -> BuiltinImplD
241 // the existence of the Unsize trait has been checked before 246 // the existence of the Unsize trait has been checked before
242 .expect("Unsize trait missing"); 247 .expect("Unsize trait missing");
243 248
244 let var = Ty::Bound(0); 249 let var = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
245 let substs = Substs::builder(2) 250 let substs = Substs::builder(2)
246 .push(Ty::apply_one(TypeCtor::Array, var.clone())) 251 .push(Ty::apply_one(TypeCtor::Array, var.clone()))
247 .push(Ty::apply_one(TypeCtor::Slice, var)) 252 .push(Ty::apply_one(TypeCtor::Slice, var))
@@ -270,19 +275,18 @@ fn trait_object_unsize_impl_datum(
270 // the existence of the Unsize trait has been checked before 275 // the existence of the Unsize trait has been checked before
271 .expect("Unsize trait missing"); 276 .expect("Unsize trait missing");
272 277
273 let self_ty = Ty::Bound(0); 278 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
274 279
275 let target_substs = Substs::build_for_def(db, trait_) 280 let target_substs = Substs::build_for_def(db, trait_)
276 .push(Ty::Bound(0)) 281 .push(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)))
277 // starting from ^2 because we want to start with ^1 outside of the 282 .fill_with_bound_vars(DebruijnIndex::ONE, 1)
278 // `dyn`, which is ^2 inside
279 .fill_with_bound_vars(2)
280 .build(); 283 .build();
281 let num_vars = target_substs.len(); 284 let num_vars = target_substs.len();
282 let target_trait_ref = TraitRef { trait_, substs: target_substs }; 285 let target_trait_ref = TraitRef { trait_, substs: target_substs };
283 let target_bounds = vec![GenericPredicate::Implemented(target_trait_ref)]; 286 let target_bounds = vec![GenericPredicate::Implemented(target_trait_ref)];
284 287
285 let self_substs = Substs::build_for_def(db, trait_).fill_with_bound_vars(0).build(); 288 let self_substs =
289 Substs::build_for_def(db, trait_).fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build();
286 let self_trait_ref = TraitRef { trait_, substs: self_substs }; 290 let self_trait_ref = TraitRef { trait_, substs: self_substs };
287 let where_clauses = vec![GenericPredicate::Implemented(self_trait_ref)]; 291 let where_clauses = vec![GenericPredicate::Implemented(self_trait_ref)];
288 292
@@ -305,24 +309,26 @@ fn super_trait_object_unsize_impl_datum(
305 // the existence of the Unsize trait has been checked before 309 // the existence of the Unsize trait has been checked before
306 .expect("Unsize trait missing"); 310 .expect("Unsize trait missing");
307 311
308 let self_substs = Substs::build_for_def(db, data.trait_).fill_with_bound_vars(0).build(); 312 let self_substs = Substs::build_for_def(db, data.trait_)
313 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
314 .build();
315 let self_trait_ref = TraitRef { trait_: data.trait_, substs: self_substs.clone() };
309 316
310 let num_vars = self_substs.len() - 1; 317 let num_vars = self_substs.len() - 1;
311 318
312 let self_trait_ref = TraitRef { trait_: data.trait_, substs: self_substs.clone() };
313 let self_bounds = vec![GenericPredicate::Implemented(self_trait_ref.clone())];
314
315 // we need to go from our trait to the super trait, substituting type parameters 319 // we need to go from our trait to the super trait, substituting type parameters
316 let path = crate::utils::find_super_trait_path(db.upcast(), data.trait_, data.super_trait); 320 let path = crate::utils::find_super_trait_path(db.upcast(), data.trait_, data.super_trait);
317 321
318 let mut current_trait_ref = self_trait_ref; 322 let mut current_trait_ref = self_trait_ref.clone();
319 for t in path.into_iter().skip(1) { 323 for t in path.into_iter().skip(1) {
320 let bounds = db.generic_predicates(current_trait_ref.trait_.into()); 324 let bounds = db.generic_predicates(current_trait_ref.trait_.into());
321 let super_trait_ref = bounds 325 let super_trait_ref = bounds
322 .iter() 326 .iter()
323 .find_map(|b| match &b.value { 327 .find_map(|b| match &b.value {
324 GenericPredicate::Implemented(tr) 328 GenericPredicate::Implemented(tr)
325 if tr.trait_ == t && tr.substs[0] == Ty::Bound(0) => 329 if tr.trait_ == t
330 && tr.substs[0]
331 == Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)) =>
326 { 332 {
327 Some(Binders { value: tr, num_binders: b.num_binders }) 333 Some(Binders { value: tr, num_binders: b.num_binders })
328 } 334 }
@@ -332,7 +338,18 @@ fn super_trait_object_unsize_impl_datum(
332 current_trait_ref = super_trait_ref.cloned().subst(&current_trait_ref.substs); 338 current_trait_ref = super_trait_ref.cloned().subst(&current_trait_ref.substs);
333 } 339 }
334 340
335 let super_bounds = vec![GenericPredicate::Implemented(current_trait_ref)]; 341 // We need to renumber the variables a bit now: from ^0.0, ^0.1, ^0.2, ...
342 // to ^0.0, ^1.0, ^1.1. The reason for this is that the first variable comes
343 // from the dyn Trait binder, while the other variables come from the impl.
344 let new_substs = Substs::builder(num_vars + 1)
345 .push(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)))
346 .fill_with_bound_vars(DebruijnIndex::ONE, 0)
347 .build();
348
349 let self_bounds =
350 vec![GenericPredicate::Implemented(self_trait_ref.subst_bound_vars(&new_substs))];
351 let super_bounds =
352 vec![GenericPredicate::Implemented(current_trait_ref.subst_bound_vars(&new_substs))];
336 353
337 let substs = Substs::builder(2) 354 let substs = Substs::builder(2)
338 .push(Ty::Dyn(self_bounds.into())) 355 .push(Ty::Dyn(self_bounds.into()))
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index ab4cb33b4..53ce362ea 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -3,7 +3,10 @@ use std::{fmt, sync::Arc};
3 3
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{cast::Cast, Goal, GoalData, Parameter, PlaceholderIndex, TypeName, UniverseIndex}; 6use chalk_ir::{
7 cast::Cast, fold::shift::Shift, Goal, GoalData, Parameter, PlaceholderIndex, TypeName,
8 UniverseIndex,
9};
7 10
8use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId}; 11use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId};
9use ra_db::{ 12use ra_db::{
@@ -235,7 +238,7 @@ impl ToChalk for Ty {
235 } 238 }
236 .to_ty::<Interner>(&Interner) 239 .to_ty::<Interner>(&Interner)
237 } 240 }
238 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(&Interner), 241 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner),
239 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 242 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
240 Ty::Dyn(predicates) => { 243 Ty::Dyn(predicates) => {
241 let where_clauses = predicates 244 let where_clauses = predicates
@@ -277,7 +280,7 @@ impl ToChalk for Ty {
277 Ty::Projection(ProjectionTy { associated_ty, parameters }) 280 Ty::Projection(ProjectionTy { associated_ty, parameters })
278 } 281 }
279 chalk_ir::TyData::Function(_) => unimplemented!(), 282 chalk_ir::TyData::Function(_) => unimplemented!(),
280 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx as u32), 283 chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx),
281 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown, 284 chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown,
282 chalk_ir::TyData::Dyn(where_clauses) => { 285 chalk_ir::TyData::Dyn(where_clauses) => {
283 assert_eq!(where_clauses.bounds.binders.len(), 1); 286 assert_eq!(where_clauses.bounds.binders.len(), 1);
@@ -407,15 +410,15 @@ impl ToChalk for GenericPredicate {
407 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::QuantifiedWhereClause<Interner> { 410 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::QuantifiedWhereClause<Interner> {
408 match self { 411 match self {
409 GenericPredicate::Implemented(trait_ref) => { 412 GenericPredicate::Implemented(trait_ref) => {
410 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) 413 let chalk_trait_ref = trait_ref.to_chalk(db);
414 let chalk_trait_ref = chalk_trait_ref.shifted_in(&Interner);
415 make_binders(chalk_ir::WhereClause::Implemented(chalk_trait_ref), 0)
416 }
417 GenericPredicate::Projection(projection_pred) => {
418 let ty = projection_pred.ty.to_chalk(db).shifted_in(&Interner);
419 let alias = projection_pred.projection_ty.to_chalk(db).shifted_in(&Interner);
420 make_binders(chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias, ty }), 0)
411 } 421 }
412 GenericPredicate::Projection(projection_pred) => make_binders(
413 chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq {
414 alias: projection_pred.projection_ty.to_chalk(db),
415 ty: projection_pred.ty.to_chalk(db),
416 }),
417 0,
418 ),
419 GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"), 422 GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"),
420 } 423 }
421 } 424 }
@@ -579,7 +582,8 @@ impl ToChalk for builtin::BuiltinImplAssocTyValueData {
579 type Chalk = AssociatedTyValue; 582 type Chalk = AssociatedTyValue;
580 583
581 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValue { 584 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValue {
582 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: self.value.to_chalk(db) }; 585 let ty = self.value.to_chalk(db);
586 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty };
583 587
584 chalk_rust_ir::AssociatedTyValue { 588 chalk_rust_ir::AssociatedTyValue {
585 associated_ty_id: self.assoc_ty_id.to_chalk(db), 589 associated_ty_id: self.assoc_ty_id.to_chalk(db),
@@ -738,11 +742,13 @@ pub(crate) fn trait_datum_query(
738 let associated_ty_ids = 742 let associated_ty_ids =
739 trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect(); 743 trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect();
740 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses }; 744 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses };
745 let well_known = None; // FIXME set this (depending on lang items)
741 let trait_datum = TraitDatum { 746 let trait_datum = TraitDatum {
742 id: trait_id, 747 id: trait_id,
743 binders: make_binders(trait_datum_bound, bound_vars.len()), 748 binders: make_binders(trait_datum_bound, bound_vars.len()),
744 flags, 749 flags,
745 associated_ty_ids, 750 associated_ty_ids,
751 well_known,
746 }; 752 };
747 Arc::new(trait_datum) 753 Arc::new(trait_datum)
748} 754}