diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:41 +0000 |
commit | 4f9fe856a25ab29345b90e7725509e9ee38a37be (patch) | |
tree | e4ffd8a9374cae7b21f7cbfb352927e0e074aff6 /src/tools/rust-analyzer/crates/ide/src/inlay_hints | |
parent | Adding upstream version 1.68.2+dfsg1. (diff) | |
download | rustc-4f9fe856a25ab29345b90e7725509e9ee38a37be.tar.xz rustc-4f9fe856a25ab29345b90e7725509e9ee38a37be.zip |
Adding upstream version 1.69.0+dfsg1.upstream/1.69.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tools/rust-analyzer/crates/ide/src/inlay_hints')
10 files changed, 438 insertions, 368 deletions
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs index bdd7c05e0..188eb7f97 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs @@ -3,15 +3,19 @@ //! let _: u32 = /* <never-to-any> */ loop {}; //! let _: &u32 = /* &* */ &mut 0; //! ``` -use hir::{Adjust, AutoBorrow, Mutability, OverloadedDeref, PointerCast, Safety, Semantics}; +use hir::{Adjust, Adjustment, AutoBorrow, HirDisplay, Mutability, PointerCast, Safety, Semantics}; use ide_db::RootDatabase; +use stdx::never; use syntax::{ ast::{self, make, AstNode}, ted, }; -use crate::{AdjustmentHints, AdjustmentHintsMode, InlayHint, InlayHintsConfig, InlayKind}; +use crate::{ + AdjustmentHints, AdjustmentHintsMode, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind, + InlayTooltip, +}; pub(super) fn hints( acc: &mut Vec<InlayHint>, @@ -44,27 +48,12 @@ pub(super) fn hints( mode_and_needs_parens_for_adjustment_hints(expr, config.adjustment_hints_mode); if needs_outer_parens { - acc.push(InlayHint { - range: expr.syntax().text_range(), - kind: InlayKind::OpeningParenthesis, - label: "(".into(), - tooltip: None, - }); + acc.push(InlayHint::opening_paren(expr.syntax().text_range())); } if postfix && needs_inner_parens { - acc.push(InlayHint { - range: expr.syntax().text_range(), - kind: InlayKind::OpeningParenthesis, - label: "(".into(), - tooltip: None, - }); - acc.push(InlayHint { - range: expr.syntax().text_range(), - kind: InlayKind::ClosingParenthesis, - label: ")".into(), - tooltip: None, - }); + acc.push(InlayHint::opening_paren(expr.syntax().text_range())); + acc.push(InlayHint::closing_paren(expr.syntax().text_range())); } let (mut tmp0, mut tmp1); @@ -76,72 +65,71 @@ pub(super) fn hints( &mut tmp1 }; - for adjustment in iter { - if adjustment.source == adjustment.target { + for Adjustment { source, target, kind } in iter { + if source == target { continue; } // FIXME: Add some nicer tooltips to each of these - let text = match adjustment.kind { + let (text, coercion) = match kind { Adjust::NeverToAny if config.adjustment_hints == AdjustmentHints::Always => { - "<never-to-any>" + ("<never-to-any>", "never to any") + } + Adjust::Deref(_) => ("*", "dereference"), + Adjust::Borrow(AutoBorrow::Ref(Mutability::Shared)) => ("&", "borrow"), + Adjust::Borrow(AutoBorrow::Ref(Mutability::Mut)) => ("&mut ", "unique borrow"), + Adjust::Borrow(AutoBorrow::RawPtr(Mutability::Shared)) => { + ("&raw const ", "const pointer borrow") + } + Adjust::Borrow(AutoBorrow::RawPtr(Mutability::Mut)) => { + ("&raw mut ", "mut pointer borrow") } - Adjust::Deref(None) => "*", - Adjust::Deref(Some(OverloadedDeref(Mutability::Mut))) => "*", - Adjust::Deref(Some(OverloadedDeref(Mutability::Shared))) => "*", - Adjust::Borrow(AutoBorrow::Ref(Mutability::Shared)) => "&", - Adjust::Borrow(AutoBorrow::Ref(Mutability::Mut)) => "&mut ", - Adjust::Borrow(AutoBorrow::RawPtr(Mutability::Shared)) => "&raw const ", - Adjust::Borrow(AutoBorrow::RawPtr(Mutability::Mut)) => "&raw mut ", // some of these could be represented via `as` casts, but that's not too nice and // handling everything as a prefix expr makes the `(` and `)` insertion easier Adjust::Pointer(cast) if config.adjustment_hints == AdjustmentHints::Always => { match cast { - PointerCast::ReifyFnPointer => "<fn-item-to-fn-pointer>", - PointerCast::UnsafeFnPointer => "<safe-fn-pointer-to-unsafe-fn-pointer>", + PointerCast::ReifyFnPointer => { + ("<fn-item-to-fn-pointer>", "fn item to fn pointer") + } + PointerCast::UnsafeFnPointer => ( + "<safe-fn-pointer-to-unsafe-fn-pointer>", + "safe fn pointer to unsafe fn pointer", + ), PointerCast::ClosureFnPointer(Safety::Unsafe) => { - "<closure-to-unsafe-fn-pointer>" + ("<closure-to-unsafe-fn-pointer>", "closure to unsafe fn pointer") + } + PointerCast::ClosureFnPointer(Safety::Safe) => { + ("<closure-to-fn-pointer>", "closure to fn pointer") + } + PointerCast::MutToConstPointer => { + ("<mut-ptr-to-const-ptr>", "mut ptr to const ptr") } - PointerCast::ClosureFnPointer(Safety::Safe) => "<closure-to-fn-pointer>", - PointerCast::MutToConstPointer => "<mut-ptr-to-const-ptr>", - PointerCast::ArrayToPointer => "<array-ptr-to-element-ptr>", - PointerCast::Unsize => "<unsize>", + PointerCast::ArrayToPointer => ("<array-ptr-to-element-ptr>", ""), + PointerCast::Unsize => ("<unsize>", "unsize"), } } _ => continue, }; acc.push(InlayHint { range: expr.syntax().text_range(), - kind: if postfix { - InlayKind::AdjustmentHintPostfix - } else { - InlayKind::AdjustmentHint - }, - label: if postfix { format!(".{}", text.trim_end()).into() } else { text.into() }, - tooltip: None, + kind: if postfix { InlayKind::AdjustmentPostfix } else { InlayKind::Adjustment }, + label: InlayHintLabel::simple( + if postfix { format!(".{}", text.trim_end()) } else { text.to_owned() }, + Some(InlayTooltip::Markdown(format!( + "`{}` → `{}` ({coercion} coercion)", + source.display(sema.db), + target.display(sema.db), + ))), + None, + ), }); } if !postfix && needs_inner_parens { - acc.push(InlayHint { - range: expr.syntax().text_range(), - kind: InlayKind::OpeningParenthesis, - label: "(".into(), - tooltip: None, - }); - acc.push(InlayHint { - range: expr.syntax().text_range(), - kind: InlayKind::ClosingParenthesis, - label: ")".into(), - tooltip: None, - }); + acc.push(InlayHint::opening_paren(expr.syntax().text_range())); + acc.push(InlayHint::closing_paren(expr.syntax().text_range())); } if needs_outer_parens { - acc.push(InlayHint { - range: expr.syntax().text_range(), - kind: InlayKind::ClosingParenthesis, - label: ")".into(), - tooltip: None, - }); + acc.push(InlayHint::closing_paren(expr.syntax().text_range())); } Some(()) } @@ -223,16 +211,21 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, ted::replace(expr.syntax(), dummy_expr.syntax()); let parent = dummy_expr.syntax().parent(); - let expr = if postfix { - let ast::Expr::TryExpr(e) = &dummy_expr else { unreachable!() }; - let Some(ast::Expr::ParenExpr(e)) = e.expr() else { unreachable!() }; + let Some(expr) = (|| { + if postfix { + let ast::Expr::TryExpr(e) = &dummy_expr else { return None }; + let Some(ast::Expr::ParenExpr(e)) = e.expr() else { return None }; - e.expr().unwrap() - } else { - let ast::Expr::RefExpr(e) = &dummy_expr else { unreachable!() }; - let Some(ast::Expr::ParenExpr(e)) = e.expr() else { unreachable!() }; + e.expr() + } else { + let ast::Expr::RefExpr(e) = &dummy_expr else { return None }; + let Some(ast::Expr::ParenExpr(e)) = e.expr() else { return None }; - e.expr().unwrap() + e.expr() + } + })() else { + never!("broken syntax tree?\n{:?}\n{:?}", expr, dummy_expr); + return (true, true) }; // At this point diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs index adec19c76..4af7f9bdb 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs @@ -12,9 +12,7 @@ use syntax::{ match_ast, }; -use crate::{ - inlay_hints::closure_has_block_body, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip, -}; +use crate::{inlay_hints::closure_has_block_body, InlayHint, InlayHintsConfig, InlayKind}; use super::label_of_ty; @@ -22,7 +20,7 @@ pub(super) fn hints( acc: &mut Vec<InlayHint>, famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - file_id: FileId, + _file_id: FileId, pat: &ast::IdentPat, ) -> Option<()> { if !config.type_hints { @@ -50,12 +48,8 @@ pub(super) fn hints( Some(name) => name.syntax().text_range(), None => pat.syntax().text_range(), }, - kind: InlayKind::TypeHint, + kind: InlayKind::Type, label, - tooltip: pat - .name() - .map(|it| it.syntax().text_range()) - .map(|it| InlayTooltip::HoverRanged(file_id, it)), }); Some(()) @@ -73,28 +67,23 @@ fn should_not_display_type_hint( return true; } - if let Some(hir::Adt::Struct(s)) = pat_ty.as_adt() { - if s.fields(db).is_empty() && s.name(db).to_smol_str() == bind_pat.to_string() { - return true; - } - } - - if config.hide_closure_initialization_hints { - if let Some(parent) = bind_pat.syntax().parent() { - if let Some(it) = ast::LetStmt::cast(parent) { - if let Some(ast::Expr::ClosureExpr(closure)) = it.initializer() { - if closure_has_block_body(&closure) { - return true; - } - } - } - } + if sema.resolve_bind_pat_to_const(bind_pat).is_some() { + return true; } for node in bind_pat.syntax().ancestors() { match_ast! { match node { - ast::LetStmt(it) => return it.ty().is_some(), + ast::LetStmt(it) => { + if config.hide_closure_initialization_hints { + if let Some(ast::Expr::ClosureExpr(closure)) = it.initializer() { + if closure_has_block_body(&closure) { + return true; + } + } + } + return it.ty().is_some() + }, // FIXME: We might wanna show type hints in parameters for non-top level patterns as well ast::Param(it) => return it.ty().is_some(), ast::MatchArm(_) => return pat_is_enum_variant(db, bind_pat, pat_ty), @@ -194,8 +183,7 @@ mod tests { use crate::{fixture, inlay_hints::InlayHintsConfig}; use crate::inlay_hints::tests::{ - check, check_expect, check_with_config, DISABLED_CONFIG, DISABLED_CONFIG_WITH_LINKS, - TEST_CONFIG, + check, check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG, }; use crate::ClosureReturnTypeHints; @@ -291,7 +279,7 @@ fn main() { fn iterator_hint_regression_issue_12674() { // Ensure we don't crash while solving the projection type of iterators. check_expect( - InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS }, + InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG }, r#" //- minicore: iterators struct S<T>(T); @@ -322,22 +310,66 @@ fn main(a: SliceIter<'_, Container>) { [ InlayHint { range: 484..554, - kind: ChainingHint, + kind: Chaining, label: [ - "impl Iterator<Item = impl Iterator<Item = &&str>>", - ], - tooltip: Some( - HoverRanged( - FileId( - 0, + "impl ", + InlayHintLabelPart { + text: "Iterator", + linked_location: Some( + FileRange { + file_id: FileId( + 1, + ), + range: 2611..2619, + }, + ), + tooltip: "", + }, + "<", + InlayHintLabelPart { + text: "Item", + linked_location: Some( + FileRange { + file_id: FileId( + 1, + ), + range: 2643..2647, + }, + ), + tooltip: "", + }, + " = impl ", + InlayHintLabelPart { + text: "Iterator", + linked_location: Some( + FileRange { + file_id: FileId( + 1, + ), + range: 2611..2619, + }, + ), + tooltip: "", + }, + "<", + InlayHintLabelPart { + text: "Item", + linked_location: Some( + FileRange { + file_id: FileId( + 1, + ), + range: 2643..2647, + }, ), - 484..554, - ), - ), + tooltip: "", + }, + " = &&str>>", + ], }, InlayHint { range: 484..485, - kind: ChainingHint, + kind: Chaining, label: [ "", InlayHintLabelPart { @@ -350,6 +382,7 @@ fn main(a: SliceIter<'_, Container>) { range: 289..298, }, ), + tooltip: "", }, "<", InlayHintLabelPart { @@ -362,17 +395,10 @@ fn main(a: SliceIter<'_, Container>) { range: 238..247, }, ), + tooltip: "", }, ">", ], - tooltip: Some( - HoverRanged( - FileId( - 0, - ), - 484..485, - ), - ), }, ] "#]], @@ -537,6 +563,21 @@ fn main() { } #[test] + fn const_pats_have_no_type_hints() { + check_types( + r#" +const FOO: usize = 0; + +fn main() { + match 0 { + FOO => (), + _ => () + } +}"#, + ); + } + + #[test] fn let_statement() { check_types( r#" diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs index a0166d004..5d9729263 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs @@ -7,7 +7,7 @@ use ide_db::RootDatabase; use syntax::ast::{self, AstNode}; -use crate::{InlayHint, InlayHintsConfig, InlayKind, InlayTooltip}; +use crate::{InlayHint, InlayHintsConfig, InlayKind}; pub(super) fn hints( acc: &mut Vec<InlayHint>, @@ -29,8 +29,17 @@ pub(super) fn hints( _ => None, }) .last(); - let range = - outer_paren_pat.as_ref().map_or_else(|| pat.syntax(), |it| it.syntax()).text_range(); + let range = outer_paren_pat.as_ref().map_or_else( + || match pat { + // for ident patterns that @ bind a name, render the un-ref patterns in front of the inner pattern + // instead of the name as that makes it more clear and doesn't really change the outcome + ast::Pat::IdentPat(it) => { + it.pat().map_or_else(|| it.syntax().text_range(), |it| it.syntax().text_range()) + } + it => it.syntax().text_range(), + }, + |it| it.syntax().text_range(), + ); let pattern_adjustments = sema.pattern_adjustments(pat); pattern_adjustments.iter().for_each(|ty| { let reference = ty.is_reference(); @@ -40,12 +49,7 @@ pub(super) fn hints( (true, false) => "&", _ => return, }; - acc.push(InlayHint { - range, - kind: InlayKind::BindingModeHint, - label: r.to_string().into(), - tooltip: Some(InlayTooltip::String("Inferred binding mode".into())), - }); + acc.push(InlayHint { range, kind: InlayKind::BindingMode, label: r.to_string().into() }); }); match pat { ast::Pat::IdentPat(pat) if pat.ref_token().is_none() && pat.mut_token().is_none() => { @@ -57,24 +61,13 @@ pub(super) fn hints( }; acc.push(InlayHint { range: pat.syntax().text_range(), - kind: InlayKind::BindingModeHint, + kind: InlayKind::BindingMode, label: bm.to_string().into(), - tooltip: Some(InlayTooltip::String("Inferred binding mode".into())), }); } ast::Pat::OrPat(pat) if !pattern_adjustments.is_empty() && outer_paren_pat.is_none() => { - acc.push(InlayHint { - range: pat.syntax().text_range(), - kind: InlayKind::OpeningParenthesis, - label: "(".into(), - tooltip: None, - }); - acc.push(InlayHint { - range: pat.syntax().text_range(), - kind: InlayKind::ClosingParenthesis, - label: ")".into(), - tooltip: None, - }); + acc.push(InlayHint::opening_paren(pat.syntax().text_range())); + acc.push(InlayHint::closing_paren(pat.syntax().text_range())); } _ => (), } @@ -139,4 +132,20 @@ fn __( }"#, ); } + + #[test] + fn hints_binding_modes_complex_ident_pat() { + check_with_config( + InlayHintsConfig { binding_mode_hints: true, ..DISABLED_CONFIG }, + r#" +struct Struct { + field: &'static str, +} +fn foo(s @ Struct { field, .. }: &Struct) {} + //^^^^^^^^^^^^^^^^^^^^^^^^ref + //^^^^^^^^^^^^^^^^^^^^& + //^^^^^ref +"#, + ); + } } diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs index 8810d5d34..0c54f084c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs @@ -5,7 +5,7 @@ use syntax::{ Direction, NodeOrToken, SyntaxKind, T, }; -use crate::{FileId, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip}; +use crate::{FileId, InlayHint, InlayHintsConfig, InlayKind}; use super::label_of_ty; @@ -13,7 +13,7 @@ pub(super) fn hints( acc: &mut Vec<InlayHint>, famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - file_id: FileId, + _file_id: FileId, expr: &ast::Expr, ) -> Option<()> { if !config.chaining_hints { @@ -59,9 +59,8 @@ pub(super) fn hints( } acc.push(InlayHint { range: expr.syntax().text_range(), - kind: InlayKind::ChainingHint, + kind: InlayKind::Chaining, label: label_of_ty(famous_defs, config, ty)?, - tooltip: Some(InlayTooltip::HoverRanged(file_id, expr.syntax().text_range())), }); } } @@ -73,10 +72,7 @@ mod tests { use expect_test::expect; use crate::{ - inlay_hints::tests::{ - check_expect, check_with_config, DISABLED_CONFIG, DISABLED_CONFIG_WITH_LINKS, - TEST_CONFIG, - }, + inlay_hints::tests::{check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG}, InlayHintsConfig, }; @@ -88,11 +84,7 @@ mod tests { #[test] fn chaining_hints_ignore_comments() { check_expect( - InlayHintsConfig { - type_hints: false, - chaining_hints: true, - ..DISABLED_CONFIG_WITH_LINKS - }, + InlayHintsConfig { type_hints: false, chaining_hints: true, ..DISABLED_CONFIG }, r#" struct A(B); impl A { fn into_b(self) -> B { self.0 } } @@ -111,7 +103,7 @@ fn main() { [ InlayHint { range: 147..172, - kind: ChainingHint, + kind: Chaining, label: [ "", InlayHintLabelPart { @@ -124,21 +116,14 @@ fn main() { range: 63..64, }, ), + tooltip: "", }, "", ], - tooltip: Some( - HoverRanged( - FileId( - 0, - ), - 147..172, - ), - ), }, InlayHint { range: 147..154, - kind: ChainingHint, + kind: Chaining, label: [ "", InlayHintLabelPart { @@ -151,17 +136,10 @@ fn main() { range: 7..8, }, ), + tooltip: "", }, "", ], - tooltip: Some( - HoverRanged( - FileId( - 0, - ), - 147..154, - ), - ), }, ] "#]], @@ -210,33 +188,43 @@ fn main() { [ InlayHint { range: 143..190, - kind: ChainingHint, + kind: Chaining, label: [ - "C", - ], - tooltip: Some( - HoverRanged( - FileId( - 0, + "", + InlayHintLabelPart { + text: "C", + linked_location: Some( + FileRange { + file_id: FileId( + 0, + ), + range: 51..52, + }, ), - 143..190, - ), - ), + tooltip: "", + }, + "", + ], }, InlayHint { range: 143..179, - kind: ChainingHint, + kind: Chaining, label: [ - "B", - ], - tooltip: Some( - HoverRanged( - FileId( - 0, + "", + InlayHintLabelPart { + text: "B", + linked_location: Some( + FileRange { + file_id: FileId( + 0, + ), + range: 29..30, + }, ), - 143..179, - ), - ), + tooltip: "", + }, + "", + ], }, ] "#]], @@ -246,7 +234,7 @@ fn main() { #[test] fn struct_access_chaining_hints() { check_expect( - InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS }, + InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG }, r#" struct A { pub b: B } struct B { pub c: C } @@ -269,7 +257,7 @@ fn main() { [ InlayHint { range: 143..190, - kind: ChainingHint, + kind: Chaining, label: [ "", InlayHintLabelPart { @@ -282,21 +270,14 @@ fn main() { range: 51..52, }, ), + tooltip: "", }, "", ], - tooltip: Some( - HoverRanged( - FileId( - 0, - ), - 143..190, - ), - ), }, InlayHint { range: 143..179, - kind: ChainingHint, + kind: Chaining, label: [ "", InlayHintLabelPart { @@ -309,17 +290,10 @@ fn main() { range: 29..30, }, ), + tooltip: "", }, "", ], - tooltip: Some( - HoverRanged( - FileId( - 0, - ), - 143..179, - ), - ), }, ] "#]], @@ -329,7 +303,7 @@ fn main() { #[test] fn generic_chaining_hints() { check_expect( - InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS }, + InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG }, r#" struct A<T>(T); struct B<T>(T); @@ -353,7 +327,7 @@ fn main() { [ InlayHint { range: 246..283, - kind: ChainingHint, + kind: Chaining, label: [ "", InlayHintLabelPart { @@ -366,6 +340,7 @@ fn main() { range: 23..24, }, ), + tooltip: "", }, "<", InlayHintLabelPart { @@ -378,21 +353,14 @@ fn main() { range: 55..56, }, ), + tooltip: "", }, "<i32, bool>>", ], - tooltip: Some( - HoverRanged( - FileId( - 0, - ), - 246..283, - ), - ), }, InlayHint { range: 246..265, - kind: ChainingHint, + kind: Chaining, label: [ "", InlayHintLabelPart { @@ -405,6 +373,7 @@ fn main() { range: 7..8, }, ), + tooltip: "", }, "<", InlayHintLabelPart { @@ -417,17 +386,10 @@ fn main() { range: 55..56, }, ), + tooltip: "", }, "<i32, bool>>", ], - tooltip: Some( - HoverRanged( - FileId( - 0, - ), - 246..265, - ), - ), }, ] "#]], @@ -437,7 +399,7 @@ fn main() { #[test] fn shorten_iterator_chaining_hints() { check_expect( - InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS }, + InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG }, r#" //- minicore: iterators use core::iter; @@ -463,52 +425,106 @@ fn main() { [ InlayHint { range: 174..241, - kind: ChainingHint, + kind: Chaining, label: [ - "impl Iterator<Item = ()>", - ], - tooltip: Some( - HoverRanged( - FileId( - 0, + "impl ", + InlayHintLabelPart { + text: "Iterator", + linked_location: Some( + FileRange { + file_id: FileId( + 1, + ), + range: 2611..2619, + }, + ), + tooltip: "", + }, + "<", + InlayHintLabelPart { + text: "Item", + linked_location: Some( + FileRange { + file_id: FileId( + 1, + ), + range: 2643..2647, + }, ), - 174..241, - ), - ), + tooltip: "", + }, + " = ()>", + ], }, InlayHint { range: 174..224, - kind: ChainingHint, + kind: Chaining, label: [ - "impl Iterator<Item = ()>", - ], - tooltip: Some( - HoverRanged( - FileId( - 0, + "impl ", + InlayHintLabelPart { + text: "Iterator", + linked_location: Some( + FileRange { + file_id: FileId( + 1, + ), + range: 2611..2619, + }, ), - 174..224, - ), - ), + tooltip: "", + }, + "<", + InlayHintLabelPart { + text: "Item", + linked_location: Some( + FileRange { + file_id: FileId( + 1, + ), + range: 2643..2647, + }, + ), + tooltip: "", + }, + " = ()>", + ], }, InlayHint { range: 174..206, - kind: ChainingHint, + kind: Chaining, label: [ - "impl Iterator<Item = ()>", - ], - tooltip: Some( - HoverRanged( - FileId( - 0, + "impl ", + InlayHintLabelPart { + text: "Iterator", + linked_location: Some( + FileRange { + file_id: FileId( + 1, + ), + range: 2611..2619, + }, ), - 174..206, - ), - ), + tooltip: "", + }, + "<", + InlayHintLabelPart { + text: "Item", + linked_location: Some( + FileRange { + file_id: FileId( + 1, + ), + range: 2643..2647, + }, + ), + tooltip: "", + }, + " = ()>", + ], }, InlayHint { range: 174..189, - kind: ChainingHint, + kind: Chaining, label: [ "&mut ", InlayHintLabelPart { @@ -521,17 +537,10 @@ fn main() { range: 24..30, }, ), + tooltip: "", }, "", ], - tooltip: Some( - HoverRanged( - FileId( - 0, - ), - 174..189, - ), - ), }, ] "#]], @@ -564,7 +573,7 @@ fn main() { [ InlayHint { range: 124..130, - kind: TypeHint, + kind: Type, label: [ "", InlayHintLabelPart { @@ -577,21 +586,14 @@ fn main() { range: 7..13, }, ), + tooltip: "", }, "", ], - tooltip: Some( - HoverRanged( - FileId( - 0, - ), - 124..130, - ), - ), }, InlayHint { range: 145..185, - kind: ChainingHint, + kind: Chaining, label: [ "", InlayHintLabelPart { @@ -604,21 +606,14 @@ fn main() { range: 7..13, }, ), + tooltip: "", }, "", ], - tooltip: Some( - HoverRanged( - FileId( - 0, - ), - 145..185, - ), - ), }, InlayHint { range: 145..168, - kind: ChainingHint, + kind: Chaining, label: [ "", InlayHintLabelPart { @@ -631,32 +626,28 @@ fn main() { range: 7..13, }, ), + tooltip: "", }, "", ], - tooltip: Some( - HoverRanged( - FileId( - 0, - ), - 145..168, - ), - ), }, InlayHint { range: 222..228, - kind: ParameterHint, + kind: Parameter, label: [ - "self", - ], - tooltip: Some( - HoverOffset( - FileId( - 0, + InlayHintLabelPart { + text: "self", + linked_location: Some( + FileRange { + file_id: FileId( + 0, + ), + range: 42..46, + }, ), - 42, - ), - ), + tooltip: "", + }, + ], }, ] "#]], diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs index e340c64c5..14c11be54 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs @@ -10,9 +10,7 @@ use syntax::{ match_ast, SyntaxKind, SyntaxNode, T, }; -use crate::{ - inlay_hints::InlayHintLabelPart, FileId, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind, -}; +use crate::{FileId, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind}; pub(super) fn hints( acc: &mut Vec<InlayHint>, @@ -109,15 +107,11 @@ pub(super) fn hints( return None; } - let linked_location = config - .location_links - .then(|| name_range.map(|range| FileRange { file_id, range })) - .flatten(); + let linked_location = name_range.map(|range| FileRange { file_id, range }); acc.push(InlayHint { range: closing_token.text_range(), - kind: InlayKind::ClosingBraceHint, - label: InlayHintLabel { parts: vec![InlayHintLabelPart { text: label, linked_location }] }, - tooltip: None, // provided by label part location + kind: InlayKind::ClosingBrace, + label: InlayHintLabel::simple(label, None, linked_location), }); None diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs index d9929beaa..f03a18b8e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs @@ -4,7 +4,7 @@ use syntax::ast::{self, AstNode}; use crate::{ inlay_hints::closure_has_block_body, ClosureReturnTypeHints, InlayHint, InlayHintsConfig, - InlayKind, InlayTooltip, + InlayKind, }; use super::label_of_ty; @@ -13,7 +13,7 @@ pub(super) fn hints( acc: &mut Vec<InlayHint>, famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - file_id: FileId, + _file_id: FileId, closure: ast::ClosureExpr, ) -> Option<()> { if config.closure_return_type_hints == ClosureReturnTypeHints::Never { @@ -41,9 +41,8 @@ pub(super) fn hints( } acc.push(InlayHint { range: param_list.syntax().text_range(), - kind: InlayKind::ClosureReturnTypeHint, + kind: InlayKind::ClosureReturnType, label: label_of_ty(famous_defs, config, ty)?, - tooltip: Some(InlayTooltip::HoverRanged(file_id, param_list.syntax().text_range())), }); Some(()) } diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs index f32c4bdf2..5dd51ad11 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs @@ -4,27 +4,43 @@ //! Bar/* = 0*/, //! } //! ``` -use ide_db::{base_db::FileId, famous_defs::FamousDefs}; +use hir::Semantics; +use ide_db::{base_db::FileId, famous_defs::FamousDefs, RootDatabase}; use syntax::ast::{self, AstNode, HasName}; -use crate::{DiscriminantHints, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip}; +use crate::{ + DiscriminantHints, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind, InlayTooltip, +}; -pub(super) fn hints( +pub(super) fn enum_hints( acc: &mut Vec<InlayHint>, FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, _: FileId, - variant: &ast::Variant, + enum_: ast::Enum, ) -> Option<()> { - let field_list = match config.discriminant_hints { - DiscriminantHints::Always => variant.field_list(), - DiscriminantHints::Fieldless => match variant.field_list() { - Some(_) => return None, - None => None, - }, - DiscriminantHints::Never => return None, + let enabled = match config.discriminant_hints { + DiscriminantHints::Always => true, + DiscriminantHints::Fieldless => { + !sema.to_def(&enum_)?.is_data_carrying(sema.db) + || enum_.variant_list()?.variants().any(|v| v.expr().is_some()) + } + DiscriminantHints::Never => false, }; + if !enabled { + return None; + } + for variant in enum_.variant_list()?.variants() { + variant_hints(acc, sema, &variant); + } + None +} +fn variant_hints( + acc: &mut Vec<InlayHint>, + sema: &Semantics<'_, RootDatabase>, + variant: &ast::Variant, +) -> Option<()> { if variant.eq_token().is_some() { return None; } @@ -37,19 +53,22 @@ pub(super) fn hints( let d = v.eval(sema.db); acc.push(InlayHint { - range: match field_list { + range: match variant.field_list() { Some(field_list) => name.syntax().text_range().cover(field_list.syntax().text_range()), None => name.syntax().text_range(), }, - kind: InlayKind::DiscriminantHint, - label: match &d { - Ok(v) => format!("{}", v).into(), - Err(_) => "?".into(), - }, - tooltip: Some(InlayTooltip::String(match &d { - Ok(_) => "enum variant discriminant".into(), - Err(e) => format!("{e:?}").into(), - })), + kind: InlayKind::Discriminant, + label: InlayHintLabel::simple( + match &d { + Ok(v) => format!("{}", v), + Err(_) => "?".into(), + }, + Some(InlayTooltip::String(match &d { + Ok(_) => "enum variant discriminant".into(), + Err(e) => format!("{e:?}").into(), + })), + None, + ), }); Some(()) @@ -86,15 +105,30 @@ mod tests { check_discriminants( r#" enum Enum { - Variant, - //^^^^^^^0 - Variant1, - //^^^^^^^^1 - Variant2, - //^^^^^^^^2 - Variant5 = 5, - Variant6, - //^^^^^^^^6 + Variant, +//^^^^^^^0 + Variant1, +//^^^^^^^^1 + Variant2, +//^^^^^^^^2 + Variant5 = 5, + Variant6, +//^^^^^^^^6 +} +"#, + ); + check_discriminants_fieldless( + r#" +enum Enum { + Variant, +//^^^^^^^0 + Variant1, +//^^^^^^^^1 + Variant2, +//^^^^^^^^2 + Variant5 = 5, + Variant6, +//^^^^^^^^6 } "#, ); @@ -128,8 +162,22 @@ enum Enum { enum Enum { Variant(), Variant1, + Variant2 {}, + Variant3, + Variant5, + Variant6, +} +"#, + ); + check_discriminants_fieldless( + r#" +enum Enum { + Variant(), + //^^^^^^^^^0 + Variant1, //^^^^^^^^1 Variant2 {}, + //^^^^^^^^^^^2 Variant3, //^^^^^^^^3 Variant5 = 5, diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/fn_lifetime_fn.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/fn_lifetime_fn.rs index 2aa5e3dc7..b7182085b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/fn_lifetime_fn.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/fn_lifetime_fn.rs @@ -10,7 +10,7 @@ use syntax::{ SyntaxToken, }; -use crate::{InlayHint, InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints}; +use crate::{InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints}; pub(super) fn hints( acc: &mut Vec<InlayHint>, @@ -23,9 +23,8 @@ pub(super) fn hints( let mk_lt_hint = |t: SyntaxToken, label: String| InlayHint { range: t.text_range(), - kind: InlayKind::LifetimeHint, + kind: InlayKind::Lifetime, label: label.into(), - tooltip: Some(InlayTooltip::String("Elided lifetime".into())), }; let param_list = func.param_list()?; @@ -183,21 +182,19 @@ pub(super) fn hints( let is_empty = gpl.generic_params().next().is_none(); acc.push(InlayHint { range: angle_tok.text_range(), - kind: InlayKind::LifetimeHint, + kind: InlayKind::Lifetime, label: format!( "{}{}", allocated_lifetimes.iter().format(", "), if is_empty { "" } else { ", " } ) .into(), - tooltip: Some(InlayTooltip::String("Elided lifetimes".into())), }); } (None, allocated_lifetimes) => acc.push(InlayHint { range: func.name()?.syntax().text_range(), - kind: InlayKind::GenericParamListHint, + kind: InlayKind::GenericParamList, label: format!("<{}>", allocated_lifetimes.iter().format(", "),).into(), - tooltip: Some(InlayTooltip::String("Elided lifetimes".into())), }), } Some(()) diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs index 588a0e3b6..1122ee2e3 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs @@ -8,7 +8,7 @@ use syntax::{ SyntaxKind, }; -use crate::{InlayHint, InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints}; +use crate::{InlayHint, InlayHintsConfig, InlayKind, LifetimeElisionHints}; pub(super) fn hints( acc: &mut Vec<InlayHint>, @@ -32,9 +32,8 @@ pub(super) fn hints( let t = ty.amp_token()?; acc.push(InlayHint { range: t.text_range(), - kind: InlayKind::LifetimeHint, + kind: InlayKind::Lifetime, label: "'static".to_owned().into(), - tooltip: Some(InlayTooltip::String("Elided static lifetime".into())), }); } } diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs index ecee67632..9cdae6324 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs @@ -10,7 +10,7 @@ use ide_db::{base_db::FileRange, RootDatabase}; use stdx::to_lower_snake_case; use syntax::ast::{self, AstNode, HasArgList, HasName, UnaryOp}; -use crate::{InlayHint, InlayHintsConfig, InlayKind, InlayTooltip}; +use crate::{InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind}; pub(super) fn hints( acc: &mut Vec<InlayHint>, @@ -43,21 +43,20 @@ pub(super) fn hints( !should_hide_param_name_hint(sema, &callable, param_name, arg) }) .map(|(param, param_name, _, FileRange { range, .. })| { - let mut tooltip = None; + let mut linked_location = None; if let Some(name) = param { if let hir::CallableKind::Function(f) = callable.kind() { // assert the file is cached so we can map out of macros if let Some(_) = sema.source(f) { - tooltip = sema.original_range_opt(name.syntax()); + linked_location = sema.original_range_opt(name.syntax()); } } } InlayHint { range, - kind: InlayKind::ParameterHint, - label: param_name.into(), - tooltip: tooltip.map(|it| InlayTooltip::HoverOffset(it.file_id, it.range.start())), + kind: InlayKind::Parameter, + label: InlayHintLabel::simple(param_name, None, linked_location), } }); |