From 88e22e9d70ac3a35989ad1d45386f86697877c4c Mon Sep 17 00:00:00 2001 From: Lenard Pratt Date: Sat, 30 Mar 2019 11:17:31 +0000 Subject: Added const bodies and static body to the ast and added inference the inference test reduce code duplication --- crates/ra_hir/src/ty/infer.rs | 20 +++++++++----- crates/ra_hir/src/ty/tests.rs | 61 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 10 deletions(-) (limited to 'crates/ra_hir/src/ty') diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 573115321..887153484 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -27,8 +27,9 @@ use test_utils::tested_by; use crate::{ Function, StructField, Path, Name, - FnSignature, AdtDef, + FnSignature, AdtDef,ConstSignature, HirDatabase, + DefWithBody, ImplItem, type_ref::{TypeRef, Mutability}, expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self}, @@ -43,14 +44,17 @@ use crate::{ use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor}; /// The entry point of type inference. -pub fn infer(db: &impl HirDatabase, func: Function) -> Arc { +pub fn infer(db: &impl HirDatabase, def: DefWithBody) -> Arc { db.check_canceled(); - let body = func.body(db); - let resolver = func.resolver(db); + let body = def.body(db); + let resolver = def.resolver(db); let mut ctx = InferenceContext::new(db, body, resolver); - let signature = func.signature(db); - ctx.collect_fn_signature(&signature); + match def { + DefWithBody::Const(ref c) => ctx.collect_const_signature(&c.signature(db)), + DefWithBody::Function(ref f) => ctx.collect_fn_signature(&f.signature(db)), + DefWithBody::Static(ref s) => ctx.collect_const_signature(&s.signature(db)), + } ctx.infer_body(); @@ -1142,6 +1146,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { ty } + fn collect_const_signature(&mut self, signature: &ConstSignature) { + self.return_ty = self.make_ty(signature.type_ref()); + } + fn collect_fn_signature(&mut self, signature: &FnSignature) { let body = Arc::clone(&self.body); // avoid borrow checker problem for (type_ref, pat) in signature.params().iter().zip(body.params()) { diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 655f3c522..1e84e2d06 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -11,6 +11,8 @@ use crate::{ source_binder, mock::MockDatabase, ty::display::HirDisplay, + ty::InferenceResult, + expr::BodySourceMap }; // These tests compare the inference results for all expressions in a file @@ -1267,6 +1269,9 @@ fn test() { } "#), @r###" +[52; 53) '1': u32 +[103; 104) '2': u32 +[211; 212) '5': u32 [227; 305) '{ ...:ID; }': () [237; 238) 'x': u32 [241; 252) 'Struct::FOO': u32 @@ -1855,6 +1860,9 @@ fn test() { } "#), @r###" +[49; 50) '0': u32 +[80; 83) '101': u32 +[126; 128) '99': u32 [95; 213) '{ ...NST; }': () [138; 139) 'x': {unknown} [142; 153) 'LOCAL_CONST': {unknown} @@ -1881,6 +1889,10 @@ fn test() { } "#), @r###" +[29; 32) '101': u32 +[70; 73) '101': u32 +[118; 120) '99': u32 +[161; 163) '99': u32 [85; 280) '{ ...MUT; }': () [173; 174) 'x': {unknown} [177; 189) 'LOCAL_STATIC': {unknown} @@ -2212,6 +2224,24 @@ fn test>() { ); } +#[test] +fn infer_const_body() { + assert_snapshot_matches!( + infer(r#" +const A: u32 = 1 + 1; +static B: u64 = { let x = 1; x }; +"#), + @r###" +[16; 17) '1': u32 +[16; 21) '1 + 1': u32 +[20; 21) '1': u32 +[39; 55) '{ let ...1; x }': u64 +[45; 46) 'x': u64 +[49; 50) '1': u64 +[52; 53) 'x': u64"### + ); +} + fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { let func = source_binder::function_from_position(db, pos).unwrap(); let body_source_map = func.body_source_map(db); @@ -2228,11 +2258,11 @@ fn infer(content: &str) -> String { let source_file = db.parse(file_id); let mut acc = String::new(); acc.push_str("\n"); - for fn_def in source_file.syntax().descendants().filter_map(ast::FnDef::cast) { - let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap(); - let inference_result = func.infer(&db); - let body_source_map = func.body_source_map(&db); + + let mut infer_def = |inference_result: Arc, + body_source_map: Arc| { let mut types = Vec::new(); + for (pat, ty) in inference_result.type_of_pat.iter() { let syntax_ptr = match body_source_map.pat_syntax(pat) { Some(sp) => sp, @@ -2240,6 +2270,7 @@ fn infer(content: &str) -> String { }; types.push((syntax_ptr, ty)); } + for (expr, ty) in inference_result.type_of_expr.iter() { let syntax_ptr = match body_source_map.expr_syntax(expr) { Some(sp) => sp, @@ -2260,7 +2291,29 @@ fn infer(content: &str) -> String { ) .unwrap(); } + }; + + for const_def in source_file.syntax().descendants().filter_map(ast::ConstDef::cast) { + let konst = source_binder::const_from_source(&db, file_id, const_def).unwrap(); + let inference_result = konst.infer(&db); + let body_source_map = konst.body_source_map(&db); + infer_def(inference_result, body_source_map) } + + for static_def in source_file.syntax().descendants().filter_map(ast::StaticDef::cast) { + let static_ = source_binder::static_from_source(&db, file_id, static_def).unwrap(); + let inference_result = static_.infer(&db); + let body_source_map = static_.body_source_map(&db); + infer_def(inference_result, body_source_map) + } + + for fn_def in source_file.syntax().descendants().filter_map(ast::FnDef::cast) { + let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap(); + let inference_result = func.infer(&db); + let body_source_map = func.body_source_map(&db); + infer_def(inference_result, body_source_map) + } + acc.truncate(acc.trim_end().len()); acc } -- cgit v1.2.3