aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-05-04 18:07:25 +0100
committerFlorian Diebold <[email protected]>2019-05-04 18:11:21 +0100
commita4eb1a546c7623f65823c5e249cd3c6d8c90fd8c (patch)
tree0942d7a4976bb444031d044beb1ea786adabcaeb /crates
parent19fbd919986e99287168f40aa11003a11aa43d3a (diff)
Differentiate Tuple / FnPtr type constructors by cardinality
This is necessary because Chalk (reasonably) expects each 'struct' to know how many type parameters it takes.
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/ty.rs16
-rw-r--r--crates/ra_hir/src/ty/infer.rs11
-rw-r--r--crates/ra_hir/src/ty/lower.rs7
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs4
-rw-r--r--crates/ra_ide_api/src/completion/complete_dot.rs2
5 files changed, 25 insertions, 15 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index f2b37b208..f4eee835f 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -82,13 +82,13 @@ pub enum TypeCtor {
82 /// fn foo() -> i32 { 1 } 82 /// fn foo() -> i32 { 1 }
83 /// let bar: fn() -> i32 = foo; 83 /// let bar: fn() -> i32 = foo;
84 /// ``` 84 /// ```
85 FnPtr, 85 FnPtr { num_args: u16 },
86 86
87 /// The never type `!`. 87 /// The never type `!`.
88 Never, 88 Never,
89 89
90 /// A tuple type. For example, `(i32, bool)`. 90 /// A tuple type. For example, `(i32, bool)`.
91 Tuple, 91 Tuple { cardinality: u16 },
92} 92}
93 93
94/// A nominal type with (maybe 0) type parameters. This might be a primitive 94/// A nominal type with (maybe 0) type parameters. This might be a primitive
@@ -299,7 +299,7 @@ impl Ty {
299 Ty::Apply(ApplicationTy { ctor, parameters }) 299 Ty::Apply(ApplicationTy { ctor, parameters })
300 } 300 }
301 pub fn unit() -> Self { 301 pub fn unit() -> Self {
302 Ty::apply(TypeCtor::Tuple, Substs::empty()) 302 Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty())
303 } 303 }
304 304
305 pub fn walk(&self, f: &mut impl FnMut(&Ty)) { 305 pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
@@ -352,7 +352,9 @@ impl Ty {
352 352
353 pub fn as_tuple(&self) -> Option<&Substs> { 353 pub fn as_tuple(&self) -> Option<&Substs> {
354 match self { 354 match self {
355 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple, parameters }) => Some(parameters), 355 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => {
356 Some(parameters)
357 }
356 _ => None, 358 _ => None,
357 } 359 }
358 } 360 }
@@ -380,7 +382,7 @@ impl Ty {
380 fn callable_sig(&self, db: &impl HirDatabase) -> Option<FnSig> { 382 fn callable_sig(&self, db: &impl HirDatabase) -> Option<FnSig> {
381 match self { 383 match self {
382 Ty::Apply(a_ty) => match a_ty.ctor { 384 Ty::Apply(a_ty) => match a_ty.ctor {
383 TypeCtor::FnPtr => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)), 385 TypeCtor::FnPtr { .. } => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)),
384 TypeCtor::FnDef(def) => { 386 TypeCtor::FnDef(def) => {
385 let sig = db.callable_item_signature(def); 387 let sig = db.callable_item_signature(def);
386 Some(sig.subst(&a_ty.parameters)) 388 Some(sig.subst(&a_ty.parameters))
@@ -466,7 +468,7 @@ impl HirDisplay for ApplicationTy {
466 write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?; 468 write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?;
467 } 469 }
468 TypeCtor::Never => write!(f, "!")?, 470 TypeCtor::Never => write!(f, "!")?,
469 TypeCtor::Tuple => { 471 TypeCtor::Tuple { .. } => {
470 let ts = &self.parameters; 472 let ts = &self.parameters;
471 if ts.len() == 1 { 473 if ts.len() == 1 {
472 write!(f, "({},)", ts[0].display(f.db))?; 474 write!(f, "({},)", ts[0].display(f.db))?;
@@ -476,7 +478,7 @@ impl HirDisplay for ApplicationTy {
476 write!(f, ")")?; 478 write!(f, ")")?;
477 } 479 }
478 } 480 }
479 TypeCtor::FnPtr => { 481 TypeCtor::FnPtr { .. } => {
480 let sig = FnSig::from_fn_ptr_substs(&self.parameters); 482 let sig = FnSig::from_fn_ptr_substs(&self.parameters);
481 write!(f, "fn(")?; 483 write!(f, "fn(")?;
482 f.write_joined(sig.params(), ", ")?; 484 f.write_joined(sig.params(), ", ")?;
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index cc74c6322..edce1afe7 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -739,14 +739,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
739 }; 739 };
740 let expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown)); 740 let expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown));
741 741
742 let inner_tys = args 742 let inner_tys: Substs = args
743 .iter() 743 .iter()
744 .zip(expectations_iter) 744 .zip(expectations_iter)
745 .map(|(&pat, ty)| self.infer_pat(pat, ty, default_bm)) 745 .map(|(&pat, ty)| self.infer_pat(pat, ty, default_bm))
746 .collect::<Vec<_>>() 746 .collect::<Vec<_>>()
747 .into(); 747 .into();
748 748
749 Ty::apply(TypeCtor::Tuple, Substs(inner_tys)) 749 Ty::apply(TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, inner_tys)
750 } 750 }
751 Pat::Ref { pat, mutability } => { 751 Pat::Ref { pat, mutability } => {
752 let expectation = match expected.as_reference() { 752 let expectation = match expected.as_reference() {
@@ -1073,7 +1073,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1073 .autoderef(self.db) 1073 .autoderef(self.db)
1074 .find_map(|derefed_ty| match derefed_ty { 1074 .find_map(|derefed_ty| match derefed_ty {
1075 Ty::Apply(a_ty) => match a_ty.ctor { 1075 Ty::Apply(a_ty) => match a_ty.ctor {
1076 TypeCtor::Tuple => { 1076 TypeCtor::Tuple { .. } => {
1077 let i = name.to_string().parse::<usize>().ok(); 1077 let i = name.to_string().parse::<usize>().ok();
1078 i.and_then(|i| a_ty.parameters.0.get(i).cloned()) 1078 i.and_then(|i| a_ty.parameters.0.get(i).cloned())
1079 } 1079 }
@@ -1184,7 +1184,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1184 ty_vec.push(self.infer_expr(*arg, &Expectation::none())); 1184 ty_vec.push(self.infer_expr(*arg, &Expectation::none()));
1185 } 1185 }
1186 1186
1187 Ty::apply(TypeCtor::Tuple, Substs(ty_vec.into())) 1187 Ty::apply(
1188 TypeCtor::Tuple { cardinality: ty_vec.len() as u16 },
1189 Substs(ty_vec.into()),
1190 )
1188 } 1191 }
1189 Expr::Array(array) => { 1192 Expr::Array(array) => {
1190 let elem_ty = match &expected.ty { 1193 let elem_ty = match &expected.ty {
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 2bbd17068..8bab7e54b 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -29,7 +29,10 @@ impl Ty {
29 TypeRef::Tuple(inner) => { 29 TypeRef::Tuple(inner) => {
30 let inner_tys = 30 let inner_tys =
31 inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>(); 31 inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>();
32 Ty::apply(TypeCtor::Tuple, Substs(inner_tys.into())) 32 Ty::apply(
33 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 },
34 Substs(inner_tys.into()),
35 )
33 } 36 }
34 TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path), 37 TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path),
35 TypeRef::RawPtr(inner, mutability) => { 38 TypeRef::RawPtr(inner, mutability) => {
@@ -53,7 +56,7 @@ impl Ty {
53 let inner_tys = 56 let inner_tys =
54 params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>(); 57 params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>();
55 let sig = Substs(inner_tys.into()); 58 let sig = Substs(inner_tys.into());
56 Ty::apply(TypeCtor::FnPtr, sig) 59 Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig)
57 } 60 }
58 TypeRef::Error => Ty::Unknown, 61 TypeRef::Error => Ty::Unknown,
59 } 62 }
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 74370bae9..8b77d21b4 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -184,6 +184,7 @@ where
184 debug!("struct_datum {:?}", struct_id); 184 debug!("struct_datum {:?}", struct_id);
185 let type_ctor = from_chalk(self.db, struct_id); 185 let type_ctor = from_chalk(self.db, struct_id);
186 // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor 186 // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor
187 // FIXME extract this to a method on Ty
187 let (num_params, upstream) = match type_ctor { 188 let (num_params, upstream) = match type_ctor {
188 TypeCtor::Bool 189 TypeCtor::Bool
189 | TypeCtor::Char 190 | TypeCtor::Char
@@ -192,7 +193,8 @@ where
192 | TypeCtor::Never 193 | TypeCtor::Never
193 | TypeCtor::Str => (0, true), 194 | TypeCtor::Str => (0, true),
194 TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => (1, true), 195 TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => (1, true),
195 TypeCtor::FnPtr | TypeCtor::Tuple => unimplemented!(), // FIXME tuples and FnPtr are currently variadic... we need to make the parameter number explicit 196 TypeCtor::FnPtr { num_args } => (num_args as usize + 1, true),
197 TypeCtor::Tuple { cardinality } => (cardinality as usize, true),
196 TypeCtor::FnDef(_) => unimplemented!(), 198 TypeCtor::FnDef(_) => unimplemented!(),
197 TypeCtor::Adt(adt) => { 199 TypeCtor::Adt(adt) => {
198 let generic_params = adt.generic_params(self.db); 200 let generic_params = adt.generic_params(self.db);
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs
index e34ddf24a..2e8084699 100644
--- a/crates/ra_ide_api/src/completion/complete_dot.rs
+++ b/crates/ra_ide_api/src/completion/complete_dot.rs
@@ -24,7 +24,7 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty)
24 } 24 }
25 } 25 }
26 // FIXME unions 26 // FIXME unions
27 TypeCtor::Tuple => { 27 TypeCtor::Tuple { .. } => {
28 for (i, ty) in a_ty.parameters.iter().enumerate() { 28 for (i, ty) in a_ty.parameters.iter().enumerate() {
29 acc.add_pos_field(ctx, i, ty); 29 acc.add_pos_field(ctx, i, ty);
30 } 30 }