diff --git a/crates/hir-def/src/expr_store.rs b/crates/hir-def/src/expr_store.rs index 05c220d223e8..eb66e592d68a 100644 --- a/crates/hir-def/src/expr_store.rs +++ b/crates/hir-def/src/expr_store.rs @@ -282,6 +282,9 @@ impl ExpressionStore { } } + /// Walks the immediate children expressions and calls `f` for each child expression. + /// + /// Note that this does not walk const blocks. pub fn walk_child_exprs(&self, expr_id: ExprId, mut f: impl FnMut(ExprId)) { let expr = &self[expr_id]; match expr { @@ -415,6 +418,10 @@ impl ExpressionStore { } } + /// Walks the immediate children expressions and calls `f` for each child expression but does + /// not walk expressions within patterns. + /// + /// Note that this does not walk const blocks. pub fn walk_child_exprs_without_pats(&self, expr_id: ExprId, mut f: impl FnMut(ExprId)) { let expr = &self[expr_id]; match expr { diff --git a/crates/hir-ty/src/diagnostics/unsafe_check.rs b/crates/hir-ty/src/diagnostics/unsafe_check.rs index ca0f33fa6936..73b99db72684 100644 --- a/crates/hir-ty/src/diagnostics/unsafe_check.rs +++ b/crates/hir-ty/src/diagnostics/unsafe_check.rs @@ -348,6 +348,7 @@ impl<'a> UnsafeVisitor<'a> { Expr::Closure { args, .. } => { self.walk_pats_top(args.iter().copied(), current); } + Expr::Const(e) => self.walk_expr(*e), _ => {} } diff --git a/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/crates/ide-diagnostics/src/handlers/missing_unsafe.rs index a9b481f8998d..c851a9c23908 100644 --- a/crates/ide-diagnostics/src/handlers/missing_unsafe.rs +++ b/crates/ide-diagnostics/src/handlers/missing_unsafe.rs @@ -874,6 +874,19 @@ fn baz() { fn f(it: unsafe fn()){ it(); // ^^^^ 💡 error: call to unsafe function is unsafe and requires an unsafe function or block +} + "#, + ); + } + + #[test] + fn unsafe_call_in_const_expr() { + check_diagnostics( + r#" +unsafe fn f() {} +fn main() { + const { f(); }; + // ^^^ 💡 error: call to unsafe function is unsafe and requires an unsafe function or block } "#, );