diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 233 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/autoderef.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/unify.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 1 |
8 files changed, 132 insertions, 133 deletions
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 752653ad7..c3e589921 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -69,7 +69,9 @@ pub use self::{ | |||
69 | resolve::Resolution, | 69 | resolve::Resolution, |
70 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, | 70 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, |
71 | source_id::{AstIdMap, ErasedFileAstId}, | 71 | source_id::{AstIdMap, ErasedFileAstId}, |
72 | ty::{display::HirDisplay, ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor}, | 72 | ty::{ |
73 | display::HirDisplay, ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor, TypeWalk, | ||
74 | }, | ||
73 | type_ref::Mutability, | 75 | type_ref::Mutability, |
74 | }; | 76 | }; |
75 | 77 | ||
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index c0c609d78..a3df08827 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -130,12 +130,14 @@ impl ProjectionTy { | |||
130 | substs: self.parameters.clone(), | 130 | substs: self.parameters.clone(), |
131 | } | 131 | } |
132 | } | 132 | } |
133 | } | ||
133 | 134 | ||
134 | pub fn walk(&self, f: &mut impl FnMut(&Ty)) { | 135 | impl TypeWalk for ProjectionTy { |
136 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
135 | self.parameters.walk(f); | 137 | self.parameters.walk(f); |
136 | } | 138 | } |
137 | 139 | ||
138 | pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { | 140 | fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { |
139 | self.parameters.walk_mut(f); | 141 | self.parameters.walk_mut(f); |
140 | } | 142 | } |
141 | } | 143 | } |
@@ -146,12 +148,12 @@ pub struct UnselectedProjectionTy { | |||
146 | pub parameters: Substs, | 148 | pub parameters: Substs, |
147 | } | 149 | } |
148 | 150 | ||
149 | impl UnselectedProjectionTy { | 151 | impl TypeWalk for UnselectedProjectionTy { |
150 | pub fn walk(&self, f: &mut impl FnMut(&Ty)) { | 152 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
151 | self.parameters.walk(f); | 153 | self.parameters.walk(f); |
152 | } | 154 | } |
153 | 155 | ||
154 | pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { | 156 | fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { |
155 | self.parameters.walk_mut(f); | 157 | self.parameters.walk_mut(f); |
156 | } | 158 | } |
157 | } | 159 | } |
@@ -312,20 +314,14 @@ impl TraitRef { | |||
312 | pub fn self_ty(&self) -> &Ty { | 314 | pub fn self_ty(&self) -> &Ty { |
313 | &self.substs[0] | 315 | &self.substs[0] |
314 | } | 316 | } |
317 | } | ||
315 | 318 | ||
316 | pub fn subst(mut self, substs: &Substs) -> TraitRef { | 319 | impl TypeWalk for TraitRef { |
317 | self.substs.walk_mut(&mut |ty_mut| { | 320 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
318 | let ty = mem::replace(ty_mut, Ty::Unknown); | ||
319 | *ty_mut = ty.subst(substs); | ||
320 | }); | ||
321 | self | ||
322 | } | ||
323 | |||
324 | pub fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
325 | self.substs.walk(f); | 321 | self.substs.walk(f); |
326 | } | 322 | } |
327 | 323 | ||
328 | pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { | 324 | fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { |
329 | self.substs.walk_mut(f); | 325 | self.substs.walk_mut(f); |
330 | } | 326 | } |
331 | } | 327 | } |
@@ -365,20 +361,10 @@ impl GenericPredicate { | |||
365 | GenericPredicate::Error => None, | 361 | GenericPredicate::Error => None, |
366 | } | 362 | } |
367 | } | 363 | } |
364 | } | ||
368 | 365 | ||
369 | pub fn subst(self, substs: &Substs) -> GenericPredicate { | 366 | impl TypeWalk for GenericPredicate { |
370 | match self { | 367 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
371 | GenericPredicate::Implemented(trait_ref) => { | ||
372 | GenericPredicate::Implemented(trait_ref.subst(substs)) | ||
373 | } | ||
374 | GenericPredicate::Projection(projection_predicate) => { | ||
375 | GenericPredicate::Projection(projection_predicate.subst(substs)) | ||
376 | } | ||
377 | GenericPredicate::Error => self, | ||
378 | } | ||
379 | } | ||
380 | |||
381 | pub fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
382 | match self { | 368 | match self { |
383 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f), | 369 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f), |
384 | GenericPredicate::Projection(projection_pred) => projection_pred.walk(f), | 370 | GenericPredicate::Projection(projection_pred) => projection_pred.walk(f), |
@@ -386,7 +372,7 @@ impl GenericPredicate { | |||
386 | } | 372 | } |
387 | } | 373 | } |
388 | 374 | ||
389 | pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { | 375 | fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { |
390 | match self { | 376 | match self { |
391 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut(f), | 377 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut(f), |
392 | GenericPredicate::Projection(projection_pred) => projection_pred.walk_mut(f), | 378 | GenericPredicate::Projection(projection_pred) => projection_pred.walk_mut(f), |
@@ -430,16 +416,16 @@ impl FnSig { | |||
430 | pub fn ret(&self) -> &Ty { | 416 | pub fn ret(&self) -> &Ty { |
431 | &self.params_and_return[self.params_and_return.len() - 1] | 417 | &self.params_and_return[self.params_and_return.len() - 1] |
432 | } | 418 | } |
419 | } | ||
433 | 420 | ||
434 | /// Applies the given substitutions to all types in this signature and | 421 | impl TypeWalk for FnSig { |
435 | /// returns the result. | 422 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
436 | pub fn subst(&self, substs: &Substs) -> FnSig { | 423 | for t in self.params_and_return.iter() { |
437 | let result: Vec<_> = | 424 | t.walk(f); |
438 | self.params_and_return.iter().map(|ty| ty.clone().subst(substs)).collect(); | 425 | } |
439 | FnSig { params_and_return: result.into() } | ||
440 | } | 426 | } |
441 | 427 | ||
442 | pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { | 428 | fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { |
443 | // Without an Arc::make_mut_slice, we can't avoid the clone here: | 429 | // Without an Arc::make_mut_slice, we can't avoid the clone here: |
444 | let mut v: Vec<_> = self.params_and_return.iter().cloned().collect(); | 430 | let mut v: Vec<_> = self.params_and_return.iter().cloned().collect(); |
445 | for t in &mut v { | 431 | for t in &mut v { |
@@ -463,64 +449,6 @@ impl Ty { | |||
463 | Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) | 449 | Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) |
464 | } | 450 | } |
465 | 451 | ||
466 | pub fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
467 | match self { | ||
468 | Ty::Apply(a_ty) => { | ||
469 | for t in a_ty.parameters.iter() { | ||
470 | t.walk(f); | ||
471 | } | ||
472 | } | ||
473 | Ty::Projection(p_ty) => { | ||
474 | for t in p_ty.parameters.iter() { | ||
475 | t.walk(f); | ||
476 | } | ||
477 | } | ||
478 | Ty::UnselectedProjection(p_ty) => { | ||
479 | for t in p_ty.parameters.iter() { | ||
480 | t.walk(f); | ||
481 | } | ||
482 | } | ||
483 | Ty::Dyn(predicates) | Ty::Opaque(predicates) => { | ||
484 | for p in predicates.iter() { | ||
485 | p.walk(f); | ||
486 | } | ||
487 | } | ||
488 | Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | ||
489 | } | ||
490 | f(self); | ||
491 | } | ||
492 | |||
493 | fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { | ||
494 | match self { | ||
495 | Ty::Apply(a_ty) => { | ||
496 | a_ty.parameters.walk_mut(f); | ||
497 | } | ||
498 | Ty::Projection(p_ty) => { | ||
499 | p_ty.parameters.walk_mut(f); | ||
500 | } | ||
501 | Ty::UnselectedProjection(p_ty) => { | ||
502 | p_ty.parameters.walk_mut(f); | ||
503 | } | ||
504 | Ty::Dyn(predicates) | Ty::Opaque(predicates) => { | ||
505 | let mut v: Vec<_> = predicates.iter().cloned().collect(); | ||
506 | for p in &mut v { | ||
507 | p.walk_mut(f); | ||
508 | } | ||
509 | *predicates = v.into(); | ||
510 | } | ||
511 | Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | ||
512 | } | ||
513 | f(self); | ||
514 | } | ||
515 | |||
516 | fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Ty { | ||
517 | self.walk_mut(&mut |ty_mut| { | ||
518 | let ty = mem::replace(ty_mut, Ty::Unknown); | ||
519 | *ty_mut = f(ty); | ||
520 | }); | ||
521 | self | ||
522 | } | ||
523 | |||
524 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { | 452 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { |
525 | match self { | 453 | match self { |
526 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | 454 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { |
@@ -596,10 +524,53 @@ impl Ty { | |||
596 | } | 524 | } |
597 | } | 525 | } |
598 | 526 | ||
527 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | ||
528 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | ||
529 | pub fn substs(&self) -> Option<Substs> { | ||
530 | match self { | ||
531 | Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), | ||
532 | _ => None, | ||
533 | } | ||
534 | } | ||
535 | |||
536 | /// If this is an `impl Trait` or `dyn Trait`, returns that trait. | ||
537 | pub fn inherent_trait(&self) -> Option<Trait> { | ||
538 | match self { | ||
539 | Ty::Dyn(predicates) | Ty::Opaque(predicates) => { | ||
540 | predicates.iter().find_map(|pred| match pred { | ||
541 | GenericPredicate::Implemented(tr) => Some(tr.trait_), | ||
542 | _ => None, | ||
543 | }) | ||
544 | } | ||
545 | _ => None, | ||
546 | } | ||
547 | } | ||
548 | } | ||
549 | |||
550 | /// This allows walking structures that contain types to do something with those | ||
551 | /// types, similar to Chalk's `Fold` trait. | ||
552 | pub trait TypeWalk { | ||
553 | fn walk(&self, f: &mut impl FnMut(&Ty)); | ||
554 | fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)); | ||
555 | |||
556 | fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Self | ||
557 | where | ||
558 | Self: Sized, | ||
559 | { | ||
560 | self.walk_mut(&mut |ty_mut| { | ||
561 | let ty = mem::replace(ty_mut, Ty::Unknown); | ||
562 | *ty_mut = f(ty); | ||
563 | }); | ||
564 | self | ||
565 | } | ||
566 | |||
599 | /// Replaces type parameters in this type using the given `Substs`. (So e.g. | 567 | /// Replaces type parameters in this type using the given `Substs`. (So e.g. |
600 | /// if `self` is `&[T]`, where type parameter T has index 0, and the | 568 | /// if `self` is `&[T]`, where type parameter T has index 0, and the |
601 | /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.) | 569 | /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.) |
602 | pub fn subst(self, substs: &Substs) -> Ty { | 570 | fn subst(self, substs: &Substs) -> Self |
571 | where | ||
572 | Self: Sized, | ||
573 | { | ||
603 | self.fold(&mut |ty| match ty { | 574 | self.fold(&mut |ty| match ty { |
604 | Ty::Param { idx, name } => { | 575 | Ty::Param { idx, name } => { |
605 | substs.get(idx as usize).cloned().unwrap_or(Ty::Param { idx, name }) | 576 | substs.get(idx as usize).cloned().unwrap_or(Ty::Param { idx, name }) |
@@ -609,24 +580,21 @@ impl Ty { | |||
609 | } | 580 | } |
610 | 581 | ||
611 | /// Substitutes `Ty::Bound` vars (as opposed to type parameters). | 582 | /// Substitutes `Ty::Bound` vars (as opposed to type parameters). |
612 | pub fn subst_bound_vars(self, substs: &Substs) -> Ty { | 583 | fn subst_bound_vars(self, substs: &Substs) -> Self |
584 | where | ||
585 | Self: Sized, | ||
586 | { | ||
613 | self.fold(&mut |ty| match ty { | 587 | self.fold(&mut |ty| match ty { |
614 | Ty::Bound(idx) => substs.get(idx as usize).cloned().unwrap_or_else(|| Ty::Bound(idx)), | 588 | Ty::Bound(idx) => substs.get(idx as usize).cloned().unwrap_or_else(|| Ty::Bound(idx)), |
615 | ty => ty, | 589 | ty => ty, |
616 | }) | 590 | }) |
617 | } | 591 | } |
618 | 592 | ||
619 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | ||
620 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | ||
621 | pub fn substs(&self) -> Option<Substs> { | ||
622 | match self { | ||
623 | Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), | ||
624 | _ => None, | ||
625 | } | ||
626 | } | ||
627 | |||
628 | /// Shifts up `Ty::Bound` vars by `n`. | 593 | /// Shifts up `Ty::Bound` vars by `n`. |
629 | pub fn shift_bound_vars(self, n: i32) -> Ty { | 594 | fn shift_bound_vars(self, n: i32) -> Self |
595 | where | ||
596 | Self: Sized, | ||
597 | { | ||
630 | self.fold(&mut |ty| match ty { | 598 | self.fold(&mut |ty| match ty { |
631 | Ty::Bound(idx) => { | 599 | Ty::Bound(idx) => { |
632 | assert!(idx as i32 >= -n); | 600 | assert!(idx as i32 >= -n); |
@@ -635,18 +603,57 @@ impl Ty { | |||
635 | ty => ty, | 603 | ty => ty, |
636 | }) | 604 | }) |
637 | } | 605 | } |
606 | } | ||
638 | 607 | ||
639 | /// If this is an `impl Trait` or `dyn Trait`, returns that trait. | 608 | impl TypeWalk for Ty { |
640 | pub fn inherent_trait(&self) -> Option<Trait> { | 609 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
641 | match self { | 610 | match self { |
611 | Ty::Apply(a_ty) => { | ||
612 | for t in a_ty.parameters.iter() { | ||
613 | t.walk(f); | ||
614 | } | ||
615 | } | ||
616 | Ty::Projection(p_ty) => { | ||
617 | for t in p_ty.parameters.iter() { | ||
618 | t.walk(f); | ||
619 | } | ||
620 | } | ||
621 | Ty::UnselectedProjection(p_ty) => { | ||
622 | for t in p_ty.parameters.iter() { | ||
623 | t.walk(f); | ||
624 | } | ||
625 | } | ||
642 | Ty::Dyn(predicates) | Ty::Opaque(predicates) => { | 626 | Ty::Dyn(predicates) | Ty::Opaque(predicates) => { |
643 | predicates.iter().find_map(|pred| match pred { | 627 | for p in predicates.iter() { |
644 | GenericPredicate::Implemented(tr) => Some(tr.trait_), | 628 | p.walk(f); |
645 | _ => None, | 629 | } |
646 | }) | ||
647 | } | 630 | } |
648 | _ => None, | 631 | Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} |
632 | } | ||
633 | f(self); | ||
634 | } | ||
635 | |||
636 | fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { | ||
637 | match self { | ||
638 | Ty::Apply(a_ty) => { | ||
639 | a_ty.parameters.walk_mut(f); | ||
640 | } | ||
641 | Ty::Projection(p_ty) => { | ||
642 | p_ty.parameters.walk_mut(f); | ||
643 | } | ||
644 | Ty::UnselectedProjection(p_ty) => { | ||
645 | p_ty.parameters.walk_mut(f); | ||
646 | } | ||
647 | Ty::Dyn(predicates) | Ty::Opaque(predicates) => { | ||
648 | let mut v: Vec<_> = predicates.iter().cloned().collect(); | ||
649 | for p in &mut v { | ||
650 | p.walk_mut(f); | ||
651 | } | ||
652 | *predicates = v.into(); | ||
653 | } | ||
654 | Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} | ||
649 | } | 655 | } |
656 | f(self); | ||
650 | } | 657 | } |
651 | } | 658 | } |
652 | 659 | ||
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index 2535d4ae7..08f52a53b 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs | |||
@@ -7,7 +7,7 @@ use std::iter::successors; | |||
7 | 7 | ||
8 | use log::{info, warn}; | 8 | use log::{info, warn}; |
9 | 9 | ||
10 | use super::{traits::Solution, Canonical, Ty}; | 10 | use super::{traits::Solution, Canonical, Ty, TypeWalk}; |
11 | use crate::{HasGenericParams, HirDatabase, Name, Resolver}; | 11 | use crate::{HasGenericParams, HirDatabase, Name, Resolver}; |
12 | 12 | ||
13 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 13 | const AUTODEREF_RECURSION_LIMIT: usize = 10; |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index b89a40b4b..ec3b7ffef 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -30,7 +30,7 @@ use super::{ | |||
30 | autoderef, lower, method_resolution, op, primitive, | 30 | autoderef, lower, method_resolution, op, primitive, |
31 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, | 31 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, |
32 | ApplicationTy, CallableDef, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, | 32 | ApplicationTy, CallableDef, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, |
33 | Ty, TypableDef, TypeCtor, | 33 | Ty, TypableDef, TypeCtor, TypeWalk, |
34 | }; | 34 | }; |
35 | use crate::{ | 35 | use crate::{ |
36 | adt::VariantDef, | 36 | adt::VariantDef, |
diff --git a/crates/ra_hir/src/ty/infer/unify.rs b/crates/ra_hir/src/ty/infer/unify.rs index e7e8825d1..9a0d2d8f9 100644 --- a/crates/ra_hir/src/ty/infer/unify.rs +++ b/crates/ra_hir/src/ty/infer/unify.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use super::{InferenceContext, Obligation}; | 3 | use super::{InferenceContext, Obligation}; |
4 | use crate::db::HirDatabase; | 4 | use crate::db::HirDatabase; |
5 | use crate::ty::{ | 5 | use crate::ty::{ |
6 | Canonical, InEnvironment, InferTy, ProjectionPredicate, ProjectionTy, TraitRef, Ty, | 6 | Canonical, InEnvironment, InferTy, ProjectionPredicate, ProjectionTy, TraitRef, Ty, TypeWalk, |
7 | }; | 7 | }; |
8 | 8 | ||
9 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 9 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 0011c06b4..f6f0137cf 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -10,6 +10,7 @@ use std::sync::Arc; | |||
10 | 10 | ||
11 | use super::{ | 11 | use super::{ |
12 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | 12 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, |
13 | TypeWalk, | ||
13 | }; | 14 | }; |
14 | use crate::{ | 15 | use crate::{ |
15 | adt::VariantDef, | 16 | adt::VariantDef, |
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 25316bc02..6e0271a96 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -8,7 +8,7 @@ use ra_db::salsa; | |||
8 | use ra_prof::profile; | 8 | use ra_prof::profile; |
9 | use rustc_hash::FxHashSet; | 9 | use rustc_hash::FxHashSet; |
10 | 10 | ||
11 | use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty}; | 11 | use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; |
12 | use crate::{db::HirDatabase, Crate, ImplBlock, Trait}; | 12 | use crate::{db::HirDatabase, Crate, ImplBlock, Trait}; |
13 | 13 | ||
14 | use self::chalk::{from_chalk, ToChalk}; | 14 | use self::chalk::{from_chalk, ToChalk}; |
@@ -138,25 +138,13 @@ pub struct ProjectionPredicate { | |||
138 | pub ty: Ty, | 138 | pub ty: Ty, |
139 | } | 139 | } |
140 | 140 | ||
141 | impl ProjectionPredicate { | 141 | impl TypeWalk for ProjectionPredicate { |
142 | pub fn subst(mut self, substs: &super::Substs) -> ProjectionPredicate { | 142 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
143 | self.walk_mut(&mut |ty| match ty { | ||
144 | Ty::Param { idx, .. } => { | ||
145 | if let Some(t) = substs.get(*idx as usize).cloned() { | ||
146 | *ty = t; | ||
147 | } | ||
148 | } | ||
149 | _ => {} | ||
150 | }); | ||
151 | self | ||
152 | } | ||
153 | |||
154 | pub fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
155 | self.projection_ty.walk(f); | 143 | self.projection_ty.walk(f); |
156 | self.ty.walk(f); | 144 | self.ty.walk(f); |
157 | } | 145 | } |
158 | 146 | ||
159 | pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { | 147 | fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { |
160 | self.projection_ty.walk_mut(f); | 148 | self.projection_ty.walk_mut(f); |
161 | self.ty.walk_mut(f); | 149 | self.ty.walk_mut(f); |
162 | } | 150 | } |
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 3ab5b7cca..c201c5e50 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -19,6 +19,7 @@ use crate::{ | |||
19 | ty::display::HirDisplay, | 19 | ty::display::HirDisplay, |
20 | ty::{ | 20 | ty::{ |
21 | ApplicationTy, CallableDef, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | 21 | ApplicationTy, CallableDef, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, |
22 | TypeWalk, | ||
22 | }, | 23 | }, |
23 | Crate, HasGenericParams, ImplBlock, ImplItem, Trait, TypeAlias, | 24 | Crate, HasGenericParams, ImplBlock, ImplItem, Trait, TypeAlias, |
24 | }; | 25 | }; |