Add a FnSig to Ty::FnDef

This commit is contained in:
Marcus Klaas de Vries 2019-01-26 18:47:22 +01:00
parent 089b1c57c1
commit 0da1e8b2f8
7 changed files with 93 additions and 67 deletions

View File

@ -34,7 +34,7 @@
use crate::{
Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock,
FnScopes, ModuleDef, AdtDef,
FnSignature, FnScopes, ModuleDef, AdtDef,
db::HirDatabase,
type_ref::{TypeRef, Mutability},
name::KnownName,
@ -225,6 +225,8 @@ pub enum Ty {
def: Function,
/// For display
name: Name,
/// Parameters and return type
sig: Arc<FnSig>,
/// Substitutions for the generic parameters of the type
substs: Substs,
},
@ -544,7 +546,12 @@ pub fn apply_substs(self, substs: Substs) -> Ty {
name,
substs,
},
Ty::FnDef { def, name, .. } => Ty::FnDef { def, name, substs },
Ty::FnDef { def, name, sig, .. } => Ty::FnDef {
def,
name,
sig,
substs,
},
_ => self,
}
}
@ -607,7 +614,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
.to_fmt(f)?;
write!(f, " -> {}", sig.output)
}
Ty::FnDef { name, substs, .. } => {
Ty::FnDef {
name, substs, sig, ..
} => {
// don't have access to the param types here :-(
// we could store them in the def, but not sure if it
// is worth it
@ -618,7 +627,11 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
.separator(", ")
.to_fmt(f)?;
}
Ok(())
join(sig.input.iter())
.surround_with("(", ")")
.separator(", ")
.to_fmt(f)?;
write!(f, " -> {}", sig.output)
}
Ty::Adt { name, substs, .. } => {
write!(f, "{}", name)?;
@ -641,12 +654,29 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// Compute the declared type of a function. This should not need to look at the
/// function body.
fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty {
let generics = f.generic_params(db);
fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
let signature = def.signature(db);
let module = def.module(db);
let impl_block = def.impl_block(db);
let generics = def.generic_params(db);
let input = signature
.params()
.iter()
.map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), &generics, tr))
.collect::<Vec<_>>();
let output = Ty::from_hir(
db,
&module,
impl_block.as_ref(),
&generics,
signature.ret_type(),
);
let sig = Arc::new(FnSig { input, output });
let substs = make_substs(&generics);
let name = f.name(db);
let name = def.name(db);
Ty::FnDef {
def: f.into(),
def,
sig,
name,
substs,
}
@ -923,7 +953,9 @@ fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
self.type_of_pat.insert(pat, ty);
}
fn make_ty(&mut self, type_ref: &TypeRef, generics: &GenericParams) -> Ty {
fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
// TODO provide generics of function
let generics = GenericParams::default();
let ty = Ty::from_hir(
self.db,
&self.module,
@ -1337,7 +1369,7 @@ fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) {
let expected = if let Some(type_ref) = arg_type {
let ty = self.make_ty(type_ref, &GenericParams::default());
let ty = self.make_ty(type_ref);
ty
} else {
Ty::Unknown
@ -1355,16 +1387,14 @@ fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
let callee_ty = self.infer_expr(*callee, &Expectation::none());
let (param_tys, ret_ty) = match &callee_ty {
Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()),
Ty::FnDef { def, substs, .. } => {
let fn_sig = def.signature(self.db);
let generic_params = def.generic_params(self.db);
let ret_ty = self
.make_ty(fn_sig.ret_type(), &generic_params)
.subst(&substs);
let param_tys = fn_sig
.params()
Ty::FnDef {
def, substs, sig, ..
} => {
let ret_ty = sig.output.clone().subst(&substs);
let param_tys = sig
.input
.iter()
.map(|type_ref| self.make_ty(type_ref, &generic_params).subst(&substs))
.map(|ty| ty.clone().subst(&substs))
.collect();
(param_tys, ret_ty)
}
@ -1407,17 +1437,13 @@ fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
(Ty::Unknown, Vec::new(), sig.output.clone())
}
}
Ty::FnDef { def, substs, .. } => {
let fn_sig = def.signature(self.db);
let generic_params = def.generic_params(self.db);
let ret_ty = self
.make_ty(fn_sig.ret_type(), &generic_params)
.subst(&substs);
Ty::FnDef {
def, substs, sig, ..
} => {
let ret_ty = sig.output.clone().subst(&substs);
if fn_sig.params().len() > 0 {
let mut arg_iter = fn_sig.params().iter().map(|type_ref| {
self.make_ty(type_ref, &generic_params).subst(&substs)
});
if sig.input.len() > 0 {
let mut arg_iter = sig.input.iter().map(|ty| ty.clone().subst(&substs));
let receiver_ty = arg_iter.next().unwrap();
(receiver_ty, arg_iter.collect(), ret_ty)
} else {
@ -1515,7 +1541,7 @@ fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
}
Expr::Cast { expr, type_ref } => {
let _inner_ty = self.infer_expr(*expr, &Expectation::none());
let cast_ty = self.make_ty(type_ref, &GenericParams::default());
let cast_ty = self.make_ty(type_ref);
// TODO check the cast...
cast_ty
}
@ -1629,7 +1655,7 @@ fn infer_block(
} => {
let decl_ty = type_ref
.as_ref()
.map(|tr| self.make_ty(tr, &GenericParams::default()))
.map(|tr| self.make_ty(tr))
.unwrap_or(Ty::Unknown);
let decl_ty = self.insert_type_vars(decl_ty);
let ty = if let Some(expr) = initializer {
@ -1654,16 +1680,14 @@ fn infer_block(
ty
}
fn collect_fn_signature(&mut self, func: Function) {
fn collect_fn_signature(&mut self, signature: &FnSignature) {
let body = Arc::clone(&self.body); // avoid borrow checker problem
let signature = func.signature(self.db);
let generics = func.generic_params(self.db);
for (type_ref, pat) in signature.params().iter().zip(body.params()) {
let ty = self.make_ty(type_ref, &generics);
let ty = self.make_ty(type_ref);
self.infer_pat(*pat, &ty);
}
self.return_ty = self.make_ty(signature.ret_type(), &generics);
self.return_ty = self.make_ty(signature.ret_type());
}
fn infer_body(&mut self) {
@ -1682,7 +1706,9 @@ pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> {
let impl_block = func.impl_block(db);
let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block);
ctx.collect_fn_signature(func);
let signature = func.signature(db);
ctx.collect_fn_signature(&signature);
ctx.infer_body();
Arc::new(ctx.resolve_all())

View File

@ -1,23 +1,23 @@
---
created: "2019-01-25T23:18:55.019197432+00:00"
created: "2019-01-26T17:46:03.963745056+00:00"
creator: insta@0.5.2
expression: "&result"
source: crates/ra_hir/src/ty/tests.rs
---
[10; 11) 'x': T
[21; 30) '{ x }': T
[27; 28) 'x': T
[44; 45) 'x': &T
[56; 65) '{ x }': &T
[62; 63) 'x': &T
[10; 11) 'x': [unknown]
[21; 30) '{ x }': [unknown]
[27; 28) 'x': [unknown]
[44; 45) 'x': &[unknown]
[56; 65) '{ x }': &[unknown]
[62; 63) 'x': &[unknown]
[77; 138) '{ ...(z); }': ()
[87; 88) 'y': u32
[91; 96) '10u32': u32
[102; 104) 'id': fn id<u32>
[102; 104) 'id': fn id<u32>(T) -> T
[102; 107) 'id(y)': u32
[105; 106) 'y': u32
[117; 118) 'x': bool
[127; 132) 'clone': fn clone<bool>
[127; 132) 'clone': fn clone<bool>(&T) -> T
[127; 135) 'clone(z)': bool
[133; 134) 'z': &bool

View File

@ -1,5 +1,5 @@
---
created: "2019-01-25T23:18:54.943309491+00:00"
created: "2019-01-26T17:46:03.842478456+00:00"
creator: insta@0.5.2
expression: "&result"
source: crates/ra_hir/src/ty/tests.rs
@ -10,7 +10,7 @@ source: crates/ra_hir/src/ty/tests.rs
[88; 89) 'a': u32
[92; 108) 'unknow...nction': [unknown]
[92; 110) 'unknow...tion()': u32
[116; 125) 'takes_u32': fn takes_u32
[116; 125) 'takes_u32': fn takes_u32(u32) -> ()
[116; 128) 'takes_u32(a)': ()
[126; 127) 'a': u32
[138; 139) 'b': i32

View File

@ -1,5 +1,5 @@
---
created: "2019-01-25T23:18:54.949540810+00:00"
created: "2019-01-26T17:46:03.853259898+00:00"
creator: insta@0.5.2
expression: "&result"
source: crates/ra_hir/src/ty/tests.rs
@ -28,7 +28,7 @@ source: crates/ra_hir/src/ty/tests.rs
[174; 196) 'minus_...ONST_2': bool
[189; 196) 'CONST_2': isize
[206; 207) 'c': i32
[210; 211) 'f': fn f
[210; 211) 'f': fn f(bool) -> i32
[210; 219) 'f(z || y)': i32
[210; 223) 'f(z || y) + 5': i32
[212; 213) 'z': bool

View File

@ -1,21 +1,21 @@
---
created: "2019-01-25T23:18:54.962273460+00:00"
created: "2019-01-26T17:46:03.856278205+00:00"
creator: insta@0.5.2
expression: "&result"
source: crates/ra_hir/src/ty/tests.rs
---
[10; 11) 't': T
[21; 26) '{ t }': T
[23; 24) 't': T
[10; 11) 't': [unknown]
[21; 26) '{ t }': [unknown]
[23; 24) 't': [unknown]
[38; 98) '{ ...(1); }': ()
[44; 46) 'id': fn id<u32>
[44; 46) 'id': fn id<u32>(T) -> T
[44; 52) 'id(1u32)': u32
[47; 51) '1u32': u32
[58; 68) 'id::<i128>': fn id<i32>
[58; 68) 'id::<i128>': fn id<i32>(T) -> T
[58; 71) 'id::<i128>(1)': i32
[69; 70) '1': i32
[81; 82) 'x': u64
[90; 92) 'id': fn id<u64>
[90; 92) 'id': fn id<u64>(T) -> T
[90; 95) 'id(1)': u64
[93; 94) '1': u64

View File

@ -1,5 +1,5 @@
---
created: "2019-01-25T23:18:54.978506051+00:00"
created: "2019-01-26T17:46:03.866825843+00:00"
creator: insta@0.5.2
expression: "&result"
source: crates/ra_hir/src/ty/tests.rs
@ -8,23 +8,23 @@ source: crates/ra_hir/src/ty/tests.rs
[65; 87) '{ ... }': [unknown]
[75; 79) 'self': A<[unknown]>
[75; 81) 'self.x': [unknown]
[99; 100) 't': T
[110; 115) '{ t }': T
[112; 113) 't': T
[99; 100) 't': [unknown]
[110; 115) '{ t }': [unknown]
[112; 113) 't': [unknown]
[135; 261) '{ ....x() }': i128
[146; 147) 'x': i32
[150; 151) '1': i32
[162; 163) 'y': i32
[166; 168) 'id': fn id<i32>
[166; 168) 'id': fn id<i32>(T) -> T
[166; 171) 'id(x)': i32
[169; 170) 'x': i32
[182; 183) 'a': A<i32>
[186; 200) 'A { x: id(y) }': A<i32>
[193; 195) 'id': fn id<i32>
[193; 195) 'id': fn id<i32>(T) -> T
[193; 198) 'id(y)': i32
[196; 197) 'y': i32
[211; 212) 'z': i32
[215; 217) 'id': fn id<i32>
[215; 217) 'id': fn id<i32>(T) -> T
[215; 222) 'id(a.x)': i32
[218; 219) 'a': A<i32>
[218; 221) 'a.x': i32

View File

@ -1,5 +1,5 @@
---
created: "2019-01-25T23:18:54.985011010+00:00"
created: "2019-01-26T17:46:03.928773630+00:00"
creator: insta@0.5.2
expression: "&result"
source: crates/ra_hir/src/ty/tests.rs
@ -9,8 +9,8 @@ source: crates/ra_hir/src/ty/tests.rs
[48; 53) '{ 1 }': u32
[50; 51) '1': u32
[67; 91) '{ ...c(); }': ()
[73; 74) 'a': fn a
[73; 74) 'a': fn a() -> u32
[73; 76) 'a()': u32
[82; 86) 'b::c': fn c
[82; 86) 'b::c': fn c() -> u32
[82; 88) 'b::c()': u32