Unnamed repository; edit this file 'description' to name the repository.
-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 7c2829c855..2933d488a1 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 2ed62372ae..8d75e01029 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 c853b924b2..e7ebaa1d46 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::{