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.rs100
1 files changed, 100 insertions, 0 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 82589e504..642dd02cb 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -94,6 +94,12 @@ pub enum TypeCtor {
94 94
95 /// A tuple type. For example, `(i32, bool)`. 95 /// A tuple type. For example, `(i32, bool)`.
96 Tuple { cardinality: u16 }, 96 Tuple { cardinality: u16 },
97
98 /// Represents an associated item like `Iterator::Item`. This is used
99 /// when we have tried to normalize a projection like `T::Item` but
100 /// couldn't find a better representation. In that case, we generate
101 /// an **application type** like `(Iterator::Item)<T>`.
102 AssociatedType(TypeAlias),
97} 103}
98 104
99/// A nominal type with (maybe 0) type parameters. This might be a primitive 105/// A nominal type with (maybe 0) type parameters. This might be a primitive
@@ -114,6 +120,12 @@ pub struct ProjectionTy {
114 pub parameters: Substs, 120 pub parameters: Substs,
115} 121}
116 122
123#[derive(Clone, PartialEq, Eq, Debug, Hash)]
124pub struct UnselectedProjectionTy {
125 pub type_name: Name,
126 pub parameters: Substs,
127}
128
117/// A type. 129/// A type.
118/// 130///
119/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents 131/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
@@ -127,6 +139,18 @@ pub enum Ty {
127 /// several other things. 139 /// several other things.
128 Apply(ApplicationTy), 140 Apply(ApplicationTy),
129 141
142 /// A "projection" type corresponds to an (unnormalized)
143 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
144 /// trait and all its parameters are fully known.
145 Projection(ProjectionTy),
146
147 /// This is a variant of a projection in which the trait is
148 /// **not** known. It corresponds to a case where people write
149 /// `T::Item` without specifying the trait. We would then try to
150 /// figure out the trait by looking at all the traits that are in
151 /// scope.
152 UnselectedProjection(UnselectedProjectionTy),
153
130 /// A type parameter; for example, `T` in `fn f<T>(x: T) {} 154 /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
131 Param { 155 Param {
132 /// The index of the parameter (starting with parameters from the 156 /// The index of the parameter (starting with parameters from the
@@ -352,6 +376,16 @@ impl Ty {
352 t.walk(f); 376 t.walk(f);
353 } 377 }
354 } 378 }
379 Ty::Projection(p_ty) => {
380 for t in p_ty.parameters.iter() {
381 t.walk(f);
382 }
383 }
384 Ty::UnselectedProjection(p_ty) => {
385 for t in p_ty.parameters.iter() {
386 t.walk(f);
387 }
388 }
355 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 389 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
356 } 390 }
357 f(self); 391 f(self);
@@ -362,6 +396,12 @@ impl Ty {
362 Ty::Apply(a_ty) => { 396 Ty::Apply(a_ty) => {
363 a_ty.parameters.walk_mut(f); 397 a_ty.parameters.walk_mut(f);
364 } 398 }
399 Ty::Projection(p_ty) => {
400 p_ty.parameters.walk_mut(f);
401 }
402 Ty::UnselectedProjection(p_ty) => {
403 p_ty.parameters.walk_mut(f);
404 }
365 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 405 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
366 } 406 }
367 f(self); 407 f(self);
@@ -572,15 +612,61 @@ impl HirDisplay for ApplicationTy {
572 write!(f, ">")?; 612 write!(f, ">")?;
573 } 613 }
574 } 614 }
615 TypeCtor::AssociatedType(type_alias) => {
616 let trait_name = type_alias
617 .parent_trait(f.db)
618 .and_then(|t| t.name(f.db))
619 .unwrap_or_else(Name::missing);
620 let name = type_alias.name(f.db);
621 write!(f, "{}::{}", trait_name, name)?;
622 if self.parameters.len() > 0 {
623 write!(f, "<")?;
624 f.write_joined(&*self.parameters.0, ", ")?;
625 write!(f, ">")?;
626 }
627 }
575 } 628 }
576 Ok(()) 629 Ok(())
577 } 630 }
578} 631}
579 632
633impl HirDisplay for ProjectionTy {
634 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
635 let trait_name = self
636 .associated_ty
637 .parent_trait(f.db)
638 .and_then(|t| t.name(f.db))
639 .unwrap_or_else(Name::missing);
640 write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?;
641 if self.parameters.len() > 1 {
642 write!(f, "<")?;
643 f.write_joined(&self.parameters[1..], ", ")?;
644 write!(f, ">")?;
645 }
646 write!(f, ">::{}", self.associated_ty.name(f.db))?;
647 Ok(())
648 }
649}
650
651impl HirDisplay for UnselectedProjectionTy {
652 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
653 write!(f, "{}", self.parameters[0].display(f.db))?;
654 if self.parameters.len() > 1 {
655 write!(f, "<")?;
656 f.write_joined(&self.parameters[1..], ", ")?;
657 write!(f, ">")?;
658 }
659 write!(f, "::{}", self.type_name)?;
660 Ok(())
661 }
662}
663
580impl HirDisplay for Ty { 664impl HirDisplay for Ty {
581 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { 665 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
582 match self { 666 match self {
583 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, 667 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
668 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
669 Ty::UnselectedProjection(p_ty) => p_ty.hir_fmt(f)?,
584 Ty::Param { name, .. } => write!(f, "{}", name)?, 670 Ty::Param { name, .. } => write!(f, "{}", name)?,
585 Ty::Bound(idx) => write!(f, "?{}", idx)?, 671 Ty::Bound(idx) => write!(f, "?{}", idx)?,
586 Ty::Unknown => write!(f, "{{unknown}}")?, 672 Ty::Unknown => write!(f, "{{unknown}}")?,
@@ -606,3 +692,17 @@ impl HirDisplay for TraitRef {
606 Ok(()) 692 Ok(())
607 } 693 }
608} 694}
695
696impl HirDisplay for Obligation {
697 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
698 match self {
699 Obligation::Trait(tr) => write!(f, "Implements({})", tr.display(f.db)),
700 Obligation::Projection(proj) => write!(
701 f,
702 "Normalize({} => {})",
703 proj.projection_ty.display(f.db),
704 proj.ty.display(f.db)
705 ),
706 }
707 }
708}