diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2022-05-30 13:51:48 +0200 |
|---|---|---|
| committer | Lukas Wirth <lukastw97@gmail.com> | 2022-05-30 13:59:58 +0200 |
| commit | aced76d0ffd8319c553f52f276f7971cfaea5cd8 (patch) | |
| tree | d4a9c97dd88c710ffadca54931acd803ab1473f4 | |
| parent | 9ceaff91d31ea16e38d6fb415d3a7d52703a7499 (diff) | |
| download | rust-aced76d0ffd8319c553f52f276f7971cfaea5cd8.tar.gz rust-aced76d0ffd8319c553f52f276f7971cfaea5cd8.zip | |
Add implicit static lifetime hints
| -rw-r--r-- | crates/ide/src/inlay_hints.rs | 105 |
1 files changed, 85 insertions, 20 deletions
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 910aee7b05c..116c1c480a1 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -117,33 +117,32 @@ pub(crate) fn inlay_hints( let mut acc = Vec::new(); - let hints = |node| hints(&mut acc, &sema, config, file_id, node); - match range_limit { - Some(FileRange { range, .. }) => match file.covering_element(range) { - NodeOrToken::Token(_) => return acc, - NodeOrToken::Node(n) => n - .descendants() - .filter(|descendant| range.intersect(descendant.text_range()).is_some()) - .for_each(hints), - }, - None => file.descendants().for_each(hints), - }; + if let Some(scope) = sema.scope(&file) { + let famous_defs = FamousDefs(&sema, scope.krate()); + + let hints = |node| hints(&mut acc, &famous_defs, config, file_id, node); + match range_limit { + Some(FileRange { range, .. }) => match file.covering_element(range) { + NodeOrToken::Token(_) => return acc, + NodeOrToken::Node(n) => n + .descendants() + .filter(|descendant| range.intersect(descendant.text_range()).is_some()) + .for_each(hints), + }, + None => file.descendants().for_each(hints), + }; + } acc } fn hints( hints: &mut Vec<InlayHint>, - sema: &Semantics<RootDatabase>, + famous_defs @ FamousDefs(sema, _): &FamousDefs, config: &InlayHintsConfig, file_id: FileId, node: SyntaxNode, ) { - let famous_defs = match sema.scope(&node) { - Some(it) => FamousDefs(sema, it.krate()), - None => return, - }; - closing_brace_hints(hints, sema, config, file_id, node.clone()); match_ast! { match node { @@ -168,8 +167,18 @@ fn hints( } Some(()) }, - ast::Fn(it) => lifetime_fn_hints(hints, config, it), - _ => Some(()), + ast::Item(it) => match it { + // FIXME: record impl lifetimes so they aren't being reused in assoc item lifetime inlay hints + ast::Item::Impl(_) => None, + ast::Item::Fn(it) => fn_lifetime_fn_hints(hints, config, it), + // static type elisions + ast::Item::Static(it) => implicit_static_hints(hints, config, Either::Left(it)), + ast::Item::Const(it) => implicit_static_hints(hints, config, Either::Right(it)), + _ => None, + }, + // FIXME: fn-ptr type, dyn fn type, and trait object type elisions + ast::Type(_) => None, + _ => None, } }; } @@ -279,7 +288,39 @@ fn closing_brace_hints( None } -fn lifetime_fn_hints( +fn implicit_static_hints( + acc: &mut Vec<InlayHint>, + config: &InlayHintsConfig, + statik_or_const: Either<ast::Static, ast::Const>, +) -> Option<()> { + if config.lifetime_elision_hints != LifetimeElisionHints::Always { + return None; + } + + if let Either::Right(it) = &statik_or_const { + if ast::AssocItemList::can_cast( + it.syntax().parent().map_or(SyntaxKind::EOF, |it| it.kind()), + ) { + return None; + } + } + + if let Some(ast::Type::RefType(ty)) = statik_or_const.either(|it| it.ty(), |it| it.ty()) { + if ty.lifetime().is_none() { + let t = ty.amp_token()?; + acc.push(InlayHint { + range: t.text_range(), + kind: InlayKind::LifetimeHint, + label: "'static".to_owned(), + tooltip: Some(InlayTooltip::String("Elided static lifetime".into())), + }); + } + } + + Some(()) +} + +fn fn_lifetime_fn_hints( acc: &mut Vec<InlayHint>, config: &InlayHintsConfig, func: ast::Fn, @@ -2594,6 +2635,30 @@ impl () { } #[test] + fn hints_lifetimes_static() { + check_with_config( + InlayHintsConfig { + lifetime_elision_hints: LifetimeElisionHints::Always, + ..TEST_CONFIG + }, + r#" +trait Trait {} +static S: &str = ""; +// ^'static +const C: &str = ""; +// ^'static +const C: &dyn Trait = panic!(); +// ^'static + +impl () { + const C: &str = ""; + const C: &dyn Trait = panic!(); +} +"#, + ); + } + + #[test] fn hints_implicit_reborrow() { check_with_config( InlayHintsConfig { |
