From 6249989e6c133792ff457896d4723c0eb0f42137 Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Sun, 27 Jan 2019 17:59:09 +0100 Subject: Process second review --- crates/ra_hir/src/ty.rs | 63 ++++++++++------------ .../ra_hir/src/ty/snapshots/tests__generic_fn.snap | 26 --------- .../src/ty/snapshots/tests__infer_type_param.snap | 26 +++++++++ crates/ra_hir/src/ty/tests.rs | 6 +-- 4 files changed, 56 insertions(+), 65 deletions(-) delete mode 100644 crates/ra_hir/src/ty/snapshots/tests__generic_fn.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 00a71a42f..37715a903 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -470,12 +470,12 @@ impl Ty { } // 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 @@ impl 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 @@ impl Ty { /// or function); so if `self` is `Option`, this returns the `u32`. fn substs(&self) -> Option { match self { - Ty::Adt { substs, .. } => Some(substs.clone()), + Ty::Adt { substs, .. } | Ty::FnDef { substs, .. } => Some(substs.clone()), _ => None, } } @@ -617,9 +630,6 @@ impl fmt::Display for Ty { 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 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { .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 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Ty::Unknown } Expr::Call { callee, args } => { - // TODO: we should use turbofish hints like this: - // f::(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 index 85aeefa0c..000000000 --- a/crates/ra_hir/src/ty/snapshots/tests__generic_fn.snap +++ /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(T) -> T -[102; 107) 'id(y)': u32 -[105; 106) 'y': u32 -[117; 118) 'x': bool -[127; 132) 'clone': fn clone(&T) -> T -[127; 135) 'clone(z)': bool -[133; 134) 'z': &bool -[173; 191) 'id::': fn id(T) -> T -[173; 194) 'id::(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 index 000000000..a99323264 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap @@ -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(T) -> T +[102; 107) 'id(y)': u32 +[105; 106) 'y': u32 +[117; 118) 'x': bool +[127; 132) 'clone': fn clone(&T) -> T +[127; 135) 'clone(z)': bool +[133; 134) 'z': &bool +[141; 151) 'id::': fn id(T) -> T +[141; 154) 'id::(1)': i128 +[152; 153) '1': i128 + diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index fac566626..ac12d974b 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -597,7 +597,7 @@ fn test() { #[test] fn infer_type_param() { check_inference( - "generic_fn", + "infer_type_param", r#" fn id(x: T) -> T { x @@ -611,9 +611,7 @@ fn test() { let y = 10u32; id(y); let x: bool = clone(z); - - // bad turbofish - ignore! - id::(1); + id::(1); } "#, ); -- cgit v1.2.3