diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_cli/src/analysis_stats.rs | 37 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 49 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model/src.rs | 30 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/ptr.rs | 5 |
7 files changed, 110 insertions, 27 deletions
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index 7e7e6c073..d355fa2e8 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; | 1 | use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; |
2 | 2 | ||
3 | use ra_db::SourceDatabase; | 3 | use ra_db::SourceDatabase; |
4 | use ra_hir::{Crate, HasSource, ImplItem, ModuleDef, Ty}; | 4 | use ra_hir::{Crate, HasBodySource, HasSource, HirDisplay, ImplItem, ModuleDef, Ty}; |
5 | use ra_syntax::AstNode; | 5 | use ra_syntax::AstNode; |
6 | 6 | ||
7 | use crate::Result; | 7 | use crate::Result; |
@@ -66,6 +66,7 @@ pub fn run(verbose: bool, memory_usage: bool, path: &Path, only: Option<&str>) - | |||
66 | let mut num_exprs = 0; | 66 | let mut num_exprs = 0; |
67 | let mut num_exprs_unknown = 0; | 67 | let mut num_exprs_unknown = 0; |
68 | let mut num_exprs_partially_unknown = 0; | 68 | let mut num_exprs_partially_unknown = 0; |
69 | let mut num_type_mismatches = 0; | ||
69 | for f in funcs { | 70 | for f in funcs { |
70 | let name = f.name(db); | 71 | let name = f.name(db); |
71 | let mut msg = format!("processing: {}", name); | 72 | let mut msg = format!("processing: {}", name); |
@@ -100,6 +101,39 @@ pub fn run(verbose: bool, memory_usage: bool, path: &Path, only: Option<&str>) - | |||
100 | num_exprs_partially_unknown += 1; | 101 | num_exprs_partially_unknown += 1; |
101 | } | 102 | } |
102 | } | 103 | } |
104 | if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { | ||
105 | num_type_mismatches += 1; | ||
106 | if verbose { | ||
107 | let src = f.expr_source(db, expr_id); | ||
108 | if let Some(src) = src { | ||
109 | // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly | ||
110 | let original_file = src.file_id.original_file(db); | ||
111 | let path = db.file_relative_path(original_file); | ||
112 | let line_index = host.analysis().file_line_index(original_file).unwrap(); | ||
113 | let (start, end) = ( | ||
114 | line_index.line_col(src.ast.syntax().text_range().start()), | ||
115 | line_index.line_col(src.ast.syntax().text_range().end()), | ||
116 | ); | ||
117 | bar.println(format!( | ||
118 | "{} {}:{}-{}:{}: Expected {}, got {}", | ||
119 | path.display(), | ||
120 | start.line + 1, | ||
121 | start.col_utf16, | ||
122 | end.line + 1, | ||
123 | end.col_utf16, | ||
124 | mismatch.expected.display(db), | ||
125 | mismatch.actual.display(db) | ||
126 | )); | ||
127 | } else { | ||
128 | bar.println(format!( | ||
129 | "{}: Expected {}, got {}", | ||
130 | name, | ||
131 | mismatch.expected.display(db), | ||
132 | mismatch.actual.display(db) | ||
133 | )); | ||
134 | } | ||
135 | } | ||
136 | } | ||
103 | } | 137 | } |
104 | bar.inc(1); | 138 | bar.inc(1); |
105 | } | 139 | } |
@@ -115,6 +149,7 @@ pub fn run(verbose: bool, memory_usage: bool, path: &Path, only: Option<&str>) - | |||
115 | num_exprs_partially_unknown, | 149 | num_exprs_partially_unknown, |
116 | (num_exprs_partially_unknown * 100 / num_exprs) | 150 | (num_exprs_partially_unknown * 100 / num_exprs) |
117 | ); | 151 | ); |
152 | println!("Type mismatches: {}", num_type_mismatches); | ||
118 | println!("Inference: {:?}, {}", inference_time.elapsed(), ra_prof::memory_usage()); | 153 | println!("Inference: {:?}, {}", inference_time.elapsed(), ra_prof::memory_usage()); |
119 | println!("Total: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage()); | 154 | println!("Total: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage()); |
120 | 155 | ||
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 66a58efed..f7efc1b66 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -510,18 +510,6 @@ pub enum DefWithBody { | |||
510 | impl_froms!(DefWithBody: Function, Const, Static); | 510 | impl_froms!(DefWithBody: Function, Const, Static); |
511 | 511 | ||
512 | impl DefWithBody { | 512 | impl DefWithBody { |
513 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
514 | db.infer(self) | ||
515 | } | ||
516 | |||
517 | pub fn body(self, db: &impl HirDatabase) -> Arc<Body> { | ||
518 | db.body_hir(self) | ||
519 | } | ||
520 | |||
521 | pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
522 | db.body_with_source_map(self).1 | ||
523 | } | ||
524 | |||
525 | /// Builds a resolver for code inside this item. | 513 | /// Builds a resolver for code inside this item. |
526 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { | 514 | pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { |
527 | match self { | 515 | match self { |
@@ -532,6 +520,43 @@ impl DefWithBody { | |||
532 | } | 520 | } |
533 | } | 521 | } |
534 | 522 | ||
523 | pub trait HasBody: Copy { | ||
524 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult>; | ||
525 | fn body(self, db: &impl HirDatabase) -> Arc<Body>; | ||
526 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap>; | ||
527 | } | ||
528 | |||
529 | impl<T> HasBody for T | ||
530 | where | ||
531 | T: Into<DefWithBody> + Copy + HasSource, | ||
532 | { | ||
533 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
534 | db.infer(self.into()) | ||
535 | } | ||
536 | |||
537 | fn body(self, db: &impl HirDatabase) -> Arc<Body> { | ||
538 | db.body_hir(self.into()) | ||
539 | } | ||
540 | |||
541 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
542 | db.body_with_source_map(self.into()).1 | ||
543 | } | ||
544 | } | ||
545 | |||
546 | impl HasBody for DefWithBody { | ||
547 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
548 | db.infer(self) | ||
549 | } | ||
550 | |||
551 | fn body(self, db: &impl HirDatabase) -> Arc<Body> { | ||
552 | db.body_hir(self) | ||
553 | } | ||
554 | |||
555 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
556 | db.body_with_source_map(self).1 | ||
557 | } | ||
558 | } | ||
559 | |||
535 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 560 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
536 | pub struct Function { | 561 | pub struct Function { |
537 | pub(crate) id: FunctionId, | 562 | pub(crate) id: FunctionId, |
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 32bd9c661..e5bae16ab 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs | |||
@@ -1,9 +1,9 @@ | |||
1 | use ra_syntax::ast; | 1 | use ra_syntax::ast::{self, AstNode}; |
2 | 2 | ||
3 | use crate::{ | 3 | use crate::{ |
4 | ids::AstItemDef, AstDatabase, Const, DefDatabase, Enum, EnumVariant, FieldSource, Function, | 4 | ids::AstItemDef, AstDatabase, Const, DefDatabase, Enum, EnumVariant, FieldSource, Function, |
5 | HirFileId, MacroDef, Module, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, | 5 | HasBody, HirDatabase, HirFileId, MacroDef, Module, ModuleSource, Static, Struct, StructField, |
6 | Union, | 6 | Trait, TypeAlias, Union, |
7 | }; | 7 | }; |
8 | 8 | ||
9 | pub struct Source<T> { | 9 | pub struct Source<T> { |
@@ -108,3 +108,27 @@ impl HasSource for MacroDef { | |||
108 | Source { file_id: self.id.0.file_id(), ast: self.id.0.to_node(db) } | 108 | Source { file_id: self.id.0.file_id(), ast: self.id.0.to_node(db) } |
109 | } | 109 | } |
110 | } | 110 | } |
111 | |||
112 | pub trait HasBodySource: HasBody + HasSource | ||
113 | where | ||
114 | Self::Ast: AstNode, | ||
115 | { | ||
116 | fn expr_source( | ||
117 | self, | ||
118 | db: &impl HirDatabase, | ||
119 | expr_id: crate::expr::ExprId, | ||
120 | ) -> Option<Source<ast::Expr>> { | ||
121 | let source_map = self.body_source_map(db); | ||
122 | let expr_syntax = source_map.expr_syntax(expr_id)?; | ||
123 | let source = self.source(db); | ||
124 | let node = expr_syntax.to_node(&source.ast.syntax()); | ||
125 | ast::Expr::cast(node).map(|ast| Source { file_id: source.file_id, ast }) | ||
126 | } | ||
127 | } | ||
128 | |||
129 | impl<T> HasBodySource for T | ||
130 | where | ||
131 | T: HasBody + HasSource, | ||
132 | T::Ast: AstNode, | ||
133 | { | ||
134 | } | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 018fcd096..752653ad7 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -75,8 +75,8 @@ pub use self::{ | |||
75 | 75 | ||
76 | pub use self::code_model::{ | 76 | pub use self::code_model::{ |
77 | docs::{DocDef, Docs, Documentation}, | 77 | docs::{DocDef, Docs, Documentation}, |
78 | src::{HasSource, Source}, | 78 | src::{HasBodySource, HasSource, Source}, |
79 | BuiltinType, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, | 79 | BuiltinType, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, |
80 | EnumVariant, FieldSource, FnData, Function, MacroDef, Module, ModuleDef, ModuleSource, Static, | 80 | EnumVariant, FieldSource, FnData, Function, HasBody, MacroDef, Module, ModuleDef, ModuleSource, |
81 | Struct, StructField, Trait, TypeAlias, Union, | 81 | Static, Struct, StructField, Trait, TypeAlias, Union, |
82 | }; | 82 | }; |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 56ff7da3a..43aec201a 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -27,9 +27,9 @@ use crate::{ | |||
27 | name, | 27 | name, |
28 | path::{PathKind, PathSegment}, | 28 | path::{PathKind, PathSegment}, |
29 | ty::method_resolution::implements_trait, | 29 | ty::method_resolution::implements_trait, |
30 | AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HirDatabase, HirFileId, | 30 | AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HasBody, HirDatabase, |
31 | MacroDef, Module, ModuleDef, Name, Path, PerNs, Resolution, Resolver, Static, Struct, Trait, | 31 | HirFileId, MacroDef, Module, ModuleDef, Name, Path, PerNs, Resolution, Resolver, Static, |
32 | Ty, | 32 | Struct, Trait, Ty, |
33 | }; | 33 | }; |
34 | 34 | ||
35 | /// Locates the module by `FileId`. Picks topmost module in the file. | 35 | /// Locates the module by `FileId`. Picks topmost module in the file. |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 812990426..9ba146299 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -50,8 +50,8 @@ use crate::{ | |||
50 | }, | 50 | }, |
51 | ty::infer::diagnostics::InferenceDiagnostic, | 51 | ty::infer::diagnostics::InferenceDiagnostic, |
52 | type_ref::{Mutability, TypeRef}, | 52 | type_ref::{Mutability, TypeRef}, |
53 | AdtDef, ConstData, DefWithBody, FnData, Function, HirDatabase, ImplItem, ModuleDef, Name, Path, | 53 | AdtDef, ConstData, DefWithBody, FnData, Function, HasBody, HirDatabase, ImplItem, ModuleDef, |
54 | StructField, | 54 | Name, Path, StructField, |
55 | }; | 55 | }; |
56 | 56 | ||
57 | mod unify; | 57 | mod unify; |
diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs index 992034ef0..80e55d2aa 100644 --- a/crates/ra_syntax/src/ptr.rs +++ b/crates/ra_syntax/src/ptr.rs | |||
@@ -15,9 +15,8 @@ impl SyntaxNodePtr { | |||
15 | SyntaxNodePtr { range: node.text_range(), kind: node.kind() } | 15 | SyntaxNodePtr { range: node.text_range(), kind: node.kind() } |
16 | } | 16 | } |
17 | 17 | ||
18 | pub fn to_node(self, root: &SyntaxNode) -> SyntaxNode { | 18 | pub fn to_node(self, parent: &SyntaxNode) -> SyntaxNode { |
19 | assert!(root.parent().is_none()); | 19 | successors(Some(parent.clone()), |node| { |
20 | successors(Some(root.clone()), |node| { | ||
21 | node.children().find(|it| self.range.is_subrange(&it.text_range())) | 20 | node.children().find(|it| self.range.is_subrange(&it.text_range())) |
22 | }) | 21 | }) |
23 | .find(|it| it.text_range() == self.range && it.kind() == self.kind) | 22 | .find(|it| it.text_range() == self.range && it.kind() == self.kind) |