From a4eb1a546c7623f65823c5e249cd3c6d8c90fd8c Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 4 May 2019 19:07:25 +0200 Subject: Differentiate Tuple / FnPtr type constructors by cardinality This is necessary because Chalk (reasonably) expects each 'struct' to know how many type parameters it takes. --- crates/ra_hir/src/ty.rs | 16 +++++++++------- crates/ra_hir/src/ty/infer.rs | 11 +++++++---- crates/ra_hir/src/ty/lower.rs | 7 +++++-- crates/ra_hir/src/ty/traits/chalk.rs | 4 +++- 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 { /// fn foo() -> i32 { 1 } /// let bar: fn() -> i32 = foo; /// ``` - FnPtr, + FnPtr { num_args: u16 }, /// The never type `!`. Never, /// A tuple type. For example, `(i32, bool)`. - Tuple, + Tuple { cardinality: u16 }, } /// A nominal type with (maybe 0) type parameters. This might be a primitive @@ -299,7 +299,7 @@ impl Ty { Ty::Apply(ApplicationTy { ctor, parameters }) } pub fn unit() -> Self { - Ty::apply(TypeCtor::Tuple, Substs::empty()) + Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) } pub fn walk(&self, f: &mut impl FnMut(&Ty)) { @@ -352,7 +352,9 @@ impl Ty { pub fn as_tuple(&self) -> Option<&Substs> { match self { - Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple, parameters }) => Some(parameters), + Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { + Some(parameters) + } _ => None, } } @@ -380,7 +382,7 @@ impl Ty { fn callable_sig(&self, db: &impl HirDatabase) -> Option { match self { Ty::Apply(a_ty) => match a_ty.ctor { - TypeCtor::FnPtr => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)), + TypeCtor::FnPtr { .. } => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)), TypeCtor::FnDef(def) => { let sig = db.callable_item_signature(def); Some(sig.subst(&a_ty.parameters)) @@ -466,7 +468,7 @@ impl HirDisplay for ApplicationTy { write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?; } TypeCtor::Never => write!(f, "!")?, - TypeCtor::Tuple => { + TypeCtor::Tuple { .. } => { let ts = &self.parameters; if ts.len() == 1 { write!(f, "({},)", ts[0].display(f.db))?; @@ -476,7 +478,7 @@ impl HirDisplay for ApplicationTy { write!(f, ")")?; } } - TypeCtor::FnPtr => { + TypeCtor::FnPtr { .. } => { let sig = FnSig::from_fn_ptr_substs(&self.parameters); write!(f, "fn(")?; 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> { }; let expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown)); - let inner_tys = args + let inner_tys: Substs = args .iter() .zip(expectations_iter) .map(|(&pat, ty)| self.infer_pat(pat, ty, default_bm)) .collect::>() .into(); - Ty::apply(TypeCtor::Tuple, Substs(inner_tys)) + Ty::apply(TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, inner_tys) } Pat::Ref { pat, mutability } => { let expectation = match expected.as_reference() { @@ -1073,7 +1073,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { .autoderef(self.db) .find_map(|derefed_ty| match derefed_ty { Ty::Apply(a_ty) => match a_ty.ctor { - TypeCtor::Tuple => { + TypeCtor::Tuple { .. } => { let i = name.to_string().parse::().ok(); i.and_then(|i| a_ty.parameters.0.get(i).cloned()) } @@ -1184,7 +1184,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { ty_vec.push(self.infer_expr(*arg, &Expectation::none())); } - Ty::apply(TypeCtor::Tuple, Substs(ty_vec.into())) + Ty::apply( + TypeCtor::Tuple { cardinality: ty_vec.len() as u16 }, + Substs(ty_vec.into()), + ) } Expr::Array(array) => { 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 { TypeRef::Tuple(inner) => { let inner_tys = inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::>(); - Ty::apply(TypeCtor::Tuple, Substs(inner_tys.into())) + Ty::apply( + TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, + Substs(inner_tys.into()), + ) } TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path), TypeRef::RawPtr(inner, mutability) => { @@ -53,7 +56,7 @@ impl Ty { let inner_tys = params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::>(); let sig = Substs(inner_tys.into()); - Ty::apply(TypeCtor::FnPtr, sig) + Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig) } TypeRef::Error => Ty::Unknown, } 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 debug!("struct_datum {:?}", struct_id); let type_ctor = from_chalk(self.db, struct_id); // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor + // FIXME extract this to a method on Ty let (num_params, upstream) = match type_ctor { TypeCtor::Bool | TypeCtor::Char @@ -192,7 +193,8 @@ where | TypeCtor::Never | TypeCtor::Str => (0, true), TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => (1, true), - TypeCtor::FnPtr | TypeCtor::Tuple => unimplemented!(), // FIXME tuples and FnPtr are currently variadic... we need to make the parameter number explicit + TypeCtor::FnPtr { num_args } => (num_args as usize + 1, true), + TypeCtor::Tuple { cardinality } => (cardinality as usize, true), TypeCtor::FnDef(_) => unimplemented!(), TypeCtor::Adt(adt) => { 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) } } // FIXME unions - TypeCtor::Tuple => { + TypeCtor::Tuple { .. } => { for (i, ty) in a_ty.parameters.iter().enumerate() { acc.add_pos_field(ctx, i, ty); } -- cgit v1.2.3