From 0da1e8b2f8709cbdb20912664878121d979a5213 Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Sat, 26 Jan 2019 18:47:22 +0100 Subject: Add a FnSig to Ty::FnDef --- crates/ra_hir/src/ty.rs | 102 +++++++++++++-------- .../ra_hir/src/ty/snapshots/tests__generic_fn.snap | 18 ++-- .../src/ty/snapshots/tests__infer_backwards.snap | 4 +- .../src/ty/snapshots/tests__infer_binary_op.snap | 4 +- .../snapshots/tests__infer_function_generics.snap | 14 +-- .../ty/snapshots/tests__infer_generic_chain.snap | 14 +-- .../src/ty/snapshots/tests__infer_paths.snap | 6 +- 7 files changed, 94 insertions(+), 68 deletions(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 3cf3eaded..9332aca9a 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -34,7 +34,7 @@ use test_utils::tested_by; 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, /// Substitutions for the generic parameters of the type substs: Substs, }, @@ -544,7 +546,12 @@ impl 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 @@ impl fmt::Display for Ty { .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 @@ impl fmt::Display for Ty { .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 @@ impl fmt::Display for Ty { /// 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::>(); + 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 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { 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 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { 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 @@ 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.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 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { (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); - - 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) - }); + Ty::FnDef { + def, substs, sig, .. + } => { + let ret_ty = sig.output.clone().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 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } 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 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } => { 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 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { 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 { 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()) diff --git a/crates/ra_hir/src/ty/snapshots/tests__generic_fn.snap b/crates/ra_hir/src/ty/snapshots/tests__generic_fn.snap index 4436dd8aa..84fbe6e4c 100644 --- a/crates/ra_hir/src/ty/snapshots/tests__generic_fn.snap +++ b/crates/ra_hir/src/ty/snapshots/tests__generic_fn.snap @@ -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 +[102; 104) 'id': fn id(T) -> T [102; 107) 'id(y)': u32 [105; 106) 'y': u32 [117; 118) 'x': bool -[127; 132) 'clone': fn clone +[127; 132) 'clone': fn clone(&T) -> T [127; 135) 'clone(z)': bool [133; 134) 'z': &bool diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_backwards.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_backwards.snap index e6b39f151..f5840a934 100644 --- a/crates/ra_hir/src/ty/snapshots/tests__infer_backwards.snap +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_backwards.snap @@ -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 diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_binary_op.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_binary_op.snap index 895c13ae6..b9dda2bc0 100644 --- a/crates/ra_hir/src/ty/snapshots/tests__infer_binary_op.snap +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_binary_op.snap @@ -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 diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap index efe0e7adf..369705f84 100644 --- a/crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap @@ -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 +[44; 46) 'id': fn id(T) -> T [44; 52) 'id(1u32)': u32 [47; 51) '1u32': u32 -[58; 68) 'id::': fn id +[58; 68) 'id::': fn id(T) -> T [58; 71) 'id::(1)': i32 [69; 70) '1': i32 [81; 82) 'x': u64 -[90; 92) 'id': fn id +[90; 92) 'id': fn id(T) -> T [90; 95) 'id(1)': u64 [93; 94) '1': u64 diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap index aaf8ccea5..f21bffa75 100644 --- a/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap @@ -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 +[166; 168) 'id': fn id(T) -> T [166; 171) 'id(x)': i32 [169; 170) 'x': i32 [182; 183) 'a': A [186; 200) 'A { x: id(y) }': A -[193; 195) 'id': fn id +[193; 195) 'id': fn id(T) -> T [193; 198) 'id(y)': i32 [196; 197) 'y': i32 [211; 212) 'z': i32 -[215; 217) 'id': fn id +[215; 217) 'id': fn id(T) -> T [215; 222) 'id(a.x)': i32 [218; 219) 'a': A [218; 221) 'a.x': i32 diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_paths.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_paths.snap index efca36058..afbe2f747 100644 --- a/crates/ra_hir/src/ty/snapshots/tests__infer_paths.snap +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_paths.snap @@ -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 -- cgit v1.2.3