|
3 | 3 | //! let _: u32 = /* <never-to-any> */ loop {};
|
4 | 4 | //! let _: &u32 = /* &* */ &mut 0;
|
5 | 5 | //! ```
|
6 |
| -use hir::{Adjust, AutoBorrow, Mutability, OverloadedDeref, PointerCast, Safety, Semantics}; |
| 6 | +use hir::{Adjust, Adjustment, AutoBorrow, HirDisplay, Mutability, PointerCast, Safety, Semantics}; |
7 | 7 | use ide_db::RootDatabase;
|
8 | 8 |
|
9 | 9 | use syntax::{
|
10 | 10 | ast::{self, make, AstNode},
|
11 | 11 | ted,
|
12 | 12 | };
|
13 | 13 |
|
14 |
| -use crate::{AdjustmentHints, AdjustmentHintsMode, InlayHint, InlayHintsConfig, InlayKind}; |
| 14 | +use crate::{ |
| 15 | + AdjustmentHints, AdjustmentHintsMode, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind, |
| 16 | + InlayTooltip, |
| 17 | +}; |
15 | 18 |
|
16 | 19 | pub(super) fn hints(
|
17 | 20 | acc: &mut Vec<InlayHint>,
|
@@ -61,44 +64,63 @@ pub(super) fn hints(
|
61 | 64 | &mut tmp1
|
62 | 65 | };
|
63 | 66 |
|
64 |
| - for adjustment in iter { |
65 |
| - if adjustment.source == adjustment.target { |
| 67 | + for Adjustment { source, target, kind } in iter { |
| 68 | + if source == target { |
66 | 69 | continue;
|
67 | 70 | }
|
68 | 71 |
|
69 | 72 | // FIXME: Add some nicer tooltips to each of these
|
70 |
| - let text = match adjustment.kind { |
| 73 | + let (text, coercion) = match kind { |
71 | 74 | Adjust::NeverToAny if config.adjustment_hints == AdjustmentHints::Always => {
|
72 |
| - "<never-to-any>" |
| 75 | + ("<never-to-any>", "never to any") |
| 76 | + } |
| 77 | + Adjust::Deref(_) => ("*", "dereference"), |
| 78 | + Adjust::Borrow(AutoBorrow::Ref(Mutability::Shared)) => ("&", "borrow"), |
| 79 | + Adjust::Borrow(AutoBorrow::Ref(Mutability::Mut)) => ("&mut ", "unique borrow"), |
| 80 | + Adjust::Borrow(AutoBorrow::RawPtr(Mutability::Shared)) => { |
| 81 | + ("&raw const ", "const pointer borrow") |
| 82 | + } |
| 83 | + Adjust::Borrow(AutoBorrow::RawPtr(Mutability::Mut)) => { |
| 84 | + ("&raw mut ", "mut pointer borrow") |
73 | 85 | }
|
74 |
| - Adjust::Deref(None) => "*", |
75 |
| - Adjust::Deref(Some(OverloadedDeref(Mutability::Mut))) => "*", |
76 |
| - Adjust::Deref(Some(OverloadedDeref(Mutability::Shared))) => "*", |
77 |
| - Adjust::Borrow(AutoBorrow::Ref(Mutability::Shared)) => "&", |
78 |
| - Adjust::Borrow(AutoBorrow::Ref(Mutability::Mut)) => "&mut ", |
79 |
| - Adjust::Borrow(AutoBorrow::RawPtr(Mutability::Shared)) => "&raw const ", |
80 |
| - Adjust::Borrow(AutoBorrow::RawPtr(Mutability::Mut)) => "&raw mut ", |
81 | 86 | // some of these could be represented via `as` casts, but that's not too nice and
|
82 | 87 | // handling everything as a prefix expr makes the `(` and `)` insertion easier
|
83 | 88 | Adjust::Pointer(cast) if config.adjustment_hints == AdjustmentHints::Always => {
|
84 | 89 | match cast {
|
85 |
| - PointerCast::ReifyFnPointer => "<fn-item-to-fn-pointer>", |
86 |
| - PointerCast::UnsafeFnPointer => "<safe-fn-pointer-to-unsafe-fn-pointer>", |
| 90 | + PointerCast::ReifyFnPointer => { |
| 91 | + ("<fn-item-to-fn-pointer>", "fn item to fn pointer") |
| 92 | + } |
| 93 | + PointerCast::UnsafeFnPointer => ( |
| 94 | + "<safe-fn-pointer-to-unsafe-fn-pointer>", |
| 95 | + "safe fn pointer to unsafe fn pointer", |
| 96 | + ), |
87 | 97 | PointerCast::ClosureFnPointer(Safety::Unsafe) => {
|
88 |
| - "<closure-to-unsafe-fn-pointer>" |
| 98 | + ("<closure-to-unsafe-fn-pointer>", "closure to unsafe fn pointer") |
| 99 | + } |
| 100 | + PointerCast::ClosureFnPointer(Safety::Safe) => { |
| 101 | + ("<closure-to-fn-pointer>", "closure to fn pointer") |
| 102 | + } |
| 103 | + PointerCast::MutToConstPointer => { |
| 104 | + ("<mut-ptr-to-const-ptr>", "mut ptr to const ptr") |
89 | 105 | }
|
90 |
| - PointerCast::ClosureFnPointer(Safety::Safe) => "<closure-to-fn-pointer>", |
91 |
| - PointerCast::MutToConstPointer => "<mut-ptr-to-const-ptr>", |
92 |
| - PointerCast::ArrayToPointer => "<array-ptr-to-element-ptr>", |
93 |
| - PointerCast::Unsize => "<unsize>", |
| 106 | + PointerCast::ArrayToPointer => ("<array-ptr-to-element-ptr>", ""), |
| 107 | + PointerCast::Unsize => ("<unsize>", "unsize"), |
94 | 108 | }
|
95 | 109 | }
|
96 | 110 | _ => continue,
|
97 | 111 | };
|
98 | 112 | acc.push(InlayHint {
|
99 | 113 | range: expr.syntax().text_range(),
|
100 | 114 | kind: if postfix { InlayKind::AdjustmentPostfix } else { InlayKind::Adjustment },
|
101 |
| - label: if postfix { format!(".{}", text.trim_end()).into() } else { text.into() }, |
| 115 | + label: InlayHintLabel::simple( |
| 116 | + if postfix { format!(".{}", text.trim_end()) } else { text.to_owned() }, |
| 117 | + Some(InlayTooltip::Markdown(format!( |
| 118 | + "`{}` → `{}` ({coercion} coercion)", |
| 119 | + source.display(sema.db), |
| 120 | + target.display(sema.db), |
| 121 | + ))), |
| 122 | + None, |
| 123 | + ), |
102 | 124 | });
|
103 | 125 | }
|
104 | 126 | if !postfix && needs_inner_parens {
|
|
0 commit comments