Auto merge of #12416 - Veykril:inlay-hints, r=Veykril

Add implicit static lifetime hints
This commit is contained in:
bors 2022-05-30 12:00:54 +00:00
commit edb2e571fe

View file

@ -117,33 +117,32 @@ pub(crate) fn inlay_hints(
let mut acc = Vec::new(); let mut acc = Vec::new();
let hints = |node| hints(&mut acc, &sema, config, file_id, node); if let Some(scope) = sema.scope(&file) {
match range_limit { let famous_defs = FamousDefs(&sema, scope.krate());
Some(FileRange { range, .. }) => match file.covering_element(range) {
NodeOrToken::Token(_) => return acc, let hints = |node| hints(&mut acc, &famous_defs, config, file_id, node);
NodeOrToken::Node(n) => n match range_limit {
.descendants() Some(FileRange { range, .. }) => match file.covering_element(range) {
.filter(|descendant| range.intersect(descendant.text_range()).is_some()) NodeOrToken::Token(_) => return acc,
.for_each(hints), NodeOrToken::Node(n) => n
}, .descendants()
None => file.descendants().for_each(hints), .filter(|descendant| range.intersect(descendant.text_range()).is_some())
}; .for_each(hints),
},
None => file.descendants().for_each(hints),
};
}
acc acc
} }
fn hints( fn hints(
hints: &mut Vec<InlayHint>, hints: &mut Vec<InlayHint>,
sema: &Semantics<RootDatabase>, famous_defs @ FamousDefs(sema, _): &FamousDefs,
config: &InlayHintsConfig, config: &InlayHintsConfig,
file_id: FileId, file_id: FileId,
node: SyntaxNode, 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()); closing_brace_hints(hints, sema, config, file_id, node.clone());
match_ast! { match_ast! {
match node { match node {
@ -168,8 +167,18 @@ fn hints(
} }
Some(()) Some(())
}, },
ast::Fn(it) => lifetime_fn_hints(hints, config, it), ast::Item(it) => match it {
_ => Some(()), // 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 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>, acc: &mut Vec<InlayHint>,
config: &InlayHintsConfig, config: &InlayHintsConfig,
func: ast::Fn, func: ast::Fn,
@ -2593,6 +2634,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] #[test]
fn hints_implicit_reborrow() { fn hints_implicit_reborrow() {
check_with_config( check_with_config(