Skip to content

Commit

Permalink
Auto merge of rust-lang#13885 - Veykril:bin-op-adjust, r=Veykril
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Jan 3, 2023
2 parents 50801b7 + b996a54 commit 5033213
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 65 deletions.
1 change: 1 addition & 0 deletions crates/hir-ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ impl<'a> InferenceContext<'a> {
let (param_tys, ret_ty) = match res {
Some(res) => {
let adjustments = auto_deref_adjust_steps(&derefs);
// FIXME: Handle call adjustments for Fn/FnMut
self.write_expr_adj(*callee, adjustments);
res
}
Expand Down
5 changes: 4 additions & 1 deletion crates/ide-assists/src/handlers/add_explicit_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
if let Some(ty) = &ascribed_ty {
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 {
cov_mark::hit!(add_explicit_type_not_applicable_if_ty_already_specified);
return None;
Expand Down
120 changes: 62 additions & 58 deletions crates/ide-assists/src/handlers/extract_type_alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,76 +108,80 @@ fn collect_used_generics<'gp>(
}

let mut generics = Vec::new();
walk_ty(ty, &mut |ty| match ty {
ast::Type::PathType(ty) => {
if let Some(path) = ty.path() {
if let Some(name_ref) = path.as_single_name_ref() {
if let Some(param) = known_generics.iter().find(|gp| {
match gp {
ast::GenericParam::ConstParam(cp) => cp.name(),
ast::GenericParam::TypeParam(tp) => tp.name(),
_ => None,
walk_ty(ty, &mut |ty| {
match ty {
ast::Type::PathType(ty) => {
if let Some(path) = ty.path() {
if let Some(name_ref) = path.as_single_name_ref() {
if let Some(param) = known_generics.iter().find(|gp| {
match gp {
ast::GenericParam::ConstParam(cp) => cp.name(),
ast::GenericParam::TypeParam(tp) => tp.name(),
_ => None,
}
.map_or(false, |n| n.text() == name_ref.text())
}) {
generics.push(param);
}
.map_or(false, |n| n.text() == name_ref.text())
}) {
generics.push(param);
}
generics.extend(
path.segments()
.filter_map(|seg| seg.generic_arg_list())
.flat_map(|it| it.generic_args())
.filter_map(|it| match it {
ast::GenericArg::LifetimeArg(lt) => {
let lt = lt.lifetime()?;
known_generics.iter().find(find_lifetime(&lt.text()))
}
_ => None,
}),
);
}
generics.extend(
path.segments()
.filter_map(|seg| seg.generic_arg_list())
.flat_map(|it| it.generic_args())
.filter_map(|it| match it {
ast::GenericArg::LifetimeArg(lt) => {
let lt = lt.lifetime()?;
known_generics.iter().find(find_lifetime(&lt.text()))
}
_ => None,
}),
);
}
}
ast::Type::ImplTraitType(impl_ty) => {
if let Some(it) = impl_ty.type_bound_list() {
generics.extend(
it.bounds()
.filter_map(|it| it.lifetime())
.filter_map(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
);
ast::Type::ImplTraitType(impl_ty) => {
if let Some(it) = impl_ty.type_bound_list() {
generics.extend(
it.bounds()
.filter_map(|it| it.lifetime())
.filter_map(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
);
}
}
}
ast::Type::DynTraitType(dyn_ty) => {
if let Some(it) = dyn_ty.type_bound_list() {
generics.extend(
it.bounds()
.filter_map(|it| it.lifetime())
.filter_map(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
);
ast::Type::DynTraitType(dyn_ty) => {
if let Some(it) = dyn_ty.type_bound_list() {
generics.extend(
it.bounds()
.filter_map(|it| it.lifetime())
.filter_map(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
);
}
}
}
ast::Type::RefType(ref_) => generics.extend(
ref_.lifetime().and_then(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
),
ast::Type::ArrayType(ar) => {
if let Some(expr) = ar.expr() {
if let ast::Expr::PathExpr(p) = expr {
if let Some(path) = p.path() {
if let Some(name_ref) = path.as_single_name_ref() {
if let Some(param) = known_generics.iter().find(|gp| {
if let ast::GenericParam::ConstParam(cp) = gp {
cp.name().map_or(false, |n| n.text() == name_ref.text())
} else {
false
ast::Type::RefType(ref_) => generics.extend(
ref_.lifetime()
.and_then(|lt| known_generics.iter().find(find_lifetime(&lt.text()))),
),
ast::Type::ArrayType(ar) => {
if let Some(expr) = ar.expr() {
if let ast::Expr::PathExpr(p) = expr {
if let Some(path) = p.path() {
if let Some(name_ref) = path.as_single_name_ref() {
if let Some(param) = known_generics.iter().find(|gp| {
if let ast::GenericParam::ConstParam(cp) = gp {
cp.name().map_or(false, |n| n.text() == name_ref.text())
} else {
false
}
}) {
generics.push(param);
}
}) {
generics.push(param);
}
}
}
}
}
}
_ => (),
_ => (),
};
false
});
// stable resort to lifetime, type, const
generics.sort_by_key(|gp| match gp {
Expand Down
9 changes: 6 additions & 3 deletions crates/ide-db/src/syntax_helpers/node_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
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();
while let Some(event) = preorder.next() {
let node = match event {
Expand All @@ -184,10 +185,12 @@ pub fn walk_ty(ty: &ast::Type, cb: &mut dyn FnMut(ast::Type)) {
match ast::Type::cast(node) {
Some(ty @ ast::Type::MacroType(_)) => {
preorder.skip_subtree();
cb(ty)
cb(ty);
}
Some(ty) => {
cb(ty);
if cb(ty) {
preorder.skip_subtree();
}
}
// skip const args
None if ast::ConstArg::can_cast(kind) => {
Expand Down
30 changes: 27 additions & 3 deletions crates/ide/src/inlay_hints/fn_lifetime_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,14 @@ pub(super) fn hints(
r.amp_token(),
lifetime,
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
Expand Down Expand Up @@ -146,8 +151,13 @@ pub(super) fn hints(
is_trivial = false;
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,
})
}
}
Expand Down Expand Up @@ -295,6 +305,20 @@ impl () {
// ^^^<'0, '1>
// ^'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(&()) -> &()) {}
"#,
);
}
Expand Down

0 comments on commit 5033213

Please sign in to comment.