8358: Align FnPointer with Chalk r=flodiebold a=flodiebold

CC #8313

Co-authored-by: Florian Diebold <flodiebold@gmail.com>
This commit is contained in:
bors[bot] 2021-04-05 20:25:13 +00:00 committed by GitHub
commit 7ce0e9c9ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 86 additions and 40 deletions

View file

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

View file

@ -22,8 +22,8 @@ use crate::{
to_chalk_trait_id, to_chalk_trait_id,
traits::{chalk::from_chalk, FnTrait}, traits::{chalk::from_chalk, FnTrait},
utils::{generics, variant_data, Generics}, utils::{generics, variant_data, Generics},
AdtId, Binders, CallableDefId, FnPointer, FnSig, InEnvironment, Interner, ProjectionTyExt, AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind, ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind,
}; };
use super::{ use super::{
@ -260,9 +260,9 @@ impl<'a> InferenceContext<'a> {
}; };
sig_tys.push(ret_ty.clone()); sig_tys.push(ret_ty.clone());
let sig_ty = TyKind::Function(FnPointer { 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 }, 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); .intern(&Interner);
let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); 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 super::{DomainGoal, InferenceContext};
use crate::{ 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, InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause,
}; };
@ -308,8 +308,8 @@ impl InferenceTable {
(TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2))
| (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2))
| ( | (
TyKind::Function(FnPointer { substs: substs1, .. }), TyKind::Function(FnPointer { substitution: FnSubst(substs1), .. }),
TyKind::Function(FnPointer { substs: substs2, .. }), TyKind::Function(FnPointer { substitution: FnSubst(substs2), .. }),
) )
| (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2)) | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2))
| (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2)) | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2))

View file

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

View file

@ -34,9 +34,9 @@ use crate::{
variant_data, Generics, variant_data, Generics,
}, },
AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, FnSubst, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution,
TyBuilder, TyKind, TypeWalk, WhereClause, TraitEnvironment, TraitRef, Ty, TyBuilder, TyKind, TypeWalk, WhereClause,
}; };
#[derive(Debug)] #[derive(Debug)]
@ -181,9 +181,9 @@ impl<'a> TyLoweringContext<'a> {
let substs = let substs =
Substitution::from_iter(&Interner, params.iter().map(|tr| self.lower_ty(tr))); Substitution::from_iter(&Interner, params.iter().map(|tr| self.lower_ty(tr)));
TyKind::Function(FnPointer { 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 }, sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
substs, substitution: FnSubst(substs),
}) })
.intern(&Interner) .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 /// 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. /// `impl &S`. Hence, this will return `None` for reference types and such.
pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 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::Str => TyFingerprint::Str,
TyKind::Never => TyFingerprint::Never, TyKind::Never => TyFingerprint::Never,
TyKind::Slice(..) => TyFingerprint::Slice, TyKind::Slice(..) => TyFingerprint::Slice,
TyKind::Array(..) => TyFingerprint::Array, TyKind::Array(..) => TyFingerprint::Array,
TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar), TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(*cardinality),
TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(alias_id), TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
TyKind::Function(FnPointer { num_args, sig, .. }) => { TyKind::Function(FnPointer { sig, substitution: substs, .. }) => {
TyFingerprint::FnPtr(num_args, sig) TyFingerprint::FnPtr(substs.0.len(&Interner) - 1, *sig)
} }
TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
_ => return None, _ => return None,

View file

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

View file

@ -11,7 +11,7 @@ use smallvec::SmallVec;
use crate::{ use crate::{
AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId, 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)] #[derive(Clone, PartialEq, Eq, Debug, Hash)]
@ -43,9 +43,36 @@ pub struct DynTy {
#[derive(Clone, PartialEq, Eq, Debug, Hash)] #[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct FnPointer { pub struct FnPointer {
pub num_args: usize, pub num_binders: usize,
pub sig: FnSig, 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)] #[derive(Clone, PartialEq, Eq, Debug, Hash)]

View file

@ -6,8 +6,9 @@ use std::mem;
use chalk_ir::DebruijnIndex; use chalk_ir::DebruijnIndex;
use crate::{ use crate::{
utils::make_mut_slice, AliasEq, AliasTy, Binders, CallableSig, GenericArg, GenericArgData, utils::make_mut_slice, AliasEq, AliasTy, Binders, CallableSig, FnSubst, GenericArg,
Interner, OpaqueTy, ProjectionTy, Substitution, TraitRef, Ty, TyKind, WhereClause, GenericArgData, Interner, OpaqueTy, ProjectionTy, Substitution, TraitRef, Ty, TyKind,
WhereClause,
}; };
/// This allows walking structures that contain types to do something with those /// 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)
}
}