aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-07-14 09:30:07 +0100
committerGitHub <[email protected]>2020-07-14 09:30:07 +0100
commit612112a2c26ec61bf341f99e9e7753bb41873fc4 (patch)
treec2becab63418e6ffd88af4bfdd1b129b305cff6d /crates/ra_hir_ty
parenta34f79b17412f83242283fae6e7a6275b4056611 (diff)
parent19450534cf308eff30ea7de1a40ab77dca4e6014 (diff)
Merge #5358
5358: Cleanup hir diagnostics API r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r--crates/ra_hir_ty/src/diagnostics.rs18
-rw-r--r--crates/ra_hir_ty/src/diagnostics/expr.rs (renamed from crates/ra_hir_ty/src/expr.rs)30
-rw-r--r--crates/ra_hir_ty/src/diagnostics/match_check.rs (renamed from crates/ra_hir_ty/src/match_checking.rs)15
-rw-r--r--crates/ra_hir_ty/src/diagnostics/unsafe_check.rs (renamed from crates/ra_hir_ty/src/unsafe_validation.rs)23
-rw-r--r--crates/ra_hir_ty/src/infer.rs10
-rw-r--r--crates/ra_hir_ty/src/lib.rs3
-rw-r--r--crates/ra_hir_ty/src/test_db.rs12
7 files changed, 60 insertions, 51 deletions
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs
index 5b0dda634..d9c2b1214 100644
--- a/crates/ra_hir_ty/src/diagnostics.rs
+++ b/crates/ra_hir_ty/src/diagnostics.rs
@@ -1,14 +1,30 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2pub mod expr;
3mod match_check;
4pub mod unsafe_check;
2 5
3use std::any::Any; 6use std::any::Any;
4 7
5use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile}; 8use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile};
9use ra_prof::profile;
6use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; 10use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr};
7use stdx::format_to; 11use stdx::format_to;
8 12
9pub use hir_def::{diagnostics::UnresolvedModule, expr::MatchArm, path::Path}; 13pub use hir_def::{diagnostics::UnresolvedModule, expr::MatchArm, path::Path, DefWithBodyId};
10pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; 14pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink};
11 15
16use crate::db::HirDatabase;
17
18pub fn validate_body(db: &dyn HirDatabase, owner: DefWithBodyId, sink: &mut DiagnosticSink<'_>) {
19 let _p = profile("validate_body");
20 let infer = db.infer(owner);
21 infer.add_diagnostics(db, owner, sink);
22 let mut validator = expr::ExprValidator::new(owner, infer.clone(), sink);
23 validator.validate_body(db);
24 let mut validator = unsafe_check::UnsafeValidator::new(owner, infer, sink);
25 validator.validate_body(db);
26}
27
12#[derive(Debug)] 28#[derive(Debug)]
13pub struct NoSuchField { 29pub struct NoSuchField {
14 pub file: HirFileId, 30 pub file: HirFileId,
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/diagnostics/expr.rs
index d44562b22..239be779f 100644
--- a/crates/ra_hir_ty/src/expr.rs
+++ b/crates/ra_hir_ty/src/diagnostics/expr.rs
@@ -2,7 +2,7 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::{path::path, resolver::HasResolver, AdtId, FunctionId}; 5use hir_def::{path::path, resolver::HasResolver, AdtId, DefWithBodyId};
6use hir_expand::diagnostics::DiagnosticSink; 6use hir_expand::diagnostics::DiagnosticSink;
7use ra_syntax::{ast, AstPtr}; 7use ra_syntax::{ast, AstPtr};
8use rustc_hash::FxHashSet; 8use rustc_hash::FxHashSet;
@@ -10,9 +10,9 @@ use rustc_hash::FxHashSet;
10use crate::{ 10use crate::{
11 db::HirDatabase, 11 db::HirDatabase,
12 diagnostics::{ 12 diagnostics::{
13 match_check::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness},
13 MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields, 14 MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields,
14 }, 15 },
15 match_checking::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness},
16 utils::variant_data, 16 utils::variant_data,
17 ApplicationTy, InferenceResult, Ty, TypeCtor, 17 ApplicationTy, InferenceResult, Ty, TypeCtor,
18}; 18};
@@ -30,23 +30,23 @@ pub use hir_def::{
30 LocalFieldId, Lookup, VariantId, 30 LocalFieldId, Lookup, VariantId,
31}; 31};
32 32
33pub struct ExprValidator<'a, 'b: 'a> { 33pub(super) struct ExprValidator<'a, 'b: 'a> {
34 func: FunctionId, 34 owner: DefWithBodyId,
35 infer: Arc<InferenceResult>, 35 infer: Arc<InferenceResult>,
36 sink: &'a mut DiagnosticSink<'b>, 36 sink: &'a mut DiagnosticSink<'b>,
37} 37}
38 38
39impl<'a, 'b> ExprValidator<'a, 'b> { 39impl<'a, 'b> ExprValidator<'a, 'b> {
40 pub fn new( 40 pub(super) fn new(
41 func: FunctionId, 41 owner: DefWithBodyId,
42 infer: Arc<InferenceResult>, 42 infer: Arc<InferenceResult>,
43 sink: &'a mut DiagnosticSink<'b>, 43 sink: &'a mut DiagnosticSink<'b>,
44 ) -> ExprValidator<'a, 'b> { 44 ) -> ExprValidator<'a, 'b> {
45 ExprValidator { func, infer, sink } 45 ExprValidator { owner, infer, sink }
46 } 46 }
47 47
48 pub fn validate_body(&mut self, db: &dyn HirDatabase) { 48 pub(super) fn validate_body(&mut self, db: &dyn HirDatabase) {
49 let body = db.body(self.func.into()); 49 let body = db.body(self.owner.into());
50 50
51 for (id, expr) in body.exprs.iter() { 51 for (id, expr) in body.exprs.iter() {
52 if let Some((variant_def, missed_fields, true)) = 52 if let Some((variant_def, missed_fields, true)) =
@@ -96,7 +96,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
96 missed_fields: Vec<LocalFieldId>, 96 missed_fields: Vec<LocalFieldId>,
97 ) { 97 ) {
98 // XXX: only look at source_map if we do have missing fields 98 // XXX: only look at source_map if we do have missing fields
99 let (_, source_map) = db.body_with_source_map(self.func.into()); 99 let (_, source_map) = db.body_with_source_map(self.owner.into());
100 100
101 if let Ok(source_ptr) = source_map.expr_syntax(id) { 101 if let Ok(source_ptr) = source_map.expr_syntax(id) {
102 let root = source_ptr.file_syntax(db.upcast()); 102 let root = source_ptr.file_syntax(db.upcast());
@@ -125,7 +125,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
125 missed_fields: Vec<LocalFieldId>, 125 missed_fields: Vec<LocalFieldId>,
126 ) { 126 ) {
127 // XXX: only look at source_map if we do have missing fields 127 // XXX: only look at source_map if we do have missing fields
128 let (_, source_map) = db.body_with_source_map(self.func.into()); 128 let (_, source_map) = db.body_with_source_map(self.owner.into());
129 129
130 if let Ok(source_ptr) = source_map.pat_syntax(id) { 130 if let Ok(source_ptr) = source_map.pat_syntax(id) {
131 if let Some(expr) = source_ptr.value.as_ref().left() { 131 if let Some(expr) = source_ptr.value.as_ref().left() {
@@ -181,7 +181,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
181 let mut arg_count = args.len(); 181 let mut arg_count = args.len();
182 182
183 if arg_count != param_count { 183 if arg_count != param_count {
184 let (_, source_map) = db.body_with_source_map(self.func.into()); 184 let (_, source_map) = db.body_with_source_map(self.owner.into());
185 if let Ok(source_ptr) = source_map.expr_syntax(call_id) { 185 if let Ok(source_ptr) = source_map.expr_syntax(call_id) {
186 if is_method_call { 186 if is_method_call {
187 param_count -= 1; 187 param_count -= 1;
@@ -208,7 +208,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
208 infer: Arc<InferenceResult>, 208 infer: Arc<InferenceResult>,
209 ) { 209 ) {
210 let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) = 210 let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) =
211 db.body_with_source_map(self.func.into()); 211 db.body_with_source_map(self.owner.into());
212 212
213 let match_expr_ty = match infer.type_of_expr.get(match_expr) { 213 let match_expr_ty = match infer.type_of_expr.get(match_expr) {
214 Some(ty) => ty, 214 Some(ty) => ty,
@@ -289,7 +289,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
289 289
290 let core_result_path = path![core::result::Result]; 290 let core_result_path = path![core::result::Result];
291 291
292 let resolver = self.func.resolver(db.upcast()); 292 let resolver = self.owner.resolver(db.upcast());
293 let core_result_enum = match resolver.resolve_known_enum(db.upcast(), &core_result_path) { 293 let core_result_enum = match resolver.resolve_known_enum(db.upcast(), &core_result_path) {
294 Some(it) => it, 294 Some(it) => it,
295 _ => return, 295 _ => return,
@@ -304,7 +304,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
304 }; 304 };
305 305
306 if params.len() == 2 && params[0] == mismatch.actual { 306 if params.len() == 2 && params[0] == mismatch.actual {
307 let (_, source_map) = db.body_with_source_map(self.func.into()); 307 let (_, source_map) = db.body_with_source_map(self.owner.into());
308 308
309 if let Ok(source_ptr) = source_map.expr_syntax(id) { 309 if let Ok(source_ptr) = source_map.expr_syntax(id) {
310 self.sink 310 self.sink
diff --git a/crates/ra_hir_ty/src/match_checking.rs b/crates/ra_hir_ty/src/diagnostics/match_check.rs
index 5495ce284..722c0e9ee 100644
--- a/crates/ra_hir_ty/src/match_checking.rs
+++ b/crates/ra_hir_ty/src/diagnostics/match_check.rs
@@ -218,15 +218,16 @@
218//! ``` 218//! ```
219use std::sync::Arc; 219use std::sync::Arc;
220 220
221use smallvec::{smallvec, SmallVec}; 221use hir_def::{
222 222 adt::VariantData,
223use crate::{ 223 body::Body,
224 db::HirDatabase, 224 expr::{Expr, Literal, Pat, PatId},
225 expr::{Body, Expr, Literal, Pat, PatId}, 225 AdtId, EnumVariantId, VariantId,
226 ApplicationTy, InferenceResult, Ty, TypeCtor,
227}; 226};
228use hir_def::{adt::VariantData, AdtId, EnumVariantId, VariantId};
229use ra_arena::Idx; 227use ra_arena::Idx;
228use smallvec::{smallvec, SmallVec};
229
230use crate::{db::HirDatabase, ApplicationTy, InferenceResult, Ty, TypeCtor};
230 231
231#[derive(Debug, Clone, Copy)] 232#[derive(Debug, Clone, Copy)]
232/// Either a pattern from the source code being analyzed, represented as 233/// Either a pattern from the source code being analyzed, represented as
diff --git a/crates/ra_hir_ty/src/unsafe_validation.rs b/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs
index c512c4f8e..b8ff95ee1 100644
--- a/crates/ra_hir_ty/src/unsafe_validation.rs
+++ b/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs
@@ -6,7 +6,7 @@ use std::sync::Arc;
6use hir_def::{ 6use hir_def::{
7 body::Body, 7 body::Body,
8 expr::{Expr, ExprId, UnaryOp}, 8 expr::{Expr, ExprId, UnaryOp},
9 DefWithBodyId, FunctionId, 9 DefWithBodyId,
10}; 10};
11use hir_expand::diagnostics::DiagnosticSink; 11use hir_expand::diagnostics::DiagnosticSink;
12 12
@@ -15,26 +15,29 @@ use crate::{
15 InferenceResult, Ty, TypeCtor, 15 InferenceResult, Ty, TypeCtor,
16}; 16};
17 17
18pub struct UnsafeValidator<'a, 'b: 'a> { 18pub(super) struct UnsafeValidator<'a, 'b: 'a> {
19 func: FunctionId, 19 owner: DefWithBodyId,
20 infer: Arc<InferenceResult>, 20 infer: Arc<InferenceResult>,
21 sink: &'a mut DiagnosticSink<'b>, 21 sink: &'a mut DiagnosticSink<'b>,
22} 22}
23 23
24impl<'a, 'b> UnsafeValidator<'a, 'b> { 24impl<'a, 'b> UnsafeValidator<'a, 'b> {
25 pub fn new( 25 pub(super) fn new(
26 func: FunctionId, 26 owner: DefWithBodyId,
27 infer: Arc<InferenceResult>, 27 infer: Arc<InferenceResult>,
28 sink: &'a mut DiagnosticSink<'b>, 28 sink: &'a mut DiagnosticSink<'b>,
29 ) -> UnsafeValidator<'a, 'b> { 29 ) -> UnsafeValidator<'a, 'b> {
30 UnsafeValidator { func, infer, sink } 30 UnsafeValidator { owner, infer, sink }
31 } 31 }
32 32
33 pub fn validate_body(&mut self, db: &dyn HirDatabase) { 33 pub(super) fn validate_body(&mut self, db: &dyn HirDatabase) {
34 let def = self.func.into(); 34 let def = self.owner.into();
35 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); 35 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def);
36 let func_data = db.function_data(self.func); 36 let is_unsafe = match self.owner {
37 if func_data.is_unsafe 37 DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe,
38 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false,
39 };
40 if is_unsafe
38 || unsafe_expressions 41 || unsafe_expressions
39 .iter() 42 .iter()
40 .filter(|unsafe_expr| !unsafe_expr.inside_unsafe_block) 43 .filter(|unsafe_expr| !unsafe_expr.inside_unsafe_block)
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index 2ce4f65cc..28f32a0a4 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -168,7 +168,7 @@ impl InferenceResult {
168 pub fn add_diagnostics( 168 pub fn add_diagnostics(
169 &self, 169 &self,
170 db: &dyn HirDatabase, 170 db: &dyn HirDatabase,
171 owner: FunctionId, 171 owner: DefWithBodyId,
172 sink: &mut DiagnosticSink, 172 sink: &mut DiagnosticSink,
173 ) { 173 ) {
174 self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink)) 174 self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink))
@@ -760,7 +760,7 @@ impl std::ops::BitOrAssign for Diverges {
760} 760}
761 761
762mod diagnostics { 762mod diagnostics {
763 use hir_def::{expr::ExprId, FunctionId}; 763 use hir_def::{expr::ExprId, DefWithBodyId};
764 use hir_expand::diagnostics::DiagnosticSink; 764 use hir_expand::diagnostics::DiagnosticSink;
765 765
766 use crate::{ 766 use crate::{
@@ -778,17 +778,17 @@ mod diagnostics {
778 pub(super) fn add_to( 778 pub(super) fn add_to(
779 &self, 779 &self,
780 db: &dyn HirDatabase, 780 db: &dyn HirDatabase,
781 owner: FunctionId, 781 owner: DefWithBodyId,
782 sink: &mut DiagnosticSink, 782 sink: &mut DiagnosticSink,
783 ) { 783 ) {
784 match self { 784 match self {
785 InferenceDiagnostic::NoSuchField { expr, field } => { 785 InferenceDiagnostic::NoSuchField { expr, field } => {
786 let (_, source_map) = db.body_with_source_map(owner.into()); 786 let (_, source_map) = db.body_with_source_map(owner);
787 let field = source_map.field_syntax(*expr, *field); 787 let field = source_map.field_syntax(*expr, *field);
788 sink.push(NoSuchField { file: field.file_id, field: field.value }) 788 sink.push(NoSuchField { file: field.file_id, field: field.value })
789 } 789 }
790 InferenceDiagnostic::BreakOutsideOfLoop { expr } => { 790 InferenceDiagnostic::BreakOutsideOfLoop { expr } => {
791 let (_, source_map) = db.body_with_source_map(owner.into()); 791 let (_, source_map) = db.body_with_source_map(owner);
792 let ptr = source_map 792 let ptr = source_map
793 .expr_syntax(*expr) 793 .expr_syntax(*expr)
794 .expect("break outside of loop in synthetic syntax"); 794 .expect("break outside of loop in synthetic syntax");
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 2652d200f..d54568e67 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -12,15 +12,12 @@ pub mod traits;
12pub mod method_resolution; 12pub mod method_resolution;
13mod op; 13mod op;
14mod lower; 14mod lower;
15mod match_checking;
16pub(crate) mod infer; 15pub(crate) mod infer;
17pub(crate) mod utils; 16pub(crate) mod utils;
18 17
19pub mod display; 18pub mod display;
20pub mod db; 19pub mod db;
21pub mod diagnostics; 20pub mod diagnostics;
22pub mod expr;
23pub mod unsafe_validation;
24 21
25#[cfg(test)] 22#[cfg(test)]
26mod tests; 23mod tests;
diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs
index dc447955f..daf2b909e 100644
--- a/crates/ra_hir_ty/src/test_db.rs
+++ b/crates/ra_hir_ty/src/test_db.rs
@@ -13,10 +13,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
13use stdx::format_to; 13use stdx::format_to;
14use test_utils::extract_annotations; 14use test_utils::extract_annotations;
15 15
16use crate::{ 16use crate::diagnostics::{validate_body, Diagnostic};
17 db::HirDatabase, diagnostics::Diagnostic, expr::ExprValidator,
18 unsafe_validation::UnsafeValidator,
19};
20 17
21#[salsa::database( 18#[salsa::database(
22 ra_db::SourceDatabaseExtStorage, 19 ra_db::SourceDatabaseExtStorage,
@@ -118,13 +115,8 @@ impl TestDB {
118 } 115 }
119 116
120 for f in fns { 117 for f in fns {
121 let infer = self.infer(f.into());
122 let mut sink = DiagnosticSink::new(&mut cb); 118 let mut sink = DiagnosticSink::new(&mut cb);
123 infer.add_diagnostics(self, f, &mut sink); 119 validate_body(self, f.into(), &mut sink);
124 let mut validator = ExprValidator::new(f, infer.clone(), &mut sink);
125 validator.validate_body(self);
126 let mut validator = UnsafeValidator::new(f, infer, &mut sink);
127 validator.validate_body(self);
128 } 120 }
129 } 121 }
130 } 122 }