mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-22 20:03:37 +00:00
Add an option to hide adjustment hints outside of unsafe blocks
This commit is contained in:
parent
4748357045
commit
3bfe7040e8
@ -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, DefWithBodyId, EnumId,
|
AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, EnumId, EnumVariantId,
|
||||||
EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
|
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,13 +107,16 @@ 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},
|
||||||
|
@ -28,6 +28,7 @@ pub struct InlayHintsConfig {
|
|||||||
pub parameter_hints: bool,
|
pub parameter_hints: bool,
|
||||||
pub chaining_hints: bool,
|
pub chaining_hints: bool,
|
||||||
pub adjustment_hints: AdjustmentHints,
|
pub adjustment_hints: AdjustmentHints,
|
||||||
|
pub adjustment_hints_hide_outside_unsafe: bool,
|
||||||
pub closure_return_type_hints: ClosureReturnTypeHints,
|
pub closure_return_type_hints: ClosureReturnTypeHints,
|
||||||
pub binding_mode_hints: bool,
|
pub binding_mode_hints: bool,
|
||||||
pub lifetime_elision_hints: LifetimeElisionHints,
|
pub lifetime_elision_hints: LifetimeElisionHints,
|
||||||
@ -343,6 +344,7 @@ mod tests {
|
|||||||
lifetime_elision_hints: LifetimeElisionHints::Never,
|
lifetime_elision_hints: LifetimeElisionHints::Never,
|
||||||
closure_return_type_hints: ClosureReturnTypeHints::Never,
|
closure_return_type_hints: ClosureReturnTypeHints::Never,
|
||||||
adjustment_hints: AdjustmentHints::Never,
|
adjustment_hints: AdjustmentHints::Never,
|
||||||
|
adjustment_hints_hide_outside_unsafe: false,
|
||||||
binding_mode_hints: false,
|
binding_mode_hints: false,
|
||||||
hide_named_constructor_hints: false,
|
hide_named_constructor_hints: false,
|
||||||
hide_closure_initialization_hints: false,
|
hide_closure_initialization_hints: false,
|
||||||
|
@ -3,10 +3,17 @@
|
|||||||
//! let _: u32 = /* <never-to-any> */ loop {};
|
//! let _: u32 = /* <never-to-any> */ loop {};
|
||||||
//! let _: &u32 = /* &* */ &mut 0;
|
//! let _: &u32 = /* &* */ &mut 0;
|
||||||
//! ```
|
//! ```
|
||||||
use hir::{Adjust, AutoBorrow, Mutability, OverloadedDeref, PointerCast, Safety, Semantics};
|
use either::Either;
|
||||||
|
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};
|
||||||
|
|
||||||
@ -16,6 +23,10 @@ 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()) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
if config.adjustment_hints == AdjustmentHints::Never {
|
if config.adjustment_hints == AdjustmentHints::Never {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -110,6 +121,59 @@ 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::{
|
||||||
@ -233,4 +297,96 @@ fn or_else() {
|
|||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn adjustment_hints_unsafe_only() {
|
||||||
|
check_with_config(
|
||||||
|
InlayHintsConfig {
|
||||||
|
adjustment_hints: AdjustmentHints::Always,
|
||||||
|
adjustment_hints_hide_outside_unsafe: true,
|
||||||
|
..DISABLED_CONFIG
|
||||||
|
},
|
||||||
|
r#"
|
||||||
|
unsafe fn enabled() {
|
||||||
|
f(&&());
|
||||||
|
//^^^^&
|
||||||
|
//^^^^*
|
||||||
|
//^^^^*
|
||||||
|
}
|
||||||
|
|
||||||
|
fn disabled() {
|
||||||
|
f(&&());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mixed() {
|
||||||
|
f(&&());
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
f(&&());
|
||||||
|
//^^^^&
|
||||||
|
//^^^^*
|
||||||
|
//^^^^*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const _: () = {
|
||||||
|
f(&&());
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
f(&&());
|
||||||
|
//^^^^&
|
||||||
|
//^^^^*
|
||||||
|
//^^^^*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static STATIC: () = {
|
||||||
|
f(&&());
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
f(&&());
|
||||||
|
//^^^^&
|
||||||
|
//^^^^*
|
||||||
|
//^^^^*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum E {
|
||||||
|
Disable = { f(&&()); 0 },
|
||||||
|
Enable = unsafe { f(&&()); 1 },
|
||||||
|
//^^^^&
|
||||||
|
//^^^^*
|
||||||
|
//^^^^*
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn f(_: &()) {}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn adjustment_hints_unsafe_only_with_item() {
|
||||||
|
check_with_config(
|
||||||
|
InlayHintsConfig {
|
||||||
|
adjustment_hints: AdjustmentHints::Always,
|
||||||
|
adjustment_hints_hide_outside_unsafe: true,
|
||||||
|
..DISABLED_CONFIG
|
||||||
|
},
|
||||||
|
r#"
|
||||||
|
fn a() {
|
||||||
|
struct Struct;
|
||||||
|
impl Struct {
|
||||||
|
fn by_ref(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = Struct.by_ref();
|
||||||
|
|
||||||
|
_ = unsafe { Struct.by_ref() };
|
||||||
|
//^^^^^^(
|
||||||
|
//^^^^^^&
|
||||||
|
//^^^^^^)
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,7 @@ impl StaticIndex<'_> {
|
|||||||
closure_return_type_hints: crate::ClosureReturnTypeHints::WithBlock,
|
closure_return_type_hints: crate::ClosureReturnTypeHints::WithBlock,
|
||||||
lifetime_elision_hints: crate::LifetimeElisionHints::Never,
|
lifetime_elision_hints: crate::LifetimeElisionHints::Never,
|
||||||
adjustment_hints: crate::AdjustmentHints::Never,
|
adjustment_hints: crate::AdjustmentHints::Never,
|
||||||
|
adjustment_hints_hide_outside_unsafe: false,
|
||||||
hide_named_constructor_hints: false,
|
hide_named_constructor_hints: false,
|
||||||
hide_closure_initialization_hints: false,
|
hide_closure_initialization_hints: false,
|
||||||
param_names_for_lifetime_elision_hints: false,
|
param_names_for_lifetime_elision_hints: false,
|
||||||
|
@ -329,6 +329,8 @@ config_data! {
|
|||||||
inlayHints_closureReturnTypeHints_enable: ClosureReturnTypeHintsDef = "\"never\"",
|
inlayHints_closureReturnTypeHints_enable: ClosureReturnTypeHintsDef = "\"never\"",
|
||||||
/// Whether to show inlay hints for type adjustments.
|
/// Whether to show inlay hints for type adjustments.
|
||||||
inlayHints_expressionAdjustmentHints_enable: AdjustmentHintsDef = "\"never\"",
|
inlayHints_expressionAdjustmentHints_enable: AdjustmentHintsDef = "\"never\"",
|
||||||
|
/// Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.
|
||||||
|
inlayHints_expressionAdjustmentHints_hideOutsideUnsafe: bool = "false",
|
||||||
/// Whether to show inlay type hints for elided lifetimes in function signatures.
|
/// Whether to show inlay type hints for elided lifetimes in function signatures.
|
||||||
inlayHints_lifetimeElisionHints_enable: LifetimeElisionDef = "\"never\"",
|
inlayHints_lifetimeElisionHints_enable: LifetimeElisionDef = "\"never\"",
|
||||||
/// Whether to prefer using parameter names as the name for elided lifetime hints if possible.
|
/// Whether to prefer using parameter names as the name for elided lifetime hints if possible.
|
||||||
@ -1224,6 +1226,9 @@ impl Config {
|
|||||||
},
|
},
|
||||||
AdjustmentHintsDef::Reborrow => ide::AdjustmentHints::ReborrowOnly,
|
AdjustmentHintsDef::Reborrow => ide::AdjustmentHints::ReborrowOnly,
|
||||||
},
|
},
|
||||||
|
adjustment_hints_hide_outside_unsafe: self
|
||||||
|
.data
|
||||||
|
.inlayHints_expressionAdjustmentHints_hideOutsideUnsafe,
|
||||||
binding_mode_hints: self.data.inlayHints_bindingModeHints_enable,
|
binding_mode_hints: self.data.inlayHints_bindingModeHints_enable,
|
||||||
param_names_for_lifetime_elision_hints: self
|
param_names_for_lifetime_elision_hints: self
|
||||||
.data
|
.data
|
||||||
|
@ -459,6 +459,11 @@ Whether to show inlay type hints for return types of closures.
|
|||||||
--
|
--
|
||||||
Whether to show inlay hints for type adjustments.
|
Whether to show inlay hints for type adjustments.
|
||||||
--
|
--
|
||||||
|
[[rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe]]rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe (default: `false`)::
|
||||||
|
+
|
||||||
|
--
|
||||||
|
Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.
|
||||||
|
--
|
||||||
[[rust-analyzer.inlayHints.lifetimeElisionHints.enable]]rust-analyzer.inlayHints.lifetimeElisionHints.enable (default: `"never"`)::
|
[[rust-analyzer.inlayHints.lifetimeElisionHints.enable]]rust-analyzer.inlayHints.lifetimeElisionHints.enable (default: `"never"`)::
|
||||||
+
|
+
|
||||||
--
|
--
|
||||||
|
@ -975,6 +975,11 @@
|
|||||||
"Only show auto borrow and dereference adjustment hints."
|
"Only show auto borrow and dereference adjustment hints."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe": {
|
||||||
|
"markdownDescription": "Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.",
|
||||||
|
"default": false,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"rust-analyzer.inlayHints.lifetimeElisionHints.enable": {
|
"rust-analyzer.inlayHints.lifetimeElisionHints.enable": {
|
||||||
"markdownDescription": "Whether to show inlay type hints for elided lifetimes in function signatures.",
|
"markdownDescription": "Whether to show inlay type hints for elided lifetimes in function signatures.",
|
||||||
"default": "never",
|
"default": "never",
|
||||||
|
Loading…
Reference in New Issue
Block a user