Add a FnSig to Ty::FnDef
This commit is contained in:
parent
089b1c57c1
commit
0da1e8b2f8
@ -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())
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user