Align FnPointer with Chalk

This commit is contained in:
Florian Diebold 2021-04-05 22:23:16 +02:00
parent f25c1e7c6a
commit edc59d897d
9 changed files with 86 additions and 40 deletions

View File

@ -12,8 +12,8 @@ use smallvec::SmallVec;
use crate::{
db::HirDatabase, primitive, to_assoc_type_id, to_chalk_trait_id, utils::generics, Binders,
CallableSig, FnPointer, FnSig, GenericArg, Interner, ProjectionTy, Substitution, TraitRef, Ty,
TyDefId, TyKind, TypeWalk, ValueTyDefId,
CallableSig, FnPointer, FnSig, FnSubst, GenericArg, Interner, ProjectionTy, Substitution,
TraitRef, Ty, TyDefId, TyKind, TypeWalk, ValueTyDefId,
};
/// This is a builder for `Ty` or anything that needs a `Substitution`.
@ -78,9 +78,12 @@ impl TyBuilder<()> {
pub fn fn_ptr(sig: CallableSig) -> Ty {
TyKind::Function(FnPointer {
num_args: sig.params().len(),
num_binders: 0,
sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs },
substs: Substitution::from_iter(&Interner, sig.params_and_return.iter().cloned()),
substitution: FnSubst(Substitution::from_iter(
&Interner,
sig.params_and_return.iter().cloned(),
)),
})
.intern(&Interner)
}

View File

@ -22,8 +22,8 @@ use crate::{
to_chalk_trait_id,
traits::{chalk::from_chalk, FnTrait},
utils::{generics, variant_data, Generics},
AdtId, Binders, CallableDefId, FnPointer, FnSig, InEnvironment, Interner, ProjectionTyExt,
Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind,
AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind,
};
use super::{
@ -260,9 +260,9 @@ impl<'a> InferenceContext<'a> {
};
sig_tys.push(ret_ty.clone());
let sig_ty = TyKind::Function(FnPointer {
num_args: sig_tys.len() - 1,
num_binders: 0,
sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
substs: Substitution::from_iter(&Interner, sig_tys.clone()),
substitution: FnSubst(Substitution::from_iter(&Interner, sig_tys.clone())),
})
.intern(&Interner);
let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();

View File

@ -7,7 +7,7 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
use super::{DomainGoal, InferenceContext};
use crate::{
AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer,
AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSubst,
InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause,
};
@ -308,8 +308,8 @@ impl InferenceTable {
(TyKind::Adt(_, substs1), TyKind::Adt(_, substs2))
| (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2))
| (
TyKind::Function(FnPointer { substs: substs1, .. }),
TyKind::Function(FnPointer { substs: substs2, .. }),
TyKind::Function(FnPointer { substitution: FnSubst(substs1), .. }),
TyKind::Function(FnPointer { substitution: FnSubst(substs2), .. }),
)
| (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2))
| (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2))

View File

@ -142,10 +142,11 @@ impl CallableSig {
CallableSig {
// FIXME: what to do about lifetime params? -> return PolyFnSig
params_and_return: fn_ptr
.substs
.substitution
.clone()
.shifted_out_to(DebruijnIndex::ONE)
.expect("unexpected lifetime vars in fn ptr")
.0
.interned()
.iter()
.map(|arg| arg.assert_ty_ref(&Interner).clone())
@ -239,9 +240,9 @@ impl Ty {
mutability == mutability2
}
(
TyKind::Function(FnPointer { num_args, sig, .. }),
TyKind::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
) => num_args == num_args2 && sig == sig2,
TyKind::Function(FnPointer { num_binders, sig, .. }),
TyKind::Function(FnPointer { num_binders: num_binders2, sig: sig2, .. }),
) => num_binders == num_binders2 && sig == sig2,
(TyKind::Tuple(cardinality, _), TyKind::Tuple(cardinality2, _)) => {
cardinality == cardinality2
}
@ -314,11 +315,11 @@ impl Ty {
match self.kind(&Interner) {
TyKind::Adt(_, substs)
| TyKind::FnDef(_, substs)
| TyKind::Function(FnPointer { substs, .. })
| TyKind::Tuple(_, substs)
| TyKind::OpaqueType(_, substs)
| TyKind::AssociatedType(_, substs)
| TyKind::Closure(.., substs) => Some(substs),
TyKind::Function(FnPointer { substitution: substs, .. }) => Some(&substs.0),
_ => None,
}
}
@ -327,11 +328,11 @@ impl Ty {
match self.interned_mut() {
TyKind::Adt(_, substs)
| TyKind::FnDef(_, substs)
| TyKind::Function(FnPointer { substs, .. })
| TyKind::Tuple(_, substs)
| TyKind::OpaqueType(_, substs)
| TyKind::AssociatedType(_, substs)
| TyKind::Closure(.., substs) => Some(substs),
TyKind::Function(FnPointer { substitution: substs, .. }) => Some(&mut substs.0),
_ => None,
}
}

View File

@ -34,9 +34,9 @@ use crate::{
variant_data, Generics,
},
AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses,
ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty,
TyBuilder, TyKind, TypeWalk, WhereClause,
FnSubst, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution,
TraitEnvironment, TraitRef, Ty, TyBuilder, TyKind, TypeWalk, WhereClause,
};
#[derive(Debug)]
@ -181,9 +181,9 @@ impl<'a> TyLoweringContext<'a> {
let substs =
Substitution::from_iter(&Interner, params.iter().map(|tr| self.lower_ty(tr)));
TyKind::Function(FnPointer {
num_args: substs.len(&Interner) - 1,
num_binders: 0, // FIXME lower `for<'a> fn()` correctly
sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
substs,
substitution: FnSubst(substs),
})
.intern(&Interner)
}

View File

@ -46,18 +46,18 @@ impl TyFingerprint {
/// have impls: if we have some `struct S`, we can have an `impl S`, but not
/// `impl &S`. Hence, this will return `None` for reference types and such.
pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
let fp = match *ty.kind(&Interner) {
let fp = match ty.kind(&Interner) {
TyKind::Str => TyFingerprint::Str,
TyKind::Never => TyFingerprint::Never,
TyKind::Slice(..) => TyFingerprint::Slice,
TyKind::Array(..) => TyFingerprint::Array,
TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar),
TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt),
TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality),
TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability),
TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(alias_id),
TyKind::Function(FnPointer { num_args, sig, .. }) => {
TyFingerprint::FnPtr(num_args, sig)
TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(*cardinality),
TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
TyKind::Function(FnPointer { sig, substitution: substs, .. }) => {
TyFingerprint::FnPtr(substs.0.len(&Interner) - 1, *sig)
}
TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
_ => return None,

View File

@ -24,8 +24,8 @@ impl ToChalk for Ty {
match self.into_inner() {
TyKind::Ref(m, ty) => ref_to_chalk(db, m, ty),
TyKind::Array(ty) => array_to_chalk(db, ty),
TyKind::Function(FnPointer { sig, substs, .. }) => {
let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner));
TyKind::Function(FnPointer { sig, substitution: substs, .. }) => {
let substitution = chalk_ir::FnSubst(substs.0.to_chalk(db).shifted_in(&Interner));
chalk_ir::TyKind::Function(chalk_ir::FnPointer {
num_binders: 0,
sig,
@ -132,11 +132,11 @@ impl ToChalk for Ty {
..
}) => {
assert_eq!(num_binders, 0);
let substs: Substitution = from_chalk(
let substs = crate::FnSubst(from_chalk(
db,
substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
);
TyKind::Function(FnPointer { num_args: (substs.len(&Interner) - 1), sig, substs })
));
TyKind::Function(FnPointer { num_binders, sig, substitution: substs })
}
chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx),
chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Error,

View File

@ -11,7 +11,7 @@ use smallvec::SmallVec;
use crate::{
AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId,
InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, TypeWalk, VariableKinds,
InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, TypeWalk, VariableKind, VariableKinds,
};
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@ -43,9 +43,36 @@ pub struct DynTy {
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct FnPointer {
pub num_args: usize,
pub num_binders: usize,
pub sig: FnSig,
pub substs: Substitution,
pub substitution: FnSubst,
}
/// A wrapper for the substs on a Fn.
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct FnSubst(pub Substitution);
impl FnPointer {
/// Represent the current `Fn` as if it was wrapped in `Binders`
pub fn into_binders(self, interner: &Interner) -> Binders<FnSubst> {
Binders::new(
VariableKinds::from_iter(
interner,
(0..self.num_binders).map(|_| VariableKind::Lifetime),
),
self.substitution,
)
}
/// Represent the current `Fn` as if it was wrapped in `Binders`
pub fn as_binders(&self, interner: &Interner) -> Binders<&FnSubst> {
Binders::new(
VariableKinds::from_iter(
interner,
(0..self.num_binders).map(|_| VariableKind::Lifetime),
),
&self.substitution,
)
}
}
#[derive(Clone, PartialEq, Eq, Debug, Hash)]

View File

@ -6,8 +6,9 @@ use std::mem;
use chalk_ir::DebruijnIndex;
use crate::{
utils::make_mut_slice, AliasEq, AliasTy, Binders, CallableSig, GenericArg, GenericArgData,
Interner, OpaqueTy, ProjectionTy, Substitution, TraitRef, Ty, TyKind, WhereClause,
utils::make_mut_slice, AliasEq, AliasTy, Binders, CallableSig, FnSubst, GenericArg,
GenericArgData, Interner, OpaqueTy, ProjectionTy, Substitution, TraitRef, Ty, TyKind,
WhereClause,
};
/// This allows walking structures that contain types to do something with those
@ -381,3 +382,17 @@ impl TypeWalk for AliasEq {
}
}
}
impl TypeWalk for FnSubst {
fn walk(&self, f: &mut impl FnMut(&Ty)) {
self.0.walk(f)
}
fn walk_mut_binders(
&mut self,
f: &mut impl FnMut(&mut Ty, DebruijnIndex),
binders: DebruijnIndex,
) {
self.0.walk_mut_binders(f, binders)
}
}