Skip to content

Commit 54d36de

Browse files
authored
Merge pull request rust-lang#20547 from ChayimFriedman2/highlight-related-unsafe-scope
fix: In highlight_related, when on an unsafe block, don't highlight unsafe operations of other unsafe blocks
2 parents 035bed8 + 28a248f commit 54d36de

File tree

4 files changed

+44
-10
lines changed

4 files changed

+44
-10
lines changed

src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,11 @@ pub fn unsafe_operations(
119119
def: DefWithBodyId,
120120
body: &Body,
121121
current: ExprId,
122-
callback: &mut dyn FnMut(InsideUnsafeBlock),
122+
callback: &mut dyn FnMut(ExprOrPatId, InsideUnsafeBlock),
123123
) {
124124
let mut visitor_callback = |diag| {
125-
if let UnsafeDiagnostic::UnsafeOperation { inside_unsafe_block, .. } = diag {
126-
callback(inside_unsafe_block);
125+
if let UnsafeDiagnostic::UnsafeOperation { inside_unsafe_block, node, .. } = diag {
126+
callback(node, inside_unsafe_block);
127127
}
128128
};
129129
let mut visitor = UnsafeVisitor::new(db, infer, body, def, &mut visitor_callback);

src/tools/rust-analyzer/crates/hir/src/semantics.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ use hir_expand::{
2828
mod_path::{ModPath, PathKind},
2929
name::AsName,
3030
};
31-
use hir_ty::diagnostics::unsafe_operations_for_body;
31+
use hir_ty::diagnostics::{unsafe_operations, unsafe_operations_for_body};
3232
use intern::{Interned, Symbol, sym};
3333
use itertools::Itertools;
3434
use rustc_hash::{FxHashMap, FxHashSet};
3535
use smallvec::{SmallVec, smallvec};
3636
use span::{Edition, FileId, SyntaxContext};
37-
use stdx::TupleExt;
37+
use stdx::{TupleExt, always};
3838
use syntax::{
3939
AstNode, AstToken, Direction, SyntaxKind, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange,
4040
TextSize,
@@ -1765,6 +1765,25 @@ impl<'db> SemanticsImpl<'db> {
17651765
res
17661766
}
17671767

1768+
pub fn get_unsafe_ops_for_unsafe_block(&self, block: ast::BlockExpr) -> Vec<ExprOrPatSource> {
1769+
always!(block.unsafe_token().is_some());
1770+
let block = self.wrap_node_infile(ast::Expr::from(block));
1771+
let Some(def) = self.body_for(block.syntax()) else { return Vec::new() };
1772+
let def = def.into();
1773+
let (body, source_map) = self.db.body_with_source_map(def);
1774+
let infer = self.db.infer(def);
1775+
let Some(ExprOrPatId::ExprId(block)) = source_map.node_expr(block.as_ref()) else {
1776+
return Vec::new();
1777+
};
1778+
let mut res = Vec::default();
1779+
unsafe_operations(self.db, &infer, def, &body, block, &mut |node, _| {
1780+
if let Ok(node) = source_map.expr_or_pat_syntax(node) {
1781+
res.push(node);
1782+
}
1783+
});
1784+
res
1785+
}
1786+
17681787
pub fn is_unsafe_macro_call(&self, macro_call: &ast::MacroCall) -> bool {
17691788
let Some(mac) = self.resolve_macro_call(macro_call) else { return false };
17701789
if mac.is_asm_like(self.db) {

src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1283,7 +1283,7 @@ impl<'db> SourceAnalyzer<'db> {
12831283
{
12841284
let mut is_unsafe = false;
12851285
let mut walk_expr = |expr_id| {
1286-
unsafe_operations(db, infer, def, body, expr_id, &mut |inside_unsafe_block| {
1286+
unsafe_operations(db, infer, def, body, expr_id, &mut |_, inside_unsafe_block| {
12871287
is_unsafe |= inside_unsafe_block == InsideUnsafeBlock::No
12881288
})
12891289
};

src/tools/rust-analyzer/crates/ide/src/highlight_related.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -805,10 +805,8 @@ pub(crate) fn highlight_unsafe_points(
805805
push_to_highlights(unsafe_token_file_id, Some(unsafe_token.text_range()));
806806

807807
// highlight unsafe operations
808-
if let Some(block) = block_expr
809-
&& let Some(body) = sema.body_for(InFile::new(unsafe_token_file_id, block.syntax()))
810-
{
811-
let unsafe_ops = sema.get_unsafe_ops(body);
808+
if let Some(block) = block_expr {
809+
let unsafe_ops = sema.get_unsafe_ops_for_unsafe_block(block);
812810
for unsafe_op in unsafe_ops {
813811
push_to_highlights(unsafe_op.file_id, Some(unsafe_op.value.text_range()));
814812
}
@@ -2535,4 +2533,21 @@ fn foo() {
25352533
"#,
25362534
);
25372535
}
2536+
2537+
#[test]
2538+
fn different_unsafe_block() {
2539+
check(
2540+
r#"
2541+
fn main() {
2542+
unsafe$0 {
2543+
// ^^^^^^
2544+
*(0 as *const u8)
2545+
// ^^^^^^^^^^^^^^^^^
2546+
};
2547+
unsafe { *(1 as *const u8) };
2548+
unsafe { *(2 as *const u8) };
2549+
}
2550+
"#,
2551+
);
2552+
}
25382553
}

0 commit comments

Comments
 (0)