mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
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 }
|
/// fn foo() -> i32 { 1 }
|
||||||
/// let bar: fn() -> i32 = foo;
|
/// let bar: fn() -> i32 = foo;
|
||||||
/// ```
|
/// ```
|
||||||
FnPtr,
|
FnPtr { num_args: u16 },
|
||||||
|
|
||||||
/// The never type `!`.
|
/// The never type `!`.
|
||||||
Never,
|
Never,
|
||||||
|
|
||||||
/// A tuple type. For example, `(i32, bool)`.
|
/// A tuple type. For example, `(i32, bool)`.
|
||||||
Tuple,
|
Tuple { cardinality: u16 },
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A nominal type with (maybe 0) type parameters. This might be a primitive
|
/// A nominal type with (maybe 0) type parameters. This might be a primitive
|
||||||
@ -299,7 +299,7 @@ impl Ty {
|
|||||||
Ty::Apply(ApplicationTy { ctor, parameters })
|
Ty::Apply(ApplicationTy { ctor, parameters })
|
||||||
}
|
}
|
||||||
pub fn unit() -> Self {
|
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)) {
|
pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
|
||||||
@ -352,7 +352,9 @@ impl Ty {
|
|||||||
|
|
||||||
pub fn as_tuple(&self) -> Option<&Substs> {
|
pub fn as_tuple(&self) -> Option<&Substs> {
|
||||||
match self {
|
match self {
|
||||||
Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple, parameters }) => Some(parameters),
|
Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => {
|
||||||
|
Some(parameters)
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -380,7 +382,7 @@ impl Ty {
|
|||||||
fn callable_sig(&self, db: &impl HirDatabase) -> Option<FnSig> {
|
fn callable_sig(&self, db: &impl HirDatabase) -> Option<FnSig> {
|
||||||
match self {
|
match self {
|
||||||
Ty::Apply(a_ty) => match a_ty.ctor {
|
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) => {
|
TypeCtor::FnDef(def) => {
|
||||||
let sig = db.callable_item_signature(def);
|
let sig = db.callable_item_signature(def);
|
||||||
Some(sig.subst(&a_ty.parameters))
|
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))?;
|
write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?;
|
||||||
}
|
}
|
||||||
TypeCtor::Never => write!(f, "!")?,
|
TypeCtor::Never => write!(f, "!")?,
|
||||||
TypeCtor::Tuple => {
|
TypeCtor::Tuple { .. } => {
|
||||||
let ts = &self.parameters;
|
let ts = &self.parameters;
|
||||||
if ts.len() == 1 {
|
if ts.len() == 1 {
|
||||||
write!(f, "({},)", ts[0].display(f.db))?;
|
write!(f, "({},)", ts[0].display(f.db))?;
|
||||||
@ -476,7 +478,7 @@ impl HirDisplay for ApplicationTy {
|
|||||||
write!(f, ")")?;
|
write!(f, ")")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypeCtor::FnPtr => {
|
TypeCtor::FnPtr { .. } => {
|
||||||
let sig = FnSig::from_fn_ptr_substs(&self.parameters);
|
let sig = FnSig::from_fn_ptr_substs(&self.parameters);
|
||||||
write!(f, "fn(")?;
|
write!(f, "fn(")?;
|
||||||
f.write_joined(sig.params(), ", ")?;
|
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 expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown));
|
||||||
|
|
||||||
let inner_tys = args
|
let inner_tys: Substs = args
|
||||||
.iter()
|
.iter()
|
||||||
.zip(expectations_iter)
|
.zip(expectations_iter)
|
||||||
.map(|(&pat, ty)| self.infer_pat(pat, ty, default_bm))
|
.map(|(&pat, ty)| self.infer_pat(pat, ty, default_bm))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
Ty::apply(TypeCtor::Tuple, Substs(inner_tys))
|
Ty::apply(TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, inner_tys)
|
||||||
}
|
}
|
||||||
Pat::Ref { pat, mutability } => {
|
Pat::Ref { pat, mutability } => {
|
||||||
let expectation = match expected.as_reference() {
|
let expectation = match expected.as_reference() {
|
||||||
@ -1073,7 +1073,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
|||||||
.autoderef(self.db)
|
.autoderef(self.db)
|
||||||
.find_map(|derefed_ty| match derefed_ty {
|
.find_map(|derefed_ty| match derefed_ty {
|
||||||
Ty::Apply(a_ty) => match a_ty.ctor {
|
Ty::Apply(a_ty) => match a_ty.ctor {
|
||||||
TypeCtor::Tuple => {
|
TypeCtor::Tuple { .. } => {
|
||||||
let i = name.to_string().parse::<usize>().ok();
|
let i = name.to_string().parse::<usize>().ok();
|
||||||
i.and_then(|i| a_ty.parameters.0.get(i).cloned())
|
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_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) => {
|
Expr::Array(array) => {
|
||||||
let elem_ty = match &expected.ty {
|
let elem_ty = match &expected.ty {
|
||||||
|
@ -29,7 +29,10 @@ impl Ty {
|
|||||||
TypeRef::Tuple(inner) => {
|
TypeRef::Tuple(inner) => {
|
||||||
let inner_tys =
|
let inner_tys =
|
||||||
inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>();
|
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::Path(path) => Ty::from_hir_path(db, resolver, path),
|
||||||
TypeRef::RawPtr(inner, mutability) => {
|
TypeRef::RawPtr(inner, mutability) => {
|
||||||
@ -53,7 +56,7 @@ impl Ty {
|
|||||||
let inner_tys =
|
let inner_tys =
|
||||||
params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>();
|
params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>();
|
||||||
let sig = Substs(inner_tys.into());
|
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,
|
TypeRef::Error => Ty::Unknown,
|
||||||
}
|
}
|
||||||
|
@ -184,6 +184,7 @@ where
|
|||||||
debug!("struct_datum {:?}", struct_id);
|
debug!("struct_datum {:?}", struct_id);
|
||||||
let type_ctor = from_chalk(self.db, 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 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 {
|
let (num_params, upstream) = match type_ctor {
|
||||||
TypeCtor::Bool
|
TypeCtor::Bool
|
||||||
| TypeCtor::Char
|
| TypeCtor::Char
|
||||||
@ -192,7 +193,8 @@ where
|
|||||||
| TypeCtor::Never
|
| TypeCtor::Never
|
||||||
| TypeCtor::Str => (0, true),
|
| TypeCtor::Str => (0, true),
|
||||||
TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => (1, 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::FnDef(_) => unimplemented!(),
|
||||||
TypeCtor::Adt(adt) => {
|
TypeCtor::Adt(adt) => {
|
||||||
let generic_params = adt.generic_params(self.db);
|
let generic_params = adt.generic_params(self.db);
|
||||||
|
@ -24,7 +24,7 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FIXME unions
|
// FIXME unions
|
||||||
TypeCtor::Tuple => {
|
TypeCtor::Tuple { .. } => {
|
||||||
for (i, ty) in a_ty.parameters.iter().enumerate() {
|
for (i, ty) in a_ty.parameters.iter().enumerate() {
|
||||||
acc.add_pos_field(ctx, i, ty);
|
acc.add_pos_field(ctx, i, ty);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user