Remove FnSig from FnDef type

It doesn't need to be in there since it's just information from the def. Another
step towards aligning Ty with Chalk's representation.
This commit is contained in:
Florian Diebold 2019-03-16 17:29:55 +01:00
parent a9ddaba905
commit 7faae12311
4 changed files with 26 additions and 21 deletions

View File

@ -12,7 +12,7 @@ use crate::{
macros::MacroExpansion,
module_tree::ModuleTree,
nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}},
ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef},
ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, CallableDef, FnSig},
adt::{StructData, EnumData},
impl_block::{ModuleImplBlocks, ImplSourceMap},
generics::{GenericParams, GenericDef},
@ -105,6 +105,9 @@ pub trait HirDatabase: PersistentHirDatabase {
#[salsa::invoke(crate::ty::type_for_field)]
fn type_for_field(&self, field: StructField) -> Ty;
#[salsa::invoke(crate::ty::callable_item_sig)]
fn callable_item_signature(&self, def: CallableDef) -> FnSig;
#[salsa::invoke(crate::expr::body_with_source_map_query)]
fn body_with_source_map(
&self,

View File

@ -16,7 +16,7 @@ use std::{fmt, mem};
use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase};
pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field};
pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field, callable_item_sig};
pub(crate) use infer::{infer, InferenceResult, InferTy};
use display::{HirDisplay, HirFormatter};
@ -77,8 +77,6 @@ pub enum Ty {
FnDef {
/// The definition of the function / constructor.
def: CallableDef,
/// Parameters and return type
sig: FnSig,
/// Substitutions for the generic parameters of the type
substs: Substs,
},
@ -189,11 +187,7 @@ impl Ty {
}
sig.ret().walk(f);
}
Ty::FnDef { substs, sig, .. } => {
for input in sig.params() {
input.walk(f);
}
sig.ret().walk(f);
Ty::FnDef { substs, .. } => {
for t in substs.0.iter() {
t.walk(f);
}
@ -232,8 +226,7 @@ impl Ty {
Ty::FnPtr(sig) => {
sig.walk_mut(f);
}
Ty::FnDef { substs, sig, .. } => {
sig.walk_mut(f);
Ty::FnDef { substs, .. } => {
substs.walk_mut(f);
}
Ty::Adt { substs, .. } => {
@ -275,7 +268,7 @@ impl Ty {
pub fn apply_substs(self, substs: Substs) -> Ty {
match self {
Ty::Adt { def_id, .. } => Ty::Adt { def_id, substs },
Ty::FnDef { def, sig, .. } => Ty::FnDef { def, sig, substs },
Ty::FnDef { def, .. } => Ty::FnDef { def, substs },
_ => self,
}
}
@ -344,7 +337,8 @@ impl HirDisplay for Ty {
f.write_joined(sig.params(), ", ")?;
write!(f, ") -> {}", sig.ret().display(f.db))?;
}
Ty::FnDef { def, substs, sig, .. } => {
Ty::FnDef { def, substs, .. } => {
let sig = f.db.callable_item_signature(*def);
let name = match def {
CallableDef::Function(ff) => ff.name(f.db),
CallableDef::Struct(s) => s.name(f.db).unwrap_or_else(Name::missing),

View File

@ -725,7 +725,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
let callee_ty = self.infer_expr(*callee, &Expectation::none());
let (param_tys, ret_ty) = match &callee_ty {
Ty::FnPtr(sig) => (sig.params().to_vec(), sig.ret().clone()),
Ty::FnDef { substs, sig, .. } => {
Ty::FnDef { substs, def, .. } => {
let sig = self.db.callable_item_signature(*def);
let ret_ty = sig.ret().clone().subst(&substs);
let param_tys =
sig.params().iter().map(|ty| ty.clone().subst(&substs)).collect();
@ -768,7 +769,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
(Ty::Unknown, Vec::new(), sig.ret().clone())
}
}
Ty::FnDef { substs, sig, .. } => {
Ty::FnDef { substs, def, .. } => {
let sig = self.db.callable_item_signature(*def);
let ret_ty = sig.ret().clone().subst(&substs);
if !sig.params().is_empty() {

View File

@ -212,6 +212,15 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace
}
}
/// Build the signature of a callable item (function, struct or enum variant).
pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig {
match def {
CallableDef::Function(f) => fn_sig_for_fn(db, f),
CallableDef::Struct(s) => fn_sig_for_struct_constructor(db, s),
CallableDef::EnumVariant(e) => fn_sig_for_enum_variant_constructor(db, e),
}
}
/// Build the type of a specific field of a struct or enum variant.
pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
let parent_def = field.parent_def(db);
@ -236,10 +245,9 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
/// Build the declared type of a function. This should not need to look at the
/// function body.
fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
let sig = fn_sig_for_fn(db, def);
let generics = def.generic_params(db);
let substs = make_substs(&generics);
Ty::FnDef { def: def.into(), sig, substs }
Ty::FnDef { def: def.into(), substs }
}
/// Build the declared type of a const.
@ -279,10 +287,9 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
if var_data.fields().is_none() {
return type_for_struct(db, def); // Unit struct
}
let sig = fn_sig_for_struct_constructor(db, def);
let generics = def.generic_params(db);
let substs = make_substs(&generics);
Ty::FnDef { def: def.into(), sig, substs }
Ty::FnDef { def: def.into(), substs }
}
fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig {
@ -308,10 +315,9 @@ fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) ->
if var_data.fields().is_none() {
return type_for_enum(db, def.parent_enum(db)); // Unit variant
}
let sig = fn_sig_for_enum_variant_constructor(db, def);
let generics = def.parent_enum(db).generic_params(db);
let substs = make_substs(&generics);
Ty::FnDef { def: def.into(), sig, substs }
Ty::FnDef { def: def.into(), substs }
}
fn make_substs(generics: &GenericParams) -> Substs {