]> git.lizzy.rs Git - rust.git/commitdiff
Process second review
authorMarcus Klaas de Vries <mail@marcusklaas.nl>
Sun, 27 Jan 2019 16:59:09 +0000 (17:59 +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 [deleted file]
crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap [new file with mode: 0644]
crates/ra_hir/src/ty/tests.rs

index 00a71a42f5ecbc85cfba9fe9f9be8a6b6ad1e414..37715a903a4ebbda2d826767d5fe38b07c1495a5 100644 (file)
@@ -470,12 +470,12 @@ fn substs_from_path(
         }
         // add placeholders for args that were not provided
         // TODO: handle defaults
-        for _ in segment
+        let supplied_params = segment
             .args_and_bindings
             .as_ref()
             .map(|ga| ga.args.len())
-            .unwrap_or(0)..def_generics.params.len()
-        {
+            .unwrap_or(0);
+        for _ in supplied_params..def_generics.params.len() {
             substs.push(Ty::Unknown);
         }
         assert_eq!(substs.len(), def_generics.params.len());
@@ -507,7 +507,20 @@ fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
                 }
                 sig_mut.output.walk_mut(f);
             }
-            Ty::FnDef { substs, .. } | Ty::Adt { substs, .. } => {
+            Ty::FnDef { substs, sig, .. } => {
+                let sig_mut = Arc::make_mut(sig);
+                for input in &mut sig_mut.input {
+                    input.walk_mut(f);
+                }
+                sig_mut.output.walk_mut(f);
+                // Without an Arc::make_mut_slice, we can't avoid the clone here:
+                let mut v: Vec<_> = substs.0.iter().cloned().collect();
+                for t in &mut v {
+                    t.walk_mut(f);
+                }
+                substs.0 = v.into();
+            }
+            Ty::Adt { substs, .. } => {
                 // Without an Arc::make_mut_slice, we can't avoid the clone here:
                 let mut v: Vec<_> = substs.0.iter().cloned().collect();
                 for t in &mut v {
@@ -579,7 +592,7 @@ pub fn subst(self, substs: &Substs) -> Ty {
     /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
     fn substs(&self) -> Option<Substs> {
         match self {
-            Ty::Adt { substs, .. } => Some(substs.clone()),
+            Ty::Adt { substs, .. } | Ty::FnDef { substs, .. } => Some(substs.clone()),
             _ => None,
         }
     }
@@ -617,9 +630,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             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
                 write!(f, "fn {}", name)?;
                 if substs.0.len() > 0 {
                     join(substs.0.iter())
@@ -1156,33 +1166,18 @@ fn infer_path_expr(&mut self, expr: ExprId, path: &Path) -> Option<Ty> {
             .into();
         let typable = typable?;
         let ty = self.db.type_for_def(typable);
+        let generics = GenericParams::default();
+        let substs = Ty::substs_from_path(
+            self.db,
+            &self.module,
+            self.impl_block.as_ref(),
+            &generics,
+            path,
+            typable,
+        );
+        let ty = ty.apply_substs(substs);
         let ty = self.insert_type_vars(ty);
 
-        // try to get generic parameters from the path and add them to the
-        // function type substitutions
-        if let Ty::FnDef { ref def, .. } = ty {
-            let last_seg_bindings = path
-                .segments
-                .last()
-                .and_then(|segment| segment.args_and_bindings.as_ref());
-            if let Some(generic_args) = last_seg_bindings {
-                let generic_params = def.generic_params(self.db);
-                if generic_args.args.len() == generic_params.params.len() {
-                    let substs = Ty::substs_from_path(
-                        self.db,
-                        &self.module,
-                        self.impl_block.as_ref(),
-                        &generic_params,
-                        path,
-                        (*def).into(),
-                    );
-                    return Some(ty.apply_substs(substs));
-                } else {
-                    // ERROR: incorrect number of type params
-                }
-            }
-        }
-
         Some(ty)
     }
 
@@ -1408,8 +1403,6 @@ fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                 Ty::Unknown
             }
             Expr::Call { callee, args } => {
-                // TODO: we should use turbofish hints like this:
-                // f::<u32>(x)
                 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()),
diff --git a/crates/ra_hir/src/ty/snapshots/tests__generic_fn.snap b/crates/ra_hir/src/ty/snapshots/tests__generic_fn.snap
deleted file mode 100644 (file)
index 85aeefa..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
----
-created: "2019-01-26T18:16:16.568375+00:00"
-creator: insta@0.5.2
-expression: "&result"
-source: crates/ra_hir/src/ty/tests.rs
----
-[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; 197) '{     ...(1); }': ()
-[87; 88) 'y': u32
-[91; 96) '10u32': 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>(&T) -> T
-[127; 135) 'clone(z)': bool
-[133; 134) 'z': &bool
-[173; 191) 'id::<i...tring>': fn id<i32>(T) -> T
-[173; 194) 'id::<i...ng>(1)': i32
-[192; 193) '1': i32
-
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap
new file mode 100644 (file)
index 0000000..a993232
--- /dev/null
@@ -0,0 +1,26 @@
+---
+created: "2019-01-27T16:54:18.368427685+00:00"
+creator: insta@0.5.2
+expression: "&result"
+source: crates/ra_hir/src/ty/tests.rs
+---
+[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; 157) '{     ...(1); }': ()
+[87; 88) 'y': u32
+[91; 96) '10u32': 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>(&T) -> T
+[127; 135) 'clone(z)': bool
+[133; 134) 'z': &bool
+[141; 151) 'id::<i128>': fn id<i128>(T) -> T
+[141; 154) 'id::<i128>(1)': i128
+[152; 153) '1': i128
+
index fac56662649617c3639b6916643b43c9d9523194..ac12d974b89a0b94b5dc9b7b5e02921862b8bb42 100644 (file)
@@ -597,7 +597,7 @@ fn test() {
 #[test]
 fn infer_type_param() {
     check_inference(
-        "generic_fn",
+        "infer_type_param",
         r#"
 fn id<T>(x: T) -> T {
     x
@@ -611,9 +611,7 @@ fn test() {
     let y = 10u32;
     id(y);
     let x: bool = clone(z);
-
-    // bad turbofish - ignore!
-    id::<i128, String>(1);
+    id::<i128>(1);
 }
 "#,
     );