Differentiate Tuple / FnPtr type constructors by cardinality
This is necessary because Chalk (reasonably) expects each 'struct' to know how many type parameters it takes.
This commit is contained in:
parent
19fbd91998
commit
a4eb1a546c
@ -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<FnSig> {
|
||||
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(), ", ")?;
|
||||
|
@ -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::<Vec<_>>()
|
||||
.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::<usize>().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 {
|
||||
|
@ -29,7 +29,10 @@ impl Ty {
|
||||
TypeRef::Tuple(inner) => {
|
||||
let inner_tys =
|
||||
inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>();
|
||||
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::<Vec<_>>();
|
||||
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,
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user