diff options
Diffstat (limited to 'crates/hir/src')
-rw-r--r-- | crates/hir/src/diagnostics.rs | 24 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 20 |
2 files changed, 40 insertions, 4 deletions
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs index 2edb53765..e888fc23b 100644 --- a/crates/hir/src/diagnostics.rs +++ b/crates/hir/src/diagnostics.rs | |||
@@ -301,3 +301,27 @@ impl Diagnostic for BreakOutsideOfLoop { | |||
301 | self | 301 | self |
302 | } | 302 | } |
303 | } | 303 | } |
304 | |||
305 | // Diagnostic: missing-unsafe | ||
306 | // | ||
307 | // This diagnostic is triggered if an operation marked as `unsafe` is used outside of an `unsafe` function or block. | ||
308 | #[derive(Debug)] | ||
309 | pub struct MissingUnsafe { | ||
310 | pub file: HirFileId, | ||
311 | pub expr: AstPtr<ast::Expr>, | ||
312 | } | ||
313 | |||
314 | impl Diagnostic for MissingUnsafe { | ||
315 | fn code(&self) -> DiagnosticCode { | ||
316 | DiagnosticCode("missing-unsafe") | ||
317 | } | ||
318 | fn message(&self) -> String { | ||
319 | format!("This operation is unsafe and requires an unsafe function or block") | ||
320 | } | ||
321 | fn display_source(&self) -> InFile<SyntaxNodePtr> { | ||
322 | InFile { file_id: self.file, value: self.expr.clone().into() } | ||
323 | } | ||
324 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
325 | self | ||
326 | } | ||
327 | } | ||
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index bce626b03..a21a9da21 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -36,14 +36,14 @@ use std::{iter, sync::Arc}; | |||
36 | use arrayvec::ArrayVec; | 36 | use arrayvec::ArrayVec; |
37 | use base_db::{CrateDisplayName, CrateId, Edition, FileId}; | 37 | use base_db::{CrateDisplayName, CrateId, Edition, FileId}; |
38 | use diagnostics::{ | 38 | use diagnostics::{ |
39 | BreakOutsideOfLoop, InactiveCode, MacroError, NoSuchField, UnimplementedBuiltinMacro, | 39 | BreakOutsideOfLoop, InactiveCode, MacroError, MissingUnsafe, NoSuchField, |
40 | UnresolvedExternCrate, UnresolvedImport, UnresolvedMacroCall, UnresolvedModule, | 40 | UnimplementedBuiltinMacro, UnresolvedExternCrate, UnresolvedImport, UnresolvedMacroCall, |
41 | UnresolvedProcMacro, | 41 | UnresolvedModule, UnresolvedProcMacro, |
42 | }; | 42 | }; |
43 | use either::Either; | 43 | use either::Either; |
44 | use hir_def::{ | 44 | use hir_def::{ |
45 | adt::{ReprKind, VariantData}, | 45 | adt::{ReprKind, VariantData}, |
46 | body::BodyDiagnostic, | 46 | body::{BodyDiagnostic, SyntheticSyntax}, |
47 | expr::{BindingAnnotation, LabelId, Pat, PatId}, | 47 | expr::{BindingAnnotation, LabelId, Pat, PatId}, |
48 | item_tree::ItemTreeNode, | 48 | item_tree::ItemTreeNode, |
49 | lang_item::LangItemTarget, | 49 | lang_item::LangItemTarget, |
@@ -1060,6 +1060,18 @@ impl Function { | |||
1060 | } | 1060 | } |
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | for expr in hir_ty::diagnostics::missing_unsafe(db, self.id.into()) { | ||
1064 | match source_map.as_ref().expr_syntax(expr) { | ||
1065 | Ok(in_file) => { | ||
1066 | sink.push(MissingUnsafe { file: in_file.file_id, expr: in_file.value }) | ||
1067 | } | ||
1068 | Err(SyntheticSyntax) => { | ||
1069 | // FIXME: The `expr` was desugared, report or assert that | ||
1070 | // this dosen't happen. | ||
1071 | } | ||
1072 | } | ||
1073 | } | ||
1074 | |||
1063 | hir_ty::diagnostics::validate_module_item(db, krate, self.id.into(), sink); | 1075 | hir_ty::diagnostics::validate_module_item(db, krate, self.id.into(), sink); |
1064 | hir_ty::diagnostics::validate_body(db, self.id.into(), sink); | 1076 | hir_ty::diagnostics::validate_body(db, self.id.into(), sink); |
1065 | } | 1077 | } |