diff options
Diffstat (limited to 'crates/ra_hir_ty/src/traits/builtin.rs')
-rw-r--r-- | crates/ra_hir_ty/src/traits/builtin.rs | 53 |
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}; | |||
8 | use crate::{ | 8 | use 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 | ||
14 | pub(super) struct BuiltinImplData { | 15 | pub(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(¤t_trait_ref.substs); | 338 | current_trait_ref = super_trait_ref.cloned().subst(¤t_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())) |