Align FnPointer with Chalk
This commit is contained in:
parent
f25c1e7c6a
commit
edc59d897d
@ -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)
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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))
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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)]
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user