Auto merge of #13885 - Veykril:bin-op-adjust, r=Veykril

Skip lifetime elision on fn pointers and fn trait types

These currently don't work correctly, so it's better to not render them at all there
This commit is contained in:
bors 2023-01-03 10:59:21 +00:00
commit 5033213fc9
5 changed files with 105 additions and 70 deletions

View file

@ -334,6 +334,7 @@ impl<'a> InferenceContext<'a> {
let (param_tys, ret_ty) = match res { let (param_tys, ret_ty) = match res {
Some(res) => { Some(res) => {
let adjustments = auto_deref_adjust_steps(&derefs); let adjustments = auto_deref_adjust_steps(&derefs);
// FIXME: Handle call adjustments for Fn/FnMut
self.write_expr_adj(*callee, adjustments); self.write_expr_adj(*callee, adjustments);
res res
} }

View file

@ -47,7 +47,10 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
// Don't enable the assist if there is a type ascription without any placeholders // Don't enable the assist if there is a type ascription without any placeholders
if let Some(ty) = &ascribed_ty { if let Some(ty) = &ascribed_ty {
let mut contains_infer_ty = false; let mut contains_infer_ty = false;
walk_ty(ty, &mut |ty| contains_infer_ty |= matches!(ty, ast::Type::InferType(_))); walk_ty(ty, &mut |ty| {
contains_infer_ty |= matches!(ty, ast::Type::InferType(_));
false
});
if !contains_infer_ty { if !contains_infer_ty {
cov_mark::hit!(add_explicit_type_not_applicable_if_ty_already_specified); cov_mark::hit!(add_explicit_type_not_applicable_if_ty_already_specified);
return None; return None;

View file

@ -108,7 +108,8 @@ fn collect_used_generics<'gp>(
} }
let mut generics = Vec::new(); let mut generics = Vec::new();
walk_ty(ty, &mut |ty| match ty { walk_ty(ty, &mut |ty| {
match ty {
ast::Type::PathType(ty) => { ast::Type::PathType(ty) => {
if let Some(path) = ty.path() { if let Some(path) = ty.path() {
if let Some(name_ref) = path.as_single_name_ref() { if let Some(name_ref) = path.as_single_name_ref() {
@ -156,7 +157,8 @@ fn collect_used_generics<'gp>(
} }
} }
ast::Type::RefType(ref_) => generics.extend( ast::Type::RefType(ref_) => generics.extend(
ref_.lifetime().and_then(|lt| known_generics.iter().find(find_lifetime(&lt.text()))), ref_.lifetime()
.and_then(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
), ),
ast::Type::ArrayType(ar) => { ast::Type::ArrayType(ar) => {
if let Some(expr) = ar.expr() { if let Some(expr) = ar.expr() {
@ -178,6 +180,8 @@ fn collect_used_generics<'gp>(
} }
} }
_ => (), _ => (),
};
false
}); });
// stable resort to lifetime, type, const // stable resort to lifetime, type, const
generics.sort_by_key(|gp| match gp { generics.sort_by_key(|gp| match gp {

View file

@ -173,7 +173,8 @@ pub fn walk_pat(pat: &ast::Pat, cb: &mut dyn FnMut(ast::Pat)) {
} }
/// Preorder walk all the type's sub types. /// Preorder walk all the type's sub types.
pub fn walk_ty(ty: &ast::Type, cb: &mut dyn FnMut(ast::Type)) { // FIXME: Make the control flow more proper
pub fn walk_ty(ty: &ast::Type, cb: &mut dyn FnMut(ast::Type) -> bool) {
let mut preorder = ty.syntax().preorder(); let mut preorder = ty.syntax().preorder();
while let Some(event) = preorder.next() { while let Some(event) = preorder.next() {
let node = match event { let node = match event {
@ -184,10 +185,12 @@ pub fn walk_ty(ty: &ast::Type, cb: &mut dyn FnMut(ast::Type)) {
match ast::Type::cast(node) { match ast::Type::cast(node) {
Some(ty @ ast::Type::MacroType(_)) => { Some(ty @ ast::Type::MacroType(_)) => {
preorder.skip_subtree(); preorder.skip_subtree();
cb(ty) cb(ty);
} }
Some(ty) => { Some(ty) => {
cb(ty); if cb(ty) {
preorder.skip_subtree();
}
} }
// skip const args // skip const args
None if ast::ConstArg::can_cast(kind) => { None if ast::ConstArg::can_cast(kind) => {

View file

@ -59,9 +59,14 @@ pub(super) fn hints(
r.amp_token(), r.amp_token(),
lifetime, lifetime,
is_elided, is_elided,
)) ));
false
} }
_ => (), ast::Type::FnPtrType(_) => true,
ast::Type::PathType(t) => {
t.path().and_then(|it| it.segment()).and_then(|it| it.param_list()).is_some()
}
_ => false,
}) })
}); });
acc acc
@ -146,8 +151,13 @@ pub(super) fn hints(
is_trivial = false; is_trivial = false;
acc.push(mk_lt_hint(amp, output_lt.to_string())); acc.push(mk_lt_hint(amp, output_lt.to_string()));
} }
false
} }
_ => (), ast::Type::FnPtrType(_) => true,
ast::Type::PathType(t) => {
t.path().and_then(|it| it.segment()).and_then(|it| it.param_list()).is_some()
}
_ => false,
}) })
} }
} }
@ -295,6 +305,20 @@ impl () {
// ^^^<'0, '1> // ^^^<'0, '1>
// ^'0 ^'1 ^'0 // ^'0 ^'1 ^'0
} }
"#,
);
}
#[test]
fn hints_lifetimes_skip_fn_likes() {
check_with_config(
InlayHintsConfig {
lifetime_elision_hints: LifetimeElisionHints::Always,
..TEST_CONFIG
},
r#"
fn fn_ptr(a: fn(&()) -> &()) {}
fn fn_trait<>(a: impl Fn(&()) -> &()) {}
"#, "#,
); );
} }