1 use hir::{Mutability, Semantics};
2 use ide_db::RootDatabase;
4 use syntax::ast::{self, AstNode};
6 use crate::{InlayHint, InlayHintsConfig, InlayKind, InlayTooltip};
9 acc: &mut Vec<InlayHint>,
10 sema: &Semantics<'_, RootDatabase>,
11 config: &InlayHintsConfig,
14 if !config.binding_mode_hints {
18 let outer_paren_pat = pat
22 .map_while(ast::Pat::cast)
23 .map_while(|pat| match pat {
24 ast::Pat::ParenPat(pat) => Some(pat),
29 outer_paren_pat.as_ref().map_or_else(|| pat.syntax(), |it| it.syntax()).text_range();
30 sema.pattern_adjustments(&pat).iter().for_each(|ty| {
31 let reference = ty.is_reference();
32 let mut_reference = ty.is_mutable_reference();
33 let r = match (reference, mut_reference) {
34 (true, true) => "&mut",
40 kind: InlayKind::BindingModeHint,
41 label: r.to_string().into(),
42 tooltip: Some(InlayTooltip::String("Inferred binding mode".into())),
46 ast::Pat::IdentPat(pat) if pat.ref_token().is_none() && pat.mut_token().is_none() => {
47 let bm = sema.binding_mode_of_pat(pat)?;
49 hir::BindingMode::Move => return None,
50 hir::BindingMode::Ref(Mutability::Mut) => "ref mut",
51 hir::BindingMode::Ref(Mutability::Shared) => "ref",
54 range: pat.syntax().text_range(),
55 kind: InlayKind::BindingModeHint,
56 label: bm.to_string().into(),
57 tooltip: Some(InlayTooltip::String("Inferred binding mode".into())),
60 ast::Pat::OrPat(pat) if outer_paren_pat.is_none() => {
62 range: pat.syntax().text_range(),
63 kind: InlayKind::OpeningParenthesis,
68 range: pat.syntax().text_range(),
69 kind: InlayKind::ClosingParenthesis,
83 inlay_hints::tests::{check_with_config, DISABLED_CONFIG},
88 fn hints_binding_modes() {
90 InlayHintsConfig { binding_mode_hints: true, ..DISABLED_CONFIG },
105 let (x,) = &mut (0,);
108 let &mut (x,) = &mut (0,);
109 let (ref mut x,) = &mut (0,);
111 let &mut (ref mut x,) = &mut (0,);
112 let (mut x,) = &mut (0,);