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

completion relevance consider if types can be unified #8056

Merged
merged 2 commits into from
Mar 26, 2021

Conversation

JoshMcguigan
Copy link
Contributor

This PR improves completion relevance scoring for generic types, in cases where the types could unify.

Before

pre-could-unify

After

post-could-unify

changelog feature improve completions

@JoshMcguigan
Copy link
Contributor Author

I do have a few questions since I am not very familiar with the type inference code. @flodiebold ?

  1. Am I using type inference correctly? It seems to work in this case, but I'm not sure if there are any rough edges to be aware of.
  2. Does it make sense to add these inference functions to the public interface of hir_ty/hir as I do here?
  3. Is there an easy fix to make this work for functions which a generic parameter in their return type fn foo<T>() -> Option<T> as shown in the FIXME in the unit test?

@JoshMcguigan
Copy link
Contributor Author

Hmm, CI is failing for a lint I don't see locally. And applying the fix breaks compilation.

  --> crates/hir_ty/src/infer.rs:48:1
   |
48 | pub use unify::could_unify;
   | ---^^^^^^^^^^^^^^^^^^^^^^^^
   | |
   | help: consider restricting its visibility: `pub(crate)`
   |
   = note: `-D unreachable-pub` implied by `-D warnings`

@lnicola
Copy link
Member

lnicola commented Mar 16, 2021

We use stable on CI, FYI.

@JoshMcguigan
Copy link
Contributor Author

$ rustup --version
rustup 1.23.1 (3df2264a9 2020-11-30)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.50.0 (cb75ad5db 2021-02-10)`

I believe I'm running with the latest stable compiler locally. I can re-create the lint by running RUSTFLAGS="-D warnings -W unreachable-pub" cargo check locally, as described in the ci config.

But I'm still not sure why I'm seeing this lint, given the suggested fix doesn't work.

@JoshMcguigan
Copy link
Contributor Author

JoshMcguigan commented Mar 16, 2021

Looks like this is the same as a bug reported a couple years ago, although it seems that was fixed 🤷

rust-lang/rust#52664

rust-lang/rust#47816

@JoshMcguigan
Copy link
Contributor Author

JoshMcguigan commented Mar 16, 2021

Actually it looks like there is a newer bug report for this, which is still open. I suppose I should add an #[allow(unreachable_pub)] on this item for now?

rust-lang/rust#57411

@flodiebold
Copy link
Member

flodiebold commented Mar 16, 2021

Does it make sense to add these inference functions to the public interface of hir_ty/hir as I do here?

I think adding it for now is fine. We might revamp the HIR type API, but only after the Chalk move.

Am I using type inference correctly? It seems to work in this case, but I'm not sure if there are any rough edges to be aware of.
Is there an easy fix to make this work for functions which a generic parameter in their return type fn foo() -> Option as shown in the FIXME in the unit test?

So, the problem here is that the Function::ret_type gives us the declared return type, which is ok for displaying, but that's not quite the type we would get when we call it. We would want to fill in the type parameters, using type variables where we don't know them yet (imagine e.g. if we have an Option<Foo> and call unwrap() on it, then can already tell the returned value will be Foo). That's not trivial though. Of course for non-method calls, we could probably mostly get by with just replacing placeholders by Unknown before the unify check.

(Also worth noting that what we'd really want is to check coercion, if the completion is happening at a coercion site...)

@matklad
Copy link
Member

matklad commented Mar 17, 2021

Let’s distinguish between “can unify” and “exact match” in the relevance, so that things like Default::default are less relevant than specific types.

@JoshMcguigan JoshMcguigan force-pushed the completion-relevance-could-unify branch 2 times, most recently from 24e6a9f to e80e58c Compare March 23, 2021 04:23
@@ -122,7 +122,7 @@ impl fmt::Debug for CompletionItem {
}
}

#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Default)]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These weren't used, because CompletionRelevance should only be compared by score. I could re-implement them in terms of score, but that would require updating the Eq impl which we use in a different way, so it would broaden the scope of this PR a bit.

The reason I removed these at all in this PR is because it didn't make sense to me to derive them on the new enum CompletionRelevanceTypeMatch.

/// ```
/// fn foo() {
/// let bar = 0;
/// $0 // `bar` is local
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change is unrelated to this PR, but combining these two examples has been discussed as something we'd like to do.

@JoshMcguigan JoshMcguigan force-pushed the completion-relevance-could-unify branch from e80e58c to 80dac6a Compare March 23, 2021 04:31
@JoshMcguigan
Copy link
Contributor Author

Let’s distinguish between “can unify” and “exact match” in the relevance, so that things like Default::default are less relevant than specific types.

I've updated this to distinguish between these cases, and score an exact match as more relevant than types which can unify.

@JoshMcguigan JoshMcguigan force-pushed the completion-relevance-could-unify branch from 80dac6a to e6891dc Compare March 26, 2021 16:11
@JoshMcguigan JoshMcguigan force-pushed the completion-relevance-could-unify branch from e6891dc to 0e31ae2 Compare March 26, 2021 16:18
@JoshMcguigan
Copy link
Contributor Author

bors r+

@bors
Copy link
Contributor

bors bot commented Mar 26, 2021

@bors bors bot merged commit 4ecaad9 into rust-lang:master Mar 26, 2021
@lnicola
Copy link
Member

lnicola commented Mar 26, 2021

changelog feature for completion, take into account whether types unify:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants