Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(completion): make the expected type a tad smarter with Fns #16136

Merged

Conversation

saiintbrisson
Copy link
Contributor

This commit changes how the expected type is calculated when
working with Fn pointers, making the parenthesis stop vanishing
when completing the function name.

I've been bugged by the behavior of parenthesis completion for
a long while now. R-a assumes that the LetStmt type is the same
as the function type I've just written. Worse is that all parenthesis
vanish, even from functions that have completely different signatures.
It will now verify if the signature is the same.

While working on this, I noticed that record fields behave the same,
so I also made it prioritize the field type instead of the current
expression when possible, but I'm unsure if this is OK, so input is
appreciated.

ImplTraits as return types will still behave weirdly because lowering
is disallowed at the time it resolves the function types.

image
image
image

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 16, 2023
Comment on lines +417 to +432
let field_ty = sema.resolve_record_field(&it).map(|(_, _, ty)| ty);
let field_name = it.field_name().map(NameOrNameRef::NameRef);
if let Some(expr) = it.expr() {
cov_mark::hit!(expected_type_struct_field_with_leading_char);
(
sema.type_of_expr(&expr).map(TypeInfo::original),
it.field_name().map(NameOrNameRef::NameRef),
)
let ty = field_ty
.or_else(|| sema.type_of_expr(&expr).map(TypeInfo::original));
(ty, field_name)
} else {
cov_mark::hit!(expected_type_struct_field_followed_by_comma);
let ty = sema.resolve_record_field(&it)
.map(|(_, _, ty)| ty);
(
ty,
it.field_name().map(NameOrNameRef::NameRef),
)
(field_ty, field_name)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't think of a reason as to why this was done this way, so please enlighten me if there is indeed a reason.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure why either, your changes look correct here to me.

@@ -359,7 +359,8 @@ fn expected_type_and_name(
let ty = it.pat()
.and_then(|pat| sema.type_of_pat(&pat))
.or_else(|| it.initializer().and_then(|it| sema.type_of_expr(&it)))
.map(TypeInfo::original);
.map(TypeInfo::original)
.filter(|ty| it.ty().is_some() || !ty.is_fn());
Copy link
Contributor Author

@saiintbrisson saiintbrisson Dec 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I'm doing here is only taking Fn types into account for the let statement if it is explicitly defined, stopping r-a from stripping the parenthesis. Is there a case I'm not seeing where this will be problematic?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think so but please add a commend for why this is done.

@@ -359,7 +359,8 @@ fn expected_type_and_name(
let ty = it.pat()
.and_then(|pat| sema.type_of_pat(&pat))
.or_else(|| it.initializer().and_then(|it| sema.type_of_expr(&it)))
.map(TypeInfo::original);
.map(TypeInfo::original)
.filter(|ty| it.ty().is_some() || !ty.is_fn());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think so but please add a commend for why this is done.

@saiintbrisson saiintbrisson force-pushed the fix/completion/a-tad-smarter-with-fns branch from 7d6e292 to d9d4c5c Compare January 2, 2024 13:07
@saiintbrisson
Copy link
Contributor Author

@Veykril done!

@Veykril
Copy link
Member

Veykril commented Jan 2, 2024

Thanks!
@bors r+

@bors
Copy link
Collaborator

bors commented Jan 2, 2024

📌 Commit d9d4c5c has been approved by Veykril

It is now in the queue for this repository.

@bors
Copy link
Collaborator

bors commented Jan 2, 2024

⌛ Testing commit d9d4c5c with merge c090c56...

bors added a commit that referenced this pull request Jan 2, 2024
…h-fns, r=Veykril

fix(completion): make the expected type a tad smarter with `Fn`s

This commit changes how the expected type is calculated when
working with Fn pointers, making the parenthesis stop vanishing
when completing the function name.

I've been bugged by the behavior of parenthesis completion for
a long while now. R-a assumes that the `LetStmt` type is the same
as the function type I've just written. Worse is that all parenthesis
vanish, even from functions that have completely different signatures.
It will now verify if the signature is the same.

While working on this, I noticed that record fields behave the same,
so I also made it prioritize the field type instead of the current
expression when possible, but I'm unsure if this is OK, so input is
appreciated.

ImplTraits as return types will still behave weirdly because lowering
is disallowed at the time it resolves the function types.

![image](https://github.com/rust-lang/rust-analyzer/assets/29989290/c06d6c93-5cac-4ebe-a93b-923017a6ae8c)
![image](https://github.com/rust-lang/rust-analyzer/assets/29989290/31594d82-fa4d-446c-a77e-47e9de1a9a67)
![image](https://github.com/rust-lang/rust-analyzer/assets/29989290/cf33856e-a485-411b-91af-11090d78a44e)
@bors
Copy link
Collaborator

bors commented Jan 2, 2024

💔 Test failed - checks-actions

@Veykril
Copy link
Member

Veykril commented Jan 2, 2024

Needs a rebase + reblessing the tests it seems as the output has changed.

This commit changes how the expected type is calculated when working
with Fn pointers, making the parenthesis stop vanishing when completing
the function name.

I've been bugged by the behaviour on parenthesis completion for a long
while now. R-a assumes that the `LetStmt` type is the same as the
function type I've just written. Worse is that all parenthesis vanish,
even from functions that have completely different signatures. It will
now verify if the signature is the same.

While working on this, I noticed that record fields behave the same, so
I also made it prioritize the field type instead of the current
expression when possible, but I'm unsure if this is OK, so input is
appreciated.

ImplTraits as return types will still behave weirdly because lowering is
disallowed at the time it resolves the function types.
@saiintbrisson saiintbrisson force-pushed the fix/completion/a-tad-smarter-with-fns branch from d9d4c5c to 9a36bc3 Compare January 2, 2024 13:31
@Veykril
Copy link
Member

Veykril commented Jan 2, 2024

@bors r+

@bors
Copy link
Collaborator

bors commented Jan 2, 2024

📌 Commit 9a36bc3 has been approved by Veykril

It is now in the queue for this repository.

@bors
Copy link
Collaborator

bors commented Jan 2, 2024

⌛ Testing commit 9a36bc3 with merge 7659109...

@bors
Copy link
Collaborator

bors commented Jan 2, 2024

☀️ Test successful - checks-actions
Approved by: Veykril
Pushing 7659109 to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants