aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs133
1 files changed, 123 insertions, 10 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 642dd02cb..b54c80318 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -161,14 +161,28 @@ pub enum Ty {
161 name: Name, 161 name: Name,
162 }, 162 },
163 163
164 /// A bound type variable. Only used during trait resolution to represent 164 /// A bound type variable. Used during trait resolution to represent Chalk
165 /// Chalk variables. 165 /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type.
166 Bound(u32), 166 Bound(u32),
167 167
168 /// A type variable used during type checking. Not to be confused with a 168 /// A type variable used during type checking. Not to be confused with a
169 /// type parameter. 169 /// type parameter.
170 Infer(InferTy), 170 Infer(InferTy),
171 171
172 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust).
173 ///
174 /// The predicates are quantified over the `Self` type, i.e. `Ty::Bound(0)`
175 /// represents the `Self` type inside the bounds. This is currently
176 /// implicit; Chalk has the `Binders` struct to make it explicit, but it
177 /// didn't seem worth the overhead yet.
178 Dyn(Arc<[GenericPredicate]>),
179
180 /// An opaque type (`impl Trait`).
181 ///
182 /// The predicates are quantified over the `Self` type; see `Ty::Dyn` for
183 /// more.
184 Opaque(Arc<[GenericPredicate]>),
185
172 /// A placeholder for a type which could not be computed; this is propagated 186 /// A placeholder for a type which could not be computed; this is propagated
173 /// to avoid useless error messages. Doubles as a placeholder where type 187 /// to avoid useless error messages. Doubles as a placeholder where type
174 /// variables are inserted before type checking, since we want to try to 188 /// variables are inserted before type checking, since we want to try to
@@ -194,6 +208,12 @@ impl Substs {
194 Substs(self.0.iter().cloned().take(n).collect::<Vec<_>>().into()) 208 Substs(self.0.iter().cloned().take(n).collect::<Vec<_>>().into())
195 } 209 }
196 210
211 pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
212 for t in self.0.iter() {
213 t.walk(f);
214 }
215 }
216
197 pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { 217 pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
198 // Without an Arc::make_mut_slice, we can't avoid the clone here: 218 // Without an Arc::make_mut_slice, we can't avoid the clone here:
199 let mut v: Vec<_> = self.0.iter().cloned().collect(); 219 let mut v: Vec<_> = self.0.iter().cloned().collect();
@@ -270,6 +290,14 @@ impl TraitRef {
270 }); 290 });
271 self 291 self
272 } 292 }
293
294 pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
295 self.substs.walk(f);
296 }
297
298 pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
299 self.substs.walk_mut(f);
300 }
273} 301}
274 302
275/// Like `generics::WherePredicate`, but with resolved types: A condition on the 303/// Like `generics::WherePredicate`, but with resolved types: A condition on the
@@ -299,6 +327,20 @@ impl GenericPredicate {
299 GenericPredicate::Error => self, 327 GenericPredicate::Error => self,
300 } 328 }
301 } 329 }
330
331 pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
332 match self {
333 GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f),
334 GenericPredicate::Error => {}
335 }
336 }
337
338 pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
339 match self {
340 GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut(f),
341 GenericPredicate::Error => {}
342 }
343 }
302} 344}
303 345
304/// Basically a claim (currently not validated / checked) that the contained 346/// Basically a claim (currently not validated / checked) that the contained
@@ -386,6 +428,11 @@ impl Ty {
386 t.walk(f); 428 t.walk(f);
387 } 429 }
388 } 430 }
431 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
432 for p in predicates.iter() {
433 p.walk(f);
434 }
435 }
389 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 436 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
390 } 437 }
391 f(self); 438 f(self);
@@ -402,6 +449,13 @@ impl Ty {
402 Ty::UnselectedProjection(p_ty) => { 449 Ty::UnselectedProjection(p_ty) => {
403 p_ty.parameters.walk_mut(f); 450 p_ty.parameters.walk_mut(f);
404 } 451 }
452 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
453 let mut v: Vec<_> = predicates.iter().cloned().collect();
454 for p in &mut v {
455 p.walk_mut(f);
456 }
457 *predicates = v.into();
458 }
405 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 459 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
406 } 460 }
407 f(self); 461 f(self);
@@ -529,6 +583,19 @@ impl Ty {
529 ty => ty, 583 ty => ty,
530 }) 584 })
531 } 585 }
586
587 /// If this is an `impl Trait` or `dyn Trait`, returns that trait.
588 pub fn inherent_trait(&self) -> Option<Trait> {
589 match self {
590 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
591 predicates.iter().find_map(|pred| match pred {
592 GenericPredicate::Implemented(tr) => Some(tr.trait_),
593 _ => None,
594 })
595 }
596 _ => None,
597 }
598 }
532} 599}
533 600
534impl HirDisplay for &Ty { 601impl HirDisplay for &Ty {
@@ -669,6 +736,28 @@ impl HirDisplay for Ty {
669 Ty::UnselectedProjection(p_ty) => p_ty.hir_fmt(f)?, 736 Ty::UnselectedProjection(p_ty) => p_ty.hir_fmt(f)?,
670 Ty::Param { name, .. } => write!(f, "{}", name)?, 737 Ty::Param { name, .. } => write!(f, "{}", name)?,
671 Ty::Bound(idx) => write!(f, "?{}", idx)?, 738 Ty::Bound(idx) => write!(f, "?{}", idx)?,
739 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
740 match self {
741 Ty::Dyn(_) => write!(f, "dyn ")?,
742 Ty::Opaque(_) => write!(f, "impl ")?,
743 _ => unreachable!(),
744 };
745 // looping by hand here just to format the bounds in a slightly nicer way
746 let mut first = true;
747 for p in predicates.iter() {
748 if !first {
749 write!(f, " + ")?;
750 }
751 first = false;
752 match p {
753 // don't show the $0 self type
754 GenericPredicate::Implemented(trait_ref) => {
755 trait_ref.hir_fmt_ext(f, false)?
756 }
757 GenericPredicate::Error => p.hir_fmt(f)?,
758 }
759 }
760 }
672 Ty::Unknown => write!(f, "{{unknown}}")?, 761 Ty::Unknown => write!(f, "{{unknown}}")?,
673 Ty::Infer(..) => write!(f, "_")?, 762 Ty::Infer(..) => write!(f, "_")?,
674 } 763 }
@@ -676,14 +765,16 @@ impl HirDisplay for Ty {
676 } 765 }
677} 766}
678 767
679impl HirDisplay for TraitRef { 768impl TraitRef {
680 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { 769 fn hir_fmt_ext(
681 write!( 770 &self,
682 f, 771 f: &mut HirFormatter<impl HirDatabase>,
683 "{}: {}", 772 with_self_ty: bool,
684 self.substs[0].display(f.db), 773 ) -> fmt::Result {
685 self.trait_.name(f.db).unwrap_or_else(Name::missing) 774 if with_self_ty {
686 )?; 775 write!(f, "{}: ", self.substs[0].display(f.db),)?;
776 }
777 write!(f, "{}", self.trait_.name(f.db).unwrap_or_else(Name::missing))?;
687 if self.substs.len() > 1 { 778 if self.substs.len() > 1 {
688 write!(f, "<")?; 779 write!(f, "<")?;
689 f.write_joined(&self.substs[1..], ", ")?; 780 f.write_joined(&self.substs[1..], ", ")?;
@@ -693,6 +784,28 @@ impl HirDisplay for TraitRef {
693 } 784 }
694} 785}
695 786
787impl HirDisplay for TraitRef {
788 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
789 self.hir_fmt_ext(f, true)
790 }
791}
792
793impl HirDisplay for &GenericPredicate {
794 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
795 HirDisplay::hir_fmt(*self, f)
796 }
797}
798
799impl HirDisplay for GenericPredicate {
800 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
801 match self {
802 GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?,
803 GenericPredicate::Error => write!(f, "{{error}}")?,
804 }
805 Ok(())
806 }
807}
808
696impl HirDisplay for Obligation { 809impl HirDisplay for Obligation {
697 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { 810 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
698 match self { 811 match self {