aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/lib.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-01-25 22:38:33 +0000
committerFlorian Diebold <[email protected]>2020-02-07 17:28:10 +0000
commit16c69374471a0072541c21a5551b4fd97f7e12ba (patch)
tree72564c6b99eb6f1aaf44f740d654b1725daed0c2 /crates/ra_hir_ty/src/lib.rs
parent93aa166748eef9560df2435391dc3f3b53f8262d (diff)
Lower impl trait to variables, move away from using placeholders where they don't belong
Diffstat (limited to 'crates/ra_hir_ty/src/lib.rs')
-rw-r--r--crates/ra_hir_ty/src/lib.rs34
1 files changed, 32 insertions, 2 deletions
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index cb7a60352..79084bb3e 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -453,6 +453,30 @@ impl Deref for Substs {
453 } 453 }
454} 454}
455 455
456#[derive(Copy, Clone, PartialEq, Eq, Debug)]
457pub struct Binders<T> {
458 pub num_binders: usize,
459 pub value: T,
460}
461
462impl<T> Binders<T> {
463 pub fn new(num_binders: usize, value: T) -> Self { Self { num_binders, value } }
464}
465
466impl<T: TypeWalk> Binders<T> {
467 /// Substitutes all variables.
468 pub fn subst(self, subst: &Substs) -> T {
469 assert_eq!(subst.len(), self.num_binders);
470 self.value.subst_bound_vars(subst)
471 }
472
473 /// Substitutes just a prefix of the variables (shifting the rest).
474 pub fn subst_prefix(self, subst: &Substs) -> Binders<T> {
475 assert!(subst.len() < self.num_binders);
476 Binders::new(self.num_binders - subst.len(), self.value.subst_bound_vars(subst))
477 }
478}
479
456/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. 480/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
457/// Name to be bikeshedded: TraitBound? TraitImplements? 481/// Name to be bikeshedded: TraitBound? TraitImplements?
458#[derive(Clone, PartialEq, Eq, Debug, Hash)] 482#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -553,6 +577,9 @@ pub struct FnSig {
553 params_and_return: Arc<[Ty]>, 577 params_and_return: Arc<[Ty]>,
554} 578}
555 579
580/// A polymorphic function signature.
581pub type PolyFnSig = Binders<FnSig>;
582
556impl FnSig { 583impl FnSig {
557 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig { 584 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig {
558 params.push(ret); 585 params.push(ret);
@@ -757,6 +784,9 @@ pub trait TypeWalk {
757 &mut Ty::Bound(idx) => { 784 &mut Ty::Bound(idx) => {
758 if idx as usize >= binders && (idx as usize - binders) < substs.len() { 785 if idx as usize >= binders && (idx as usize - binders) < substs.len() {
759 *ty = substs.0[idx as usize - binders].clone(); 786 *ty = substs.0[idx as usize - binders].clone();
787 } else if idx as usize >= binders + substs.len() {
788 // shift free binders
789 *ty = Ty::Bound(idx - substs.len() as u32);
760 } 790 }
761 } 791 }
762 _ => {} 792 _ => {}
@@ -903,8 +933,8 @@ impl HirDisplay for ApplicationTy {
903 write!(f, ">")?; 933 write!(f, ">")?;
904 } 934 }
905 write!(f, "(")?; 935 write!(f, "(")?;
906 f.write_joined(sig.params(), ", ")?; 936 f.write_joined(sig.value.params(), ", ")?;
907 write!(f, ") -> {}", sig.ret().display(f.db))?; 937 write!(f, ") -> {}", sig.value.ret().display(f.db))?;
908 } 938 }
909 TypeCtor::Adt(def_id) => { 939 TypeCtor::Adt(def_id) => {
910 let name = match def_id { 940 let name = match def_id {