Move is_inside_unsafe
to Semantics
impl
This commit is contained in:
parent
3bfe7040e8
commit
608dc492ea
@ -50,8 +50,8 @@ use hir_def::{
|
|||||||
per_ns::PerNs,
|
per_ns::PerNs,
|
||||||
resolver::{HasResolver, Resolver},
|
resolver::{HasResolver, Resolver},
|
||||||
src::HasSource as _,
|
src::HasSource as _,
|
||||||
AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, EnumId, EnumVariantId,
|
AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
|
||||||
FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
|
EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
|
||||||
LocalEnumVariantId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId,
|
LocalEnumVariantId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId,
|
||||||
TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
|
TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
|
||||||
};
|
};
|
||||||
@ -107,16 +107,13 @@ pub use {
|
|||||||
hir_def::{
|
hir_def::{
|
||||||
adt::StructKind,
|
adt::StructKind,
|
||||||
attr::{Attr, Attrs, AttrsWithOwner, Documentation},
|
attr::{Attr, Attrs, AttrsWithOwner, Documentation},
|
||||||
body::{Body, BodySourceMap},
|
|
||||||
builtin_attr::AttributeTemplate,
|
builtin_attr::AttributeTemplate,
|
||||||
expr::Expr,
|
|
||||||
find_path::PrefixKind,
|
find_path::PrefixKind,
|
||||||
import_map,
|
import_map,
|
||||||
nameres::ModuleSource,
|
nameres::ModuleSource,
|
||||||
path::{ModPath, PathKind},
|
path::{ModPath, PathKind},
|
||||||
type_ref::{Mutability, TypeRef},
|
type_ref::{Mutability, TypeRef},
|
||||||
visibility::Visibility,
|
visibility::Visibility,
|
||||||
DefWithBodyId,
|
|
||||||
},
|
},
|
||||||
hir_expand::{
|
hir_expand::{
|
||||||
name::{known, Name},
|
name::{known, Name},
|
||||||
|
@ -5,11 +5,14 @@ mod source_to_def;
|
|||||||
use std::{cell::RefCell, fmt, iter, mem, ops};
|
use std::{cell::RefCell, fmt, iter, mem, ops};
|
||||||
|
|
||||||
use base_db::{FileId, FileRange};
|
use base_db::{FileId, FileRange};
|
||||||
|
use either::Either;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
body, macro_id_to_def_id,
|
body,
|
||||||
|
expr::Expr,
|
||||||
|
macro_id_to_def_id,
|
||||||
resolver::{self, HasResolver, Resolver, TypeNs},
|
resolver::{self, HasResolver, Resolver, TypeNs},
|
||||||
type_ref::Mutability,
|
type_ref::Mutability,
|
||||||
AsMacroCall, FunctionId, MacroId, TraitId, VariantId,
|
AsMacroCall, DefWithBodyId, FunctionId, MacroId, TraitId, VariantId,
|
||||||
};
|
};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
db::AstDatabase,
|
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> {
|
pub fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
|
||||||
let src = self.imp.find_file(src.syntax()).with_value(src).cloned();
|
self.imp.to_def(src)
|
||||||
T::to_def(&self.imp, src)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_module_def(&self, file: FileId) -> Option<Module> {
|
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 {
|
pub fn is_unsafe_ident_pat(&self, ident_pat: &ast::IdentPat) -> bool {
|
||||||
self.imp.is_unsafe_ident_pat(ident_pat)
|
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> {
|
impl<'db> SemanticsImpl<'db> {
|
||||||
@ -1243,6 +1250,11 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
f(&mut ctx)
|
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> {
|
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)
|
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))
|
.map(|ty| ty.original.is_packed(self.db))
|
||||||
.unwrap_or(false)
|
.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(
|
fn macro_call_to_macro_id(
|
||||||
|
@ -3,17 +3,9 @@
|
|||||||
//! let _: u32 = /* <never-to-any> */ loop {};
|
//! let _: u32 = /* <never-to-any> */ loop {};
|
||||||
//! let _: &u32 = /* &* */ &mut 0;
|
//! let _: &u32 = /* &* */ &mut 0;
|
||||||
//! ```
|
//! ```
|
||||||
use either::Either;
|
use hir::{Adjust, AutoBorrow, Mutability, OverloadedDeref, PointerCast, Safety, Semantics};
|
||||||
use hir::{
|
|
||||||
db::DefDatabase, Adjust, AutoBorrow, InFile, Mutability, OverloadedDeref, PointerCast, Safety,
|
|
||||||
Semantics,
|
|
||||||
};
|
|
||||||
use ide_db::RootDatabase;
|
use ide_db::RootDatabase;
|
||||||
|
use syntax::ast::{self, AstNode};
|
||||||
use syntax::{
|
|
||||||
ast::{self, AstNode},
|
|
||||||
SyntaxNode,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{AdjustmentHints, InlayHint, InlayHintsConfig, InlayKind};
|
use crate::{AdjustmentHints, InlayHint, InlayHintsConfig, InlayKind};
|
||||||
|
|
||||||
@ -23,7 +15,7 @@ pub(super) fn hints(
|
|||||||
config: &InlayHintsConfig,
|
config: &InlayHintsConfig,
|
||||||
expr: &ast::Expr,
|
expr: &ast::Expr,
|
||||||
) -> Option<()> {
|
) -> 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;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,59 +113,6 @@ pub(super) fn hints(
|
|||||||
Some(())
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user