diff options
author | Florian Diebold <[email protected]> | 2019-05-04 18:07:25 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-05-04 18:11:21 +0100 |
commit | a4eb1a546c7623f65823c5e249cd3c6d8c90fd8c (patch) | |
tree | 0942d7a4976bb444031d044beb1ea786adabcaeb | |
parent | 19fbd919986e99287168f40aa11003a11aa43d3a (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.
-rw-r--r-- | crates/ra_hir/src/ty.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_dot.rs | 2 |
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 | } |