mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
Cleanup hir diagnostics API
This commit is contained in:
parent
1fdbf81181
commit
19450534cf
6 changed files with 49 additions and 48 deletions
|
@ -24,7 +24,6 @@ use hir_expand::{
|
|||
};
|
||||
use hir_ty::{
|
||||
autoderef,
|
||||
diagnostics::{expr::ExprValidator, unsafe_check::UnsafeValidator},
|
||||
display::{HirDisplayError, HirFormatter},
|
||||
method_resolution, ApplicationTy, Canonical, GenericPredicate, InEnvironment, Substs,
|
||||
TraitEnvironment, Ty, TyDefId, TypeCtor,
|
||||
|
@ -678,13 +677,7 @@ impl Function {
|
|||
}
|
||||
|
||||
pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
|
||||
let _p = profile("Function::diagnostics");
|
||||
let infer = db.infer(self.id.into());
|
||||
infer.add_diagnostics(db, self.id, sink);
|
||||
let mut validator = ExprValidator::new(self.id, infer.clone(), sink);
|
||||
validator.validate_body(db);
|
||||
let mut validator = UnsafeValidator::new(self.id, infer, sink);
|
||||
validator.validate_body(db);
|
||||
hir_ty::diagnostics::validate_body(db, self.id.into(), sink)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,25 @@ pub mod unsafe_check;
|
|||
use std::any::Any;
|
||||
|
||||
use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile};
|
||||
use ra_prof::profile;
|
||||
use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr};
|
||||
use stdx::format_to;
|
||||
|
||||
pub use hir_def::{diagnostics::UnresolvedModule, expr::MatchArm, path::Path};
|
||||
pub use hir_def::{diagnostics::UnresolvedModule, expr::MatchArm, path::Path, DefWithBodyId};
|
||||
pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink};
|
||||
|
||||
use crate::db::HirDatabase;
|
||||
|
||||
pub fn validate_body(db: &dyn HirDatabase, owner: DefWithBodyId, sink: &mut DiagnosticSink<'_>) {
|
||||
let _p = profile("validate_body");
|
||||
let infer = db.infer(owner);
|
||||
infer.add_diagnostics(db, owner, sink);
|
||||
let mut validator = expr::ExprValidator::new(owner, infer.clone(), sink);
|
||||
validator.validate_body(db);
|
||||
let mut validator = unsafe_check::UnsafeValidator::new(owner, infer, sink);
|
||||
validator.validate_body(db);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NoSuchField {
|
||||
pub file: HirFileId,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use hir_def::{path::path, resolver::HasResolver, AdtId, FunctionId};
|
||||
use hir_def::{path::path, resolver::HasResolver, AdtId, DefWithBodyId};
|
||||
use hir_expand::diagnostics::DiagnosticSink;
|
||||
use ra_syntax::{ast, AstPtr};
|
||||
use rustc_hash::FxHashSet;
|
||||
|
@ -30,23 +30,23 @@ pub use hir_def::{
|
|||
LocalFieldId, Lookup, VariantId,
|
||||
};
|
||||
|
||||
pub struct ExprValidator<'a, 'b: 'a> {
|
||||
func: FunctionId,
|
||||
pub(super) struct ExprValidator<'a, 'b: 'a> {
|
||||
owner: DefWithBodyId,
|
||||
infer: Arc<InferenceResult>,
|
||||
sink: &'a mut DiagnosticSink<'b>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> ExprValidator<'a, 'b> {
|
||||
pub fn new(
|
||||
func: FunctionId,
|
||||
pub(super) fn new(
|
||||
owner: DefWithBodyId,
|
||||
infer: Arc<InferenceResult>,
|
||||
sink: &'a mut DiagnosticSink<'b>,
|
||||
) -> ExprValidator<'a, 'b> {
|
||||
ExprValidator { func, infer, sink }
|
||||
ExprValidator { owner, infer, sink }
|
||||
}
|
||||
|
||||
pub fn validate_body(&mut self, db: &dyn HirDatabase) {
|
||||
let body = db.body(self.func.into());
|
||||
pub(super) fn validate_body(&mut self, db: &dyn HirDatabase) {
|
||||
let body = db.body(self.owner.into());
|
||||
|
||||
for (id, expr) in body.exprs.iter() {
|
||||
if let Some((variant_def, missed_fields, true)) =
|
||||
|
@ -96,7 +96,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
|||
missed_fields: Vec<LocalFieldId>,
|
||||
) {
|
||||
// XXX: only look at source_map if we do have missing fields
|
||||
let (_, source_map) = db.body_with_source_map(self.func.into());
|
||||
let (_, source_map) = db.body_with_source_map(self.owner.into());
|
||||
|
||||
if let Ok(source_ptr) = source_map.expr_syntax(id) {
|
||||
let root = source_ptr.file_syntax(db.upcast());
|
||||
|
@ -125,7 +125,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
|||
missed_fields: Vec<LocalFieldId>,
|
||||
) {
|
||||
// XXX: only look at source_map if we do have missing fields
|
||||
let (_, source_map) = db.body_with_source_map(self.func.into());
|
||||
let (_, source_map) = db.body_with_source_map(self.owner.into());
|
||||
|
||||
if let Ok(source_ptr) = source_map.pat_syntax(id) {
|
||||
if let Some(expr) = source_ptr.value.as_ref().left() {
|
||||
|
@ -181,7 +181,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
|||
let mut arg_count = args.len();
|
||||
|
||||
if arg_count != param_count {
|
||||
let (_, source_map) = db.body_with_source_map(self.func.into());
|
||||
let (_, source_map) = db.body_with_source_map(self.owner.into());
|
||||
if let Ok(source_ptr) = source_map.expr_syntax(call_id) {
|
||||
if is_method_call {
|
||||
param_count -= 1;
|
||||
|
@ -208,7 +208,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
|||
infer: Arc<InferenceResult>,
|
||||
) {
|
||||
let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) =
|
||||
db.body_with_source_map(self.func.into());
|
||||
db.body_with_source_map(self.owner.into());
|
||||
|
||||
let match_expr_ty = match infer.type_of_expr.get(match_expr) {
|
||||
Some(ty) => ty,
|
||||
|
@ -289,7 +289,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
|||
|
||||
let core_result_path = path![core::result::Result];
|
||||
|
||||
let resolver = self.func.resolver(db.upcast());
|
||||
let resolver = self.owner.resolver(db.upcast());
|
||||
let core_result_enum = match resolver.resolve_known_enum(db.upcast(), &core_result_path) {
|
||||
Some(it) => it,
|
||||
_ => return,
|
||||
|
@ -304,7 +304,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
|||
};
|
||||
|
||||
if params.len() == 2 && params[0] == mismatch.actual {
|
||||
let (_, source_map) = db.body_with_source_map(self.func.into());
|
||||
let (_, source_map) = db.body_with_source_map(self.owner.into());
|
||||
|
||||
if let Ok(source_ptr) = source_map.expr_syntax(id) {
|
||||
self.sink
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::sync::Arc;
|
|||
use hir_def::{
|
||||
body::Body,
|
||||
expr::{Expr, ExprId, UnaryOp},
|
||||
DefWithBodyId, FunctionId,
|
||||
DefWithBodyId,
|
||||
};
|
||||
use hir_expand::diagnostics::DiagnosticSink;
|
||||
|
||||
|
@ -15,26 +15,29 @@ use crate::{
|
|||
InferenceResult, Ty, TypeCtor,
|
||||
};
|
||||
|
||||
pub struct UnsafeValidator<'a, 'b: 'a> {
|
||||
func: FunctionId,
|
||||
pub(super) struct UnsafeValidator<'a, 'b: 'a> {
|
||||
owner: DefWithBodyId,
|
||||
infer: Arc<InferenceResult>,
|
||||
sink: &'a mut DiagnosticSink<'b>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> UnsafeValidator<'a, 'b> {
|
||||
pub fn new(
|
||||
func: FunctionId,
|
||||
pub(super) fn new(
|
||||
owner: DefWithBodyId,
|
||||
infer: Arc<InferenceResult>,
|
||||
sink: &'a mut DiagnosticSink<'b>,
|
||||
) -> UnsafeValidator<'a, 'b> {
|
||||
UnsafeValidator { func, infer, sink }
|
||||
UnsafeValidator { owner, infer, sink }
|
||||
}
|
||||
|
||||
pub fn validate_body(&mut self, db: &dyn HirDatabase) {
|
||||
let def = self.func.into();
|
||||
pub(super) fn validate_body(&mut self, db: &dyn HirDatabase) {
|
||||
let def = self.owner.into();
|
||||
let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def);
|
||||
let func_data = db.function_data(self.func);
|
||||
if func_data.is_unsafe
|
||||
let is_unsafe = match self.owner {
|
||||
DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe,
|
||||
DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false,
|
||||
};
|
||||
if is_unsafe
|
||||
|| unsafe_expressions
|
||||
.iter()
|
||||
.filter(|unsafe_expr| !unsafe_expr.inside_unsafe_block)
|
||||
|
|
|
@ -168,7 +168,7 @@ impl InferenceResult {
|
|||
pub fn add_diagnostics(
|
||||
&self,
|
||||
db: &dyn HirDatabase,
|
||||
owner: FunctionId,
|
||||
owner: DefWithBodyId,
|
||||
sink: &mut DiagnosticSink,
|
||||
) {
|
||||
self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink))
|
||||
|
@ -760,7 +760,7 @@ impl std::ops::BitOrAssign for Diverges {
|
|||
}
|
||||
|
||||
mod diagnostics {
|
||||
use hir_def::{expr::ExprId, FunctionId};
|
||||
use hir_def::{expr::ExprId, DefWithBodyId};
|
||||
use hir_expand::diagnostics::DiagnosticSink;
|
||||
|
||||
use crate::{
|
||||
|
@ -778,17 +778,17 @@ mod diagnostics {
|
|||
pub(super) fn add_to(
|
||||
&self,
|
||||
db: &dyn HirDatabase,
|
||||
owner: FunctionId,
|
||||
owner: DefWithBodyId,
|
||||
sink: &mut DiagnosticSink,
|
||||
) {
|
||||
match self {
|
||||
InferenceDiagnostic::NoSuchField { expr, field } => {
|
||||
let (_, source_map) = db.body_with_source_map(owner.into());
|
||||
let (_, source_map) = db.body_with_source_map(owner);
|
||||
let field = source_map.field_syntax(*expr, *field);
|
||||
sink.push(NoSuchField { file: field.file_id, field: field.value })
|
||||
}
|
||||
InferenceDiagnostic::BreakOutsideOfLoop { expr } => {
|
||||
let (_, source_map) = db.body_with_source_map(owner.into());
|
||||
let (_, source_map) = db.body_with_source_map(owner);
|
||||
let ptr = source_map
|
||||
.expr_syntax(*expr)
|
||||
.expect("break outside of loop in synthetic syntax");
|
||||
|
|
|
@ -13,10 +13,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
|
|||
use stdx::format_to;
|
||||
use test_utils::extract_annotations;
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
diagnostics::{expr::ExprValidator, unsafe_check::UnsafeValidator, Diagnostic},
|
||||
};
|
||||
use crate::diagnostics::{validate_body, Diagnostic};
|
||||
|
||||
#[salsa::database(
|
||||
ra_db::SourceDatabaseExtStorage,
|
||||
|
@ -118,13 +115,8 @@ impl TestDB {
|
|||
}
|
||||
|
||||
for f in fns {
|
||||
let infer = self.infer(f.into());
|
||||
let mut sink = DiagnosticSink::new(&mut cb);
|
||||
infer.add_diagnostics(self, f, &mut sink);
|
||||
let mut validator = ExprValidator::new(f, infer.clone(), &mut sink);
|
||||
validator.validate_body(self);
|
||||
let mut validator = UnsafeValidator::new(f, infer, &mut sink);
|
||||
validator.validate_body(self);
|
||||
validate_body(self, f.into(), &mut sink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue