]> git.lizzy.rs Git - rust.git/commitdiff
Add a FnSig to Ty::FnDef
authorMarcus Klaas de Vries <mail@marcusklaas.nl>
Sat, 26 Jan 2019 17:47:22 +0000 (18:47 +0100)
committerMarcus Klaas de Vries <mail@marcusklaas.nl>
Sun, 27 Jan 2019 16:59:21 +0000 (17:59 +0100)
crates/ra_hir/src/ty.rs
crates/ra_hir/src/ty/snapshots/tests__generic_fn.snap
crates/ra_hir/src/ty/snapshots/tests__infer_backwards.snap
crates/ra_hir/src/ty/snapshots/tests__infer_binary_op.snap
crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap
crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap
crates/ra_hir/src/ty/snapshots/tests__infer_paths.snap

index 3cf3eaded45b3123794f7c30e2bce853706b2c0e..9332aca9a48653a6461865dce91224b1abb7e482 100644 (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);
-
-                        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 @@ 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())
index 4436dd8aa26ff4846035d0e7d879d2fba81db2d7..84fbe6e4c5989c9582b731741229a694360806df 100644 (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
 
index e6b39f1510dced88f9df3c85b8a5ab7a94fba991..f5840a934748e8c244010bed30ae39c2a0bd0799 100644 (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
index 895c13ae60beff479786ddfbe8f637407099351b..b9dda2bc073cafb2045e8b9abb3e7393fceee114 100644 (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
index efe0e7adf9faff0d323114f2e2851f8b83569f57..369705f84ccedc0b7cce507035a9ae1fbd0a8f37 100644 (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
 
index aaf8ccea58e242a37a82c744bf11102e3e82e49a..f21bffa75450b20cf4f9ad263fd3187f645cefc9 100644 (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
index efca360587563f899bb99ea50b48ffb888c24602..afbe2f747aabf9b1ab1d3d6d0052d7b1453ba989 100644 (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