From edc59d897d56815e8b9814cdc4ff084100e4f3b4 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Mon, 5 Apr 2021 22:23:16 +0200 Subject: Align FnPointer with Chalk --- crates/hir_ty/src/builder.rs | 11 +++++++---- crates/hir_ty/src/infer/expr.rs | 8 ++++---- crates/hir_ty/src/infer/unify.rs | 6 +++--- crates/hir_ty/src/lib.rs | 13 ++++++------ crates/hir_ty/src/lower.rs | 10 +++++----- crates/hir_ty/src/method_resolution.rs | 16 +++++++-------- crates/hir_ty/src/traits/chalk/mapping.rs | 10 +++++----- crates/hir_ty/src/types.rs | 33 ++++++++++++++++++++++++++++--- crates/hir_ty/src/walk.rs | 19 ++++++++++++++++-- 9 files changed, 86 insertions(+), 40 deletions(-) diff --git a/crates/hir_ty/src/builder.rs b/crates/hir_ty/src/builder.rs index 9b2c6975a..791915fe0 100644 --- a/crates/hir_ty/src/builder.rs +++ b/crates/hir_ty/src/builder.rs @@ -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) } diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 185a2dfc3..a2a7236a8 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -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(); diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index c90a16720..2f9523325 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs @@ -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)) diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index f74b22b58..c3ec12352 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -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, } } diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 6cef8095f..20bb7dd59 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -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) } diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index d6de844a8..6d65d3eb9 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -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 { - 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, diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 9f10b889f..13d8d1111 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs @@ -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, diff --git a/crates/hir_ty/src/types.rs b/crates/hir_ty/src/types.rs index 4a626d5e7..d4e07a6b8 100644 --- a/crates/hir_ty/src/types.rs +++ b/crates/hir_ty/src/types.rs @@ -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 { + 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)] diff --git a/crates/hir_ty/src/walk.rs b/crates/hir_ty/src/walk.rs index b85e6ab4d..963eb12c8 100644 --- a/crates/hir_ty/src/walk.rs +++ b/crates/hir_ty/src/walk.rs @@ -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) + } +} -- cgit v1.2.3