about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2022-12-21 20:34:49 +0000
committerMaybe Waffle <waffle.lapkin@gmail.com>2022-12-21 20:36:05 +0000
commit608dc492ea9adaed2ae0cfee03fd5a6e398032c5 (patch)
tree06ef674b15c398ae7a89fc19d1120d863e54ba65
parent3bfe7040e8321e8fbe3c5bdc8660dae1488838d1 (diff)
downloadrust-608dc492ea9adaed2ae0cfee03fd5a6e398032c5.tar.gz
rust-608dc492ea9adaed2ae0cfee03fd5a6e398032c5.zip
Move `is_inside_unsafe` to `Semantics` impl
-rw-r--r--crates/hir/src/lib.rs7
-rw-r--r--crates/hir/src/semantics.rs73
-rw-r--r--crates/ide/src/inlay_hints/adjustment.rs67
3 files changed, 74 insertions, 73 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 7c2829c855c..2933d488a18 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -50,8 +50,8 @@ use hir_def::{
     per_ns::PerNs,
     resolver::{HasResolver, Resolver},
     src::HasSource as _,
-    AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, EnumId, EnumVariantId,
-    FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
+    AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
+    EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
     LocalEnumVariantId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId,
     TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
 };
@@ -107,16 +107,13 @@ pub use {
     hir_def::{
         adt::StructKind,
         attr::{Attr, Attrs, AttrsWithOwner, Documentation},
-        body::{Body, BodySourceMap},
         builtin_attr::AttributeTemplate,
-        expr::Expr,
         find_path::PrefixKind,
         import_map,
         nameres::ModuleSource,
         path::{ModPath, PathKind},
         type_ref::{Mutability, TypeRef},
         visibility::Visibility,
-        DefWithBodyId,
     },
     hir_expand::{
         name::{known, Name},
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 2ed62372ae2..8d75e01029b 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -5,11 +5,14 @@ mod source_to_def;
 use std::{cell::RefCell, fmt, iter, mem, ops};
 
 use base_db::{FileId, FileRange};
+use either::Either;
 use hir_def::{
-    body, macro_id_to_def_id,
+    body,
+    expr::Expr,
+    macro_id_to_def_id,
     resolver::{self, HasResolver, Resolver, TypeNs},
     type_ref::Mutability,
-    AsMacroCall, FunctionId, MacroId, TraitId, VariantId,
+    AsMacroCall, DefWithBodyId, FunctionId, MacroId, TraitId, VariantId,
 };
 use hir_expand::{
     db::AstDatabase,
@@ -438,8 +441,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
     }
 
     pub fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
-        let src = self.imp.find_file(src.syntax()).with_value(src).cloned();
-        T::to_def(&self.imp, src)
+        self.imp.to_def(src)
     }
 
     pub fn to_module_def(&self, file: FileId) -> Option<Module> {
@@ -481,6 +483,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
     pub fn is_unsafe_ident_pat(&self, ident_pat: &ast::IdentPat) -> bool {
         self.imp.is_unsafe_ident_pat(ident_pat)
     }
+
+    /// Returns `true` if the `node` is inside an `unsafe` context.
+    pub fn is_inside_unsafe(&self, node: &SyntaxNode) -> bool {
+        self.imp.is_inside_unsafe(node)
+    }
 }
 
 impl<'db> SemanticsImpl<'db> {
@@ -1243,6 +1250,11 @@ impl<'db> SemanticsImpl<'db> {
         f(&mut ctx)
     }
 
+    fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
+        let src = self.find_file(src.syntax()).with_value(src).cloned();
+        T::to_def(&self, src)
+    }
+
     fn to_module_def(&self, file: FileId) -> impl Iterator<Item = Module> {
         self.with_ctx(|ctx| ctx.file_to_def(file)).into_iter().map(Module::from)
     }
@@ -1458,6 +1470,59 @@ impl<'db> SemanticsImpl<'db> {
             .map(|ty| ty.original.is_packed(self.db))
             .unwrap_or(false)
     }
+
+    fn is_inside_unsafe(&self, node: &SyntaxNode) -> bool {
+        let item_or_variant = |ancestor: SyntaxNode| {
+            if ast::Item::can_cast(ancestor.kind()) {
+                ast::Item::cast(ancestor).map(Either::Left)
+            } else {
+                ast::Variant::cast(ancestor).map(Either::Right)
+            }
+        };
+        let Some(enclosing_item) = node.ancestors().find_map(item_or_variant) else { return false };
+
+        let def = match &enclosing_item {
+            Either::Left(ast::Item::Fn(it)) => {
+                self.to_def(it).map(<_>::into).map(DefWithBodyId::FunctionId)
+            }
+            Either::Left(ast::Item::Const(it)) => {
+                self.to_def(it).map(<_>::into).map(DefWithBodyId::ConstId)
+            }
+            Either::Left(ast::Item::Static(it)) => {
+                self.to_def(it).map(<_>::into).map(DefWithBodyId::StaticId)
+            }
+            Either::Left(_) => None,
+            Either::Right(it) => self.to_def(it).map(<_>::into).map(DefWithBodyId::VariantId),
+        };
+        let Some(def) = def else { return false };
+        let enclosing_node = enclosing_item.as_ref().either(|i| i.syntax(), |v| v.syntax());
+
+        if ast::Fn::cast(enclosing_node.clone()).and_then(|f| f.unsafe_token()).is_some() {
+            return true;
+        }
+
+        let (body, source_map) = self.db.body_with_source_map(def);
+
+        let file_id = self.find_file(node).file_id;
+
+        let Some(mut parent) = node.parent() else { return false };
+        loop {
+            if &parent == enclosing_node {
+                break false;
+            }
+
+            if let Some(parent) = ast::Expr::cast(parent.clone()) {
+                if let Some(expr_id) = source_map.node_expr(InFile { file_id, value: &parent }) {
+                    if let Expr::Unsafe { .. } = body[expr_id] {
+                        break true;
+                    }
+                }
+            }
+
+            let Some(parent_) = parent.parent() else { break false };
+            parent = parent_;
+        }
+    }
 }
 
 fn macro_call_to_macro_id(
diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs
index c853b924b2f..e7ebaa1d468 100644
--- a/crates/ide/src/inlay_hints/adjustment.rs
+++ b/crates/ide/src/inlay_hints/adjustment.rs
@@ -3,17 +3,9 @@
 //! let _: u32  = /* <never-to-any> */ loop {};
 //! let _: &u32 = /* &* */ &mut 0;
 //! ```
-use either::Either;
-use hir::{
-    db::DefDatabase, Adjust, AutoBorrow, InFile, Mutability, OverloadedDeref, PointerCast, Safety,
-    Semantics,
-};
+use hir::{Adjust, AutoBorrow, Mutability, OverloadedDeref, PointerCast, Safety, Semantics};
 use ide_db::RootDatabase;
-
-use syntax::{
-    ast::{self, AstNode},
-    SyntaxNode,
-};
+use syntax::ast::{self, AstNode};
 
 use crate::{AdjustmentHints, InlayHint, InlayHintsConfig, InlayKind};
 
@@ -23,7 +15,7 @@ pub(super) fn hints(
     config: &InlayHintsConfig,
     expr: &ast::Expr,
 ) -> Option<()> {
-    if config.adjustment_hints_hide_outside_unsafe && !is_inside_unsafe(sema, expr.syntax()) {
+    if config.adjustment_hints_hide_outside_unsafe && !sema.is_inside_unsafe(expr.syntax()) {
         return None;
     }
 
@@ -121,59 +113,6 @@ pub(super) fn hints(
     Some(())
 }
 
-fn is_inside_unsafe(sema: &Semantics<'_, RootDatabase>, node: &SyntaxNode) -> bool {
-    let item_or_variant = |ancestor: SyntaxNode| {
-        if ast::Item::can_cast(ancestor.kind()) {
-            ast::Item::cast(ancestor).map(Either::Left)
-        } else {
-            ast::Variant::cast(ancestor).map(Either::Right)
-        }
-    };
-    let Some(enclosing_item) = node.ancestors().find_map(item_or_variant) else { return false };
-
-    let def = match &enclosing_item {
-        Either::Left(ast::Item::Fn(it)) => {
-            sema.to_def(it).map(<_>::into).map(hir::DefWithBodyId::FunctionId)
-        }
-        Either::Left(ast::Item::Const(it)) => {
-            sema.to_def(it).map(<_>::into).map(hir::DefWithBodyId::ConstId)
-        }
-        Either::Left(ast::Item::Static(it)) => {
-            sema.to_def(it).map(<_>::into).map(hir::DefWithBodyId::StaticId)
-        }
-        Either::Left(_) => None,
-        Either::Right(it) => sema.to_def(it).map(<_>::into).map(hir::DefWithBodyId::VariantId),
-    };
-    let Some(def) = def else { return false };
-    let enclosing_node = enclosing_item.as_ref().either(|i| i.syntax(), |v| v.syntax());
-
-    if ast::Fn::cast(enclosing_node.clone()).and_then(|f| f.unsafe_token()).is_some() {
-        return true;
-    }
-
-    let (body, source_map) = sema.db.body_with_source_map(def);
-
-    let file_id = sema.hir_file_for(node);
-
-    let Some(mut parent) = node.parent() else { return false };
-    loop {
-        if &parent == enclosing_node {
-            break false;
-        }
-
-        if let Some(parent) = ast::Expr::cast(parent.clone()) {
-            if let Some(expr_id) = source_map.node_expr(InFile { file_id, value: &parent }) {
-                if let hir::Expr::Unsafe { .. } = body[expr_id] {
-                    break true;
-                }
-            }
-        }
-
-        let Some(parent_) = parent.parent() else { break false };
-        parent = parent_;
-    }
-}
-
 #[cfg(test)]
 mod tests {
     use crate::{