From 6a77ec7bbe6ddbf663dce9529d11d1bb56c5489a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 13 Aug 2020 16:35:29 +0200 Subject: Rename ra_hir_ty -> hir_ty --- crates/ra_hir_ty/src/diagnostics.rs | 444 ------------------------------------ 1 file changed, 444 deletions(-) delete mode 100644 crates/ra_hir_ty/src/diagnostics.rs (limited to 'crates/ra_hir_ty/src/diagnostics.rs') diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs deleted file mode 100644 index ae0cf8d09..000000000 --- a/crates/ra_hir_ty/src/diagnostics.rs +++ /dev/null @@ -1,444 +0,0 @@ -//! FIXME: write short doc here -mod expr; -mod match_check; -mod unsafe_check; - -use std::any::Any; - -use hir_def::DefWithBodyId; -use hir_expand::diagnostics::{Diagnostic, DiagnosticSink}; -use hir_expand::{name::Name, HirFileId, InFile}; -use stdx::format_to; -use syntax::{ast, AstPtr, SyntaxNodePtr}; - -use crate::db::HirDatabase; - -pub use crate::diagnostics::expr::{record_literal_missing_fields, record_pattern_missing_fields}; - -pub fn validate_body(db: &dyn HirDatabase, owner: DefWithBodyId, sink: &mut DiagnosticSink<'_>) { - let _p = profile::span("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, - pub field: AstPtr, -} - -impl Diagnostic for NoSuchField { - fn message(&self) -> String { - "no such field".to_string() - } - - fn display_source(&self) -> InFile { - InFile::new(self.file, self.field.clone().into()) - } - - fn as_any(&self) -> &(dyn Any + Send + 'static) { - self - } -} - -#[derive(Debug)] -pub struct MissingFields { - pub file: HirFileId, - pub field_list_parent: AstPtr, - pub field_list_parent_path: Option>, - pub missed_fields: Vec, -} - -impl Diagnostic for MissingFields { - fn message(&self) -> String { - let mut buf = String::from("Missing structure fields:\n"); - for field in &self.missed_fields { - format_to!(buf, "- {}\n", field); - } - buf - } - - fn display_source(&self) -> InFile { - InFile { - file_id: self.file, - value: self - .field_list_parent_path - .clone() - .map(SyntaxNodePtr::from) - .unwrap_or_else(|| self.field_list_parent.clone().into()), - } - } - - fn as_any(&self) -> &(dyn Any + Send + 'static) { - self - } -} - -#[derive(Debug)] -pub struct MissingPatFields { - pub file: HirFileId, - pub field_list_parent: AstPtr, - pub field_list_parent_path: Option>, - pub missed_fields: Vec, -} - -impl Diagnostic for MissingPatFields { - fn message(&self) -> String { - let mut buf = String::from("Missing structure fields:\n"); - for field in &self.missed_fields { - format_to!(buf, "- {}\n", field); - } - buf - } - fn display_source(&self) -> InFile { - InFile { - file_id: self.file, - value: self - .field_list_parent_path - .clone() - .map(SyntaxNodePtr::from) - .unwrap_or_else(|| self.field_list_parent.clone().into()), - } - } - fn as_any(&self) -> &(dyn Any + Send + 'static) { - self - } -} - -#[derive(Debug)] -pub struct MissingMatchArms { - pub file: HirFileId, - pub match_expr: AstPtr, - pub arms: AstPtr, -} - -impl Diagnostic for MissingMatchArms { - fn message(&self) -> String { - String::from("Missing match arm") - } - fn display_source(&self) -> InFile { - InFile { file_id: self.file, value: self.match_expr.clone().into() } - } - fn as_any(&self) -> &(dyn Any + Send + 'static) { - self - } -} - -#[derive(Debug)] -pub struct MissingOkInTailExpr { - pub file: HirFileId, - pub expr: AstPtr, -} - -impl Diagnostic for MissingOkInTailExpr { - fn message(&self) -> String { - "wrap return expression in Ok".to_string() - } - fn display_source(&self) -> InFile { - InFile { file_id: self.file, value: self.expr.clone().into() } - } - fn as_any(&self) -> &(dyn Any + Send + 'static) { - self - } -} - -#[derive(Debug)] -pub struct BreakOutsideOfLoop { - pub file: HirFileId, - pub expr: AstPtr, -} - -impl Diagnostic for BreakOutsideOfLoop { - fn message(&self) -> String { - "break outside of loop".to_string() - } - fn display_source(&self) -> InFile { - InFile { file_id: self.file, value: self.expr.clone().into() } - } - fn as_any(&self) -> &(dyn Any + Send + 'static) { - self - } -} - -#[derive(Debug)] -pub struct MissingUnsafe { - pub file: HirFileId, - pub expr: AstPtr, -} - -impl Diagnostic for MissingUnsafe { - fn message(&self) -> String { - format!("This operation is unsafe and requires an unsafe function or block") - } - fn display_source(&self) -> InFile { - InFile { file_id: self.file, value: self.expr.clone().into() } - } - fn as_any(&self) -> &(dyn Any + Send + 'static) { - self - } -} - -#[derive(Debug)] -pub struct MismatchedArgCount { - pub file: HirFileId, - pub call_expr: AstPtr, - pub expected: usize, - pub found: usize, -} - -impl Diagnostic for MismatchedArgCount { - fn message(&self) -> String { - let s = if self.expected == 1 { "" } else { "s" }; - format!("Expected {} argument{}, found {}", self.expected, s, self.found) - } - fn display_source(&self) -> InFile { - InFile { file_id: self.file, value: self.call_expr.clone().into() } - } - fn as_any(&self) -> &(dyn Any + Send + 'static) { - self - } - fn is_experimental(&self) -> bool { - true - } -} - -#[cfg(test)] -mod tests { - use base_db::{fixture::WithFixture, FileId, SourceDatabase, SourceDatabaseExt}; - use hir_def::{db::DefDatabase, AssocItemId, ModuleDefId}; - use hir_expand::{ - db::AstDatabase, - diagnostics::{Diagnostic, DiagnosticSinkBuilder}, - }; - use rustc_hash::FxHashMap; - use syntax::{TextRange, TextSize}; - - use crate::{diagnostics::validate_body, test_db::TestDB}; - - impl TestDB { - fn diagnostics(&self, mut cb: F) { - let crate_graph = self.crate_graph(); - for krate in crate_graph.iter() { - let crate_def_map = self.crate_def_map(krate); - - let mut fns = Vec::new(); - for (module_id, _) in crate_def_map.modules.iter() { - for decl in crate_def_map[module_id].scope.declarations() { - if let ModuleDefId::FunctionId(f) = decl { - fns.push(f) - } - } - - for impl_id in crate_def_map[module_id].scope.impls() { - let impl_data = self.impl_data(impl_id); - for item in impl_data.items.iter() { - if let AssocItemId::FunctionId(f) = item { - fns.push(*f) - } - } - } - } - - for f in fns { - let mut sink = DiagnosticSinkBuilder::new().build(&mut cb); - validate_body(self, f.into(), &mut sink); - } - } - } - } - - pub(crate) fn check_diagnostics(ra_fixture: &str) { - let db = TestDB::with_files(ra_fixture); - let annotations = db.extract_annotations(); - - let mut actual: FxHashMap> = FxHashMap::default(); - db.diagnostics(|d| { - let src = d.display_source(); - let root = db.parse_or_expand(src.file_id).unwrap(); - // FIXME: macros... - let file_id = src.file_id.original_file(&db); - let range = src.value.to_node(&root).text_range(); - let message = d.message().to_owned(); - actual.entry(file_id).or_default().push((range, message)); - }); - - for (file_id, diags) in actual.iter_mut() { - diags.sort_by_key(|it| it.0.start()); - let text = db.file_text(*file_id); - // For multiline spans, place them on line start - for (range, content) in diags { - if text[*range].contains('\n') { - *range = TextRange::new(range.start(), range.start() + TextSize::from(1)); - *content = format!("... {}", content); - } - } - } - - assert_eq!(annotations, actual); - } - - #[test] - fn no_such_field_diagnostics() { - check_diagnostics( - r#" -struct S { foo: i32, bar: () } -impl S { - fn new() -> S { - S { - //^ Missing structure fields: - //| - bar - foo: 92, - baz: 62, - //^^^^^^^ no such field - } - } -} -"#, - ); - } - #[test] - fn no_such_field_with_feature_flag_diagnostics() { - check_diagnostics( - r#" -//- /lib.rs crate:foo cfg:feature=foo -struct MyStruct { - my_val: usize, - #[cfg(feature = "foo")] - bar: bool, -} - -impl MyStruct { - #[cfg(feature = "foo")] - pub(crate) fn new(my_val: usize, bar: bool) -> Self { - Self { my_val, bar } - } - #[cfg(not(feature = "foo"))] - pub(crate) fn new(my_val: usize, _bar: bool) -> Self { - Self { my_val } - } -} -"#, - ); - } - - #[test] - fn no_such_field_enum_with_feature_flag_diagnostics() { - check_diagnostics( - r#" -//- /lib.rs crate:foo cfg:feature=foo -enum Foo { - #[cfg(not(feature = "foo"))] - Buz, - #[cfg(feature = "foo")] - Bar, - Baz -} - -fn test_fn(f: Foo) { - match f { - Foo::Bar => {}, - Foo::Baz => {}, - } -} -"#, - ); - } - - #[test] - fn no_such_field_with_feature_flag_diagnostics_on_struct_lit() { - check_diagnostics( - r#" -//- /lib.rs crate:foo cfg:feature=foo -struct S { - #[cfg(feature = "foo")] - foo: u32, - #[cfg(not(feature = "foo"))] - bar: u32, -} - -impl S { - #[cfg(feature = "foo")] - fn new(foo: u32) -> Self { - Self { foo } - } - #[cfg(not(feature = "foo"))] - fn new(bar: u32) -> Self { - Self { bar } - } - fn new2(bar: u32) -> Self { - #[cfg(feature = "foo")] - { Self { foo: bar } } - #[cfg(not(feature = "foo"))] - { Self { bar } } - } - fn new2(val: u32) -> Self { - Self { - #[cfg(feature = "foo")] - foo: val, - #[cfg(not(feature = "foo"))] - bar: val, - } - } -} -"#, - ); - } - - #[test] - fn no_such_field_with_type_macro() { - check_diagnostics( - r#" -macro_rules! Type { () => { u32 }; } -struct Foo { bar: Type![] } - -impl Foo { - fn new() -> Self { - Foo { bar: 0 } - } -} -"#, - ); - } - - #[test] - fn missing_record_pat_field_diagnostic() { - check_diagnostics( - r#" -struct S { foo: i32, bar: () } -fn baz(s: S) { - let S { foo: _ } = s; - //^ Missing structure fields: - //| - bar -} -"#, - ); - } - - #[test] - fn missing_record_pat_field_no_diagnostic_if_not_exhaustive() { - check_diagnostics( - r" -struct S { foo: i32, bar: () } -fn baz(s: S) -> i32 { - match s { - S { foo, .. } => foo, - } -} -", - ) - } - - #[test] - fn break_outside_of_loop() { - check_diagnostics( - r#" -fn foo() { break; } - //^^^^^ break outside of loop -"#, - ); - } -} -- cgit v1.2.3