Unnamed repository; edit this file 'description' to name the repository.
fix: Walk const block expressions for unsafety checking
Lukas Wirth 2025-04-10
parent 4fdc250 · commit 8df812f
-rw-r--r--crates/hir-def/src/expr_store.rs7
-rw-r--r--crates/hir-ty/src/diagnostics/unsafe_check.rs1
-rw-r--r--crates/ide-diagnostics/src/handlers/missing_unsafe.rs13
3 files changed, 21 insertions, 0 deletions
diff --git a/crates/hir-def/src/expr_store.rs b/crates/hir-def/src/expr_store.rs
index 05c220d223..eb66e592d6 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 ca0f33fa69..73b99db726 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 a9b481f899..c851a9c239 100644
--- a/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
+++ b/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
@@ -878,4 +878,17 @@ fn f(it: unsafe fn()){
"#,
);
}
+
+ #[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
+}
+ "#,
+ );
+ }
}