Skip to content

Commit 5033213

Browse files
committed
Auto merge of rust-lang#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
2 parents 50801b7 + b996a54 commit 5033213

File tree

5 files changed

+100
-65
lines changed

5 files changed

+100
-65
lines changed

crates/hir-ty/src/infer/expr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ impl<'a> InferenceContext<'a> {
334334
let (param_tys, ret_ty) = match res {
335335
Some(res) => {
336336
let adjustments = auto_deref_adjust_steps(&derefs);
337+
// FIXME: Handle call adjustments for Fn/FnMut
337338
self.write_expr_adj(*callee, adjustments);
338339
res
339340
}

crates/ide-assists/src/handlers/add_explicit_type.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
4747
// Don't enable the assist if there is a type ascription without any placeholders
4848
if let Some(ty) = &ascribed_ty {
4949
let mut contains_infer_ty = false;
50-
walk_ty(ty, &mut |ty| contains_infer_ty |= matches!(ty, ast::Type::InferType(_)));
50+
walk_ty(ty, &mut |ty| {
51+
contains_infer_ty |= matches!(ty, ast::Type::InferType(_));
52+
false
53+
});
5154
if !contains_infer_ty {
5255
cov_mark::hit!(add_explicit_type_not_applicable_if_ty_already_specified);
5356
return None;

crates/ide-assists/src/handlers/extract_type_alias.rs

Lines changed: 62 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -108,76 +108,80 @@ fn collect_used_generics<'gp>(
108108
}
109109

110110
let mut generics = Vec::new();
111-
walk_ty(ty, &mut |ty| match ty {
112-
ast::Type::PathType(ty) => {
113-
if let Some(path) = ty.path() {
114-
if let Some(name_ref) = path.as_single_name_ref() {
115-
if let Some(param) = known_generics.iter().find(|gp| {
116-
match gp {
117-
ast::GenericParam::ConstParam(cp) => cp.name(),
118-
ast::GenericParam::TypeParam(tp) => tp.name(),
119-
_ => None,
111+
walk_ty(ty, &mut |ty| {
112+
match ty {
113+
ast::Type::PathType(ty) => {
114+
if let Some(path) = ty.path() {
115+
if let Some(name_ref) = path.as_single_name_ref() {
116+
if let Some(param) = known_generics.iter().find(|gp| {
117+
match gp {
118+
ast::GenericParam::ConstParam(cp) => cp.name(),
119+
ast::GenericParam::TypeParam(tp) => tp.name(),
120+
_ => None,
121+
}
122+
.map_or(false, |n| n.text() == name_ref.text())
123+
}) {
124+
generics.push(param);
120125
}
121-
.map_or(false, |n| n.text() == name_ref.text())
122-
}) {
123-
generics.push(param);
124126
}
127+
generics.extend(
128+
path.segments()
129+
.filter_map(|seg| seg.generic_arg_list())
130+
.flat_map(|it| it.generic_args())
131+
.filter_map(|it| match it {
132+
ast::GenericArg::LifetimeArg(lt) => {
133+
let lt = lt.lifetime()?;
134+
known_generics.iter().find(find_lifetime(&lt.text()))
135+
}
136+
_ => None,
137+
}),
138+
);
125139
}
126-
generics.extend(
127-
path.segments()
128-
.filter_map(|seg| seg.generic_arg_list())
129-
.flat_map(|it| it.generic_args())
130-
.filter_map(|it| match it {
131-
ast::GenericArg::LifetimeArg(lt) => {
132-
let lt = lt.lifetime()?;
133-
known_generics.iter().find(find_lifetime(&lt.text()))
134-
}
135-
_ => None,
136-
}),
137-
);
138140
}
139-
}
140-
ast::Type::ImplTraitType(impl_ty) => {
141-
if let Some(it) = impl_ty.type_bound_list() {
142-
generics.extend(
143-
it.bounds()
144-
.filter_map(|it| it.lifetime())
145-
.filter_map(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
146-
);
141+
ast::Type::ImplTraitType(impl_ty) => {
142+
if let Some(it) = impl_ty.type_bound_list() {
143+
generics.extend(
144+
it.bounds()
145+
.filter_map(|it| it.lifetime())
146+
.filter_map(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
147+
);
148+
}
147149
}
148-
}
149-
ast::Type::DynTraitType(dyn_ty) => {
150-
if let Some(it) = dyn_ty.type_bound_list() {
151-
generics.extend(
152-
it.bounds()
153-
.filter_map(|it| it.lifetime())
154-
.filter_map(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
155-
);
150+
ast::Type::DynTraitType(dyn_ty) => {
151+
if let Some(it) = dyn_ty.type_bound_list() {
152+
generics.extend(
153+
it.bounds()
154+
.filter_map(|it| it.lifetime())
155+
.filter_map(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
156+
);
157+
}
156158
}
157-
}
158-
ast::Type::RefType(ref_) => generics.extend(
159-
ref_.lifetime().and_then(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
160-
),
161-
ast::Type::ArrayType(ar) => {
162-
if let Some(expr) = ar.expr() {
163-
if let ast::Expr::PathExpr(p) = expr {
164-
if let Some(path) = p.path() {
165-
if let Some(name_ref) = path.as_single_name_ref() {
166-
if let Some(param) = known_generics.iter().find(|gp| {
167-
if let ast::GenericParam::ConstParam(cp) = gp {
168-
cp.name().map_or(false, |n| n.text() == name_ref.text())
169-
} else {
170-
false
159+
ast::Type::RefType(ref_) => generics.extend(
160+
ref_.lifetime()
161+
.and_then(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
162+
),
163+
ast::Type::ArrayType(ar) => {
164+
if let Some(expr) = ar.expr() {
165+
if let ast::Expr::PathExpr(p) = expr {
166+
if let Some(path) = p.path() {
167+
if let Some(name_ref) = path.as_single_name_ref() {
168+
if let Some(param) = known_generics.iter().find(|gp| {
169+
if let ast::GenericParam::ConstParam(cp) = gp {
170+
cp.name().map_or(false, |n| n.text() == name_ref.text())
171+
} else {
172+
false
173+
}
174+
}) {
175+
generics.push(param);
171176
}
172-
}) {
173-
generics.push(param);
174177
}
175178
}
176179
}
177180
}
178181
}
179-
}
180-
_ => (),
182+
_ => (),
183+
};
184+
false
181185
});
182186
// stable resort to lifetime, type, const
183187
generics.sort_by_key(|gp| match gp {

crates/ide-db/src/syntax_helpers/node_ext.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ pub fn walk_pat(pat: &ast::Pat, cb: &mut dyn FnMut(ast::Pat)) {
173173
}
174174

175175
/// Preorder walk all the type's sub types.
176-
pub fn walk_ty(ty: &ast::Type, cb: &mut dyn FnMut(ast::Type)) {
176+
// FIXME: Make the control flow more proper
177+
pub fn walk_ty(ty: &ast::Type, cb: &mut dyn FnMut(ast::Type) -> bool) {
177178
let mut preorder = ty.syntax().preorder();
178179
while let Some(event) = preorder.next() {
179180
let node = match event {
@@ -184,10 +185,12 @@ pub fn walk_ty(ty: &ast::Type, cb: &mut dyn FnMut(ast::Type)) {
184185
match ast::Type::cast(node) {
185186
Some(ty @ ast::Type::MacroType(_)) => {
186187
preorder.skip_subtree();
187-
cb(ty)
188+
cb(ty);
188189
}
189190
Some(ty) => {
190-
cb(ty);
191+
if cb(ty) {
192+
preorder.skip_subtree();
193+
}
191194
}
192195
// skip const args
193196
None if ast::ConstArg::can_cast(kind) => {

crates/ide/src/inlay_hints/fn_lifetime_fn.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,14 @@ pub(super) fn hints(
5959
r.amp_token(),
6060
lifetime,
6161
is_elided,
62-
))
62+
));
63+
false
6364
}
64-
_ => (),
65+
ast::Type::FnPtrType(_) => true,
66+
ast::Type::PathType(t) => {
67+
t.path().and_then(|it| it.segment()).and_then(|it| it.param_list()).is_some()
68+
}
69+
_ => false,
6570
})
6671
});
6772
acc
@@ -146,8 +151,13 @@ pub(super) fn hints(
146151
is_trivial = false;
147152
acc.push(mk_lt_hint(amp, output_lt.to_string()));
148153
}
154+
false
155+
}
156+
ast::Type::FnPtrType(_) => true,
157+
ast::Type::PathType(t) => {
158+
t.path().and_then(|it| it.segment()).and_then(|it| it.param_list()).is_some()
149159
}
150-
_ => (),
160+
_ => false,
151161
})
152162
}
153163
}
@@ -295,6 +305,20 @@ impl () {
295305
// ^^^<'0, '1>
296306
// ^'0 ^'1 ^'0
297307
}
308+
"#,
309+
);
310+
}
311+
312+
#[test]
313+
fn hints_lifetimes_skip_fn_likes() {
314+
check_with_config(
315+
InlayHintsConfig {
316+
lifetime_elision_hints: LifetimeElisionHints::Always,
317+
..TEST_CONFIG
318+
},
319+
r#"
320+
fn fn_ptr(a: fn(&()) -> &()) {}
321+
fn fn_trait<>(a: impl Fn(&()) -> &()) {}
298322
"#,
299323
);
300324
}

0 commit comments

Comments
 (0)