aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/traits/builtin.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/traits/builtin.rs')
-rw-r--r--crates/ra_hir_ty/src/traits/builtin.rs53
1 files changed, 35 insertions, 18 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()))