Skip to content

Commit

Permalink
Merge #7816
Browse files Browse the repository at this point in the history
7816: Lift Ty::Fn into a struct r=Veykril a=Veykril

bors r+

Co-authored-by: Lukas Wirth <[email protected]>
  • Loading branch information
bors[bot] and Veykril authored Feb 28, 2021
2 parents 72457d0 + 407196b commit 5df3ee8
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 86 deletions.
10 changes: 5 additions & 5 deletions crates/hir/src/code_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ use hir_ty::{
display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter},
method_resolution,
traits::{FnTrait, Solution, SolutionVariables},
BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, InEnvironment,
Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, Ty, TyDefId,
TyKind,
BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment,
Ty, TyDefId, TyKind,
};
use rustc_hash::FxHashSet;
use stdx::{format_to, impl_from};
Expand Down Expand Up @@ -1692,7 +1692,7 @@ impl Type {
}

pub fn is_fn(&self) -> bool {
matches!(&self.ty.value, Ty::FnDef(..) | Ty::FnPtr { .. })
matches!(&self.ty.value, Ty::FnDef(..) | Ty::Function { .. })
}

pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
Expand Down Expand Up @@ -1974,7 +1974,7 @@ impl HirDisplay for Type {
#[derive(Debug)]
pub struct Callable {
ty: Type,
sig: FnSig,
sig: CallableSig,
def: Option<CallableDefId>,
pub(crate) is_bound_method: bool,
}
Expand Down
12 changes: 6 additions & 6 deletions crates/hir_ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
use std::{borrow::Cow, fmt};

use crate::{
db::HirDatabase, primitive, utils::generics, CallableDefId, FnSig, GenericPredicate, Lifetime,
Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, TraitRef, Ty,
db::HirDatabase, primitive, utils::generics, CallableDefId, CallableSig, GenericPredicate,
Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, TraitRef, Ty,
};
use arrayvec::ArrayVec;
use hir_def::{
Expand Down Expand Up @@ -341,8 +341,8 @@ impl HirDisplay for Ty {
write!(f, ")")?;
}
}
Ty::FnPtr { is_varargs, substs, .. } => {
let sig = FnSig::from_fn_ptr_substs(&substs, *is_varargs);
Ty::Function(fn_ptr) => {
let sig = CallableSig::from_fn_ptr(fn_ptr);
sig.hir_fmt(f)?;
}
Ty::FnDef(def, parameters) => {
Expand Down Expand Up @@ -494,7 +494,7 @@ impl HirDisplay for Ty {
}
}
}
Ty::Closure { substs, .. } => {
Ty::Closure(.., substs) => {
let sig = substs[0].callable_sig(f.db);
if let Some(sig) = sig {
if sig.params().is_empty() {
Expand Down Expand Up @@ -571,7 +571,7 @@ impl HirDisplay for Ty {
}
}

impl HirDisplay for FnSig {
impl HirDisplay for CallableSig {
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
write!(f, "fn(")?;
f.write_joined(self.params(), ", ")?;
Expand Down
4 changes: 2 additions & 2 deletions crates/hir_ty/src/infer/coerce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,14 @@ impl<'a> InferenceContext<'a> {
| (Ty::Ref(Mutability::Shared, ..), Ty::Ref(Mutability::Mut, ..)) => return false,

// `{function_type}` -> `fn()`
(Ty::FnDef(..), Ty::FnPtr { .. }) => match from_ty.callable_sig(self.db) {
(Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) {
None => return false,
Some(sig) => {
from_ty = Ty::fn_ptr(sig);
}
},

(Ty::Closure { substs, .. }, Ty::FnPtr { .. }) => {
(Ty::Closure(.., substs), Ty::Function { .. }) => {
from_ty = substs[0].clone();
}

Expand Down
15 changes: 7 additions & 8 deletions crates/hir_ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use crate::{
primitive::{self, UintTy},
traits::{FnTrait, InEnvironment},
utils::{generics, variant_data, Generics},
Binders, CallableDefId, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, Scalar, Substs,
TraitRef, Ty,
Binders, CallableDefId, FnPointer, FnSig, InferTy, Mutability, Obligation, OpaqueTyId, Rawness,
Scalar, Substs, TraitRef, Ty,
};

use super::{
Expand Down Expand Up @@ -247,13 +247,12 @@ impl<'a> InferenceContext<'a> {
None => self.table.new_type_var(),
};
sig_tys.push(ret_ty.clone());
let sig_ty = Ty::FnPtr {
num_args: sig_tys.len() as u16 - 1,
is_varargs: false,
let sig_ty = Ty::Function(FnPointer {
num_args: sig_tys.len() - 1,
sig: FnSig { variadic: false },
substs: Substs(sig_tys.clone().into()),
};
let closure_ty =
Ty::Closure { def: self.owner, expr: tgt_expr, substs: Substs::single(sig_ty) };
});
let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty));

// Eagerly try to relate the closure type with the expected
// type, otherwise we often won't have enough information to
Expand Down
80 changes: 48 additions & 32 deletions crates/hir_ty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ impl TypeWalk for ProjectionTy {
}
}

#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub struct FnSig {
pub variadic: bool,
}

#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct FnPointer {
pub num_args: usize,
pub sig: FnSig,
pub substs: Substs,
}

/// A type.
///
/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
Expand Down Expand Up @@ -166,7 +178,7 @@ pub enum Ty {
///
/// The closure signature is stored in a `FnPtr` type in the first type
/// parameter.
Closure { def: DefWithBodyId, expr: ExprId, substs: Substs },
Closure(DefWithBodyId, ExprId, Substs),

/// Represents a foreign type declared in external blocks.
ForeignType(TypeAliasId),
Expand All @@ -179,8 +191,7 @@ pub enum Ty {
/// fn foo() -> i32 { 1 }
/// let bar: fn() -> i32 = foo;
/// ```
// FIXME make this a Ty variant like in Chalk
FnPtr { num_args: u16, is_varargs: bool, substs: Substs },
Function(FnPointer),

/// A "projection" type corresponds to an (unnormalized)
/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
Expand Down Expand Up @@ -535,22 +546,29 @@ pub enum TyKind {
/// A function signature as seen by type inference: Several parameter types and
/// one return type.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct FnSig {
pub struct CallableSig {
params_and_return: Arc<[Ty]>,
is_varargs: bool,
}

/// A polymorphic function signature.
pub type PolyFnSig = Binders<FnSig>;
pub type PolyFnSig = Binders<CallableSig>;

impl FnSig {
pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> FnSig {
impl CallableSig {
pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> CallableSig {
params.push(ret);
FnSig { params_and_return: params.into(), is_varargs }
CallableSig { params_and_return: params.into(), is_varargs }
}

pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
CallableSig {
params_and_return: Arc::clone(&fn_ptr.substs.0),
is_varargs: fn_ptr.sig.variadic,
}
}

pub fn from_fn_ptr_substs(substs: &Substs, is_varargs: bool) -> FnSig {
FnSig { params_and_return: Arc::clone(&substs.0), is_varargs }
pub fn from_substs(substs: &Substs) -> CallableSig {
CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false }
}

pub fn params(&self) -> &[Ty] {
Expand All @@ -562,7 +580,7 @@ impl FnSig {
}
}

impl TypeWalk for FnSig {
impl TypeWalk for CallableSig {
fn walk(&self, f: &mut impl FnMut(&Ty)) {
for t in self.params_and_return.iter() {
t.walk(f);
Expand All @@ -585,12 +603,12 @@ impl Ty {
Ty::Tuple(0, Substs::empty())
}

pub fn fn_ptr(sig: FnSig) -> Self {
Ty::FnPtr {
num_args: sig.params().len() as u16,
is_varargs: sig.is_varargs,
pub fn fn_ptr(sig: CallableSig) -> Self {
Ty::Function(FnPointer {
num_args: sig.params().len(),
sig: FnSig { variadic: sig.is_varargs },
substs: Substs(sig.params_and_return),
}
})
}

pub fn builtin(builtin: BuiltinType) -> Self {
Expand Down Expand Up @@ -673,17 +691,17 @@ impl Ty {
(Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
(Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..))
| (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2,
(Ty::Closure { def, expr, .. }, Ty::Closure { def: def2, expr: expr2, .. }) => {
(Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => {
expr == expr2 && def == def2
}
(Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..))
| (Ty::RawPtr(mutability, ..), Ty::RawPtr(mutability2, ..)) => {
mutability == mutability2
}
(
Ty::FnPtr { num_args, is_varargs, .. },
Ty::FnPtr { num_args: num_args2, is_varargs: is_varargs2, .. },
) => num_args == num_args2 && is_varargs == is_varargs2,
Ty::Function(FnPointer { num_args, sig, .. }),
Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
) => num_args == num_args2 && sig == sig2,
(Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2,
(Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true,
(Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2,
Expand Down Expand Up @@ -722,17 +740,15 @@ impl Ty {
}
}

pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> {
pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
match self {
Ty::FnPtr { is_varargs, substs: parameters, .. } => {
Some(FnSig::from_fn_ptr_substs(&parameters, *is_varargs))
}
Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
Ty::FnDef(def, parameters) => {
let sig = db.callable_item_signature(*def);
Some(sig.subst(&parameters))
}
Ty::Closure { substs: parameters, .. } => {
let sig_param = &parameters[0];
Ty::Closure(.., substs) => {
let sig_param = &substs[0];
sig_param.callable_sig(db)
}
_ => None,
Expand All @@ -751,11 +767,11 @@ impl Ty {
| Ty::RawPtr(_, substs)
| Ty::Ref(_, substs)
| Ty::FnDef(_, substs)
| Ty::FnPtr { substs, .. }
| Ty::Function(FnPointer { substs, .. })
| Ty::Tuple(_, substs)
| Ty::OpaqueType(_, substs)
| Ty::AssociatedType(_, substs)
| Ty::Closure { substs, .. } => {
| Ty::Closure(.., substs) => {
assert_eq!(substs.len(), new_substs.len());
*substs = new_substs;
}
Expand All @@ -774,11 +790,11 @@ impl Ty {
| Ty::RawPtr(_, substs)
| Ty::Ref(_, substs)
| Ty::FnDef(_, substs)
| Ty::FnPtr { substs, .. }
| Ty::Function(FnPointer { substs, .. })
| Ty::Tuple(_, substs)
| Ty::OpaqueType(_, substs)
| Ty::AssociatedType(_, substs)
| Ty::Closure { substs, .. } => Some(substs),
| Ty::Closure(.., substs) => Some(substs),
_ => None,
}
}
Expand All @@ -791,11 +807,11 @@ impl Ty {
| Ty::RawPtr(_, substs)
| Ty::Ref(_, substs)
| Ty::FnDef(_, substs)
| Ty::FnPtr { substs, .. }
| Ty::Function(FnPointer { substs, .. })
| Ty::Tuple(_, substs)
| Ty::OpaqueType(_, substs)
| Ty::AssociatedType(_, substs)
| Ty::Closure { substs, .. } => Some(substs),
| Ty::Closure(.., substs) => Some(substs),
_ => None,
}
}
Expand Down
20 changes: 12 additions & 8 deletions crates/hir_ty/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ use crate::{
all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
make_mut_slice, variant_data,
},
Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, OpaqueTy, OpaqueTyId, PolyFnSig,
ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substs,
TraitEnvironment, TraitRef, Ty, TypeWalk,
Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, OpaqueTy,
OpaqueTyId, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk,
};

#[derive(Debug)]
Expand Down Expand Up @@ -173,8 +173,12 @@ impl Ty {
}
TypeRef::Placeholder => Ty::Unknown,
TypeRef::Fn(params, is_varargs) => {
let sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect());
Ty::FnPtr { num_args: sig.len() as u16 - 1, is_varargs: *is_varargs, substs: sig }
let substs = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect());
Ty::Function(FnPointer {
num_args: substs.len() - 1,
sig: FnSig { variadic: *is_varargs },
substs,
})
}
TypeRef::DynTrait(bounds) => {
let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
Expand Down Expand Up @@ -1010,7 +1014,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
let ret = Ty::from_hir(&ctx_ret, &data.ret_type);
let generics = generics(db.upcast(), def.into());
let num_binders = generics.len();
Binders::new(num_binders, FnSig::from_params_and_return(params, ret, data.is_varargs))
Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs))
}

/// Build the declared type of a function. This should not need to look at the
Expand Down Expand Up @@ -1050,7 +1054,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
let params =
fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
let ret = type_for_adt(db, def.into());
Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false))
Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
}

/// Build the type of a tuple struct constructor.
Expand All @@ -1074,7 +1078,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
let params =
fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
let ret = type_for_adt(db, def.parent.into());
Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false))
Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
}

/// Build the type of a tuple enum variant constructor.
Expand Down
10 changes: 4 additions & 6 deletions crates/hir_ty/src/method_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use crate::{
db::HirDatabase,
primitive::{self, FloatTy, IntTy, UintTy},
utils::all_super_traits,
Canonical, DebruijnIndex, InEnvironment, Scalar, Substs, TraitEnvironment, TraitRef, Ty,
TyKind, TypeWalk,
Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, TraitEnvironment,
TraitRef, Ty, TyKind, TypeWalk,
};

/// This is used as a key for indexing impls.
Expand All @@ -35,7 +35,7 @@ pub enum TyFingerprint {
Dyn(TraitId),
Tuple(usize),
ForeignType(TypeAliasId),
FnPtr { num_args: u16, is_varargs: bool },
FnPtr(usize, FnSig),
}

impl TyFingerprint {
Expand All @@ -53,9 +53,7 @@ impl TyFingerprint {
&Ty::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality),
&Ty::RawPtr(mutability, ..) => TyFingerprint::RawPtr(mutability),
&Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id),
&Ty::FnPtr { num_args, is_varargs, .. } => {
TyFingerprint::FnPtr { num_args, is_varargs }
}
&Ty::Function(FnPointer { num_args, sig, .. }) => TyFingerprint::FnPtr(num_args, sig),
Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
_ => return None,
};
Expand Down
Loading

0 comments on commit 5df3ee8

Please sign in to comment.