Suggest case insensitive import suggestions - #156239
Conversation
36cee45 to
a23f444
Compare
|
I see from the 247 failed tests that 1-edit difference is too big for small names. 'net' should probably NOT be suggested to replace 'new'... Edit: i have now switched to case insensitive match only. |
This comment has been minimized.
This comment has been minimized.
fdc8fcc to
2893b67
Compare
|
r? @TaKO8Ki rustbot has assigned @TaKO8Ki. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
|
upstream change #157991 contains commit cd2d10a and 4f6a600 from #157974 which do some weird file swapping instead of renamings that completely confuses and breaks my rebase attempts. If this is not a skill issue on my part, maybe avoiding this kind of file swapping and splitting this in multiple rename commits would help git not getting confused ? |
1bcb37c to
981c290
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
65853f4 to
1fdd975
Compare
|
For anyone having trouble with the file swap, my cleanest solution is:
# make patches out of my commits
git format-patch HEAD~7..HEAD
# edit the patch files to change the file path
sed -i 's|a/compiler/rustc_resolve/src/diagnostics.rs|a/compiler/rustc_resolve/src/error_helper.rs|g; s|b/compiler/rustc_resolve/src/diagnostics.rs|b/compiler/rustc
_resolve/src/error_helper.rs|g' *.patch
# create new 'fix-swapped-files' branch from upstream latest
git checkout -b fix-swapped-files <upstream>/main
# apply updated patches
git am --committer-date-is-author-date *.patch |
Co-authored-by: Chris Simpkins <git.simpkins@gmail.com>
adds a is_exact_match field to ImportSuggestion use is_exact_match field to customize help message suggest imports with different casing -only suggest modules if the following segment matches too
When a pattern has `..` and a matching binding, suggest replacing `..` with `binding, ..`
1fdd975 to
9f894a0
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
☔ The latest upstream changes (presumably #158942) made this pull request unmergeable. Please resolve the merge conflicts by rebasing. |
|
@rustbot reroll |
There was a problem hiding this comment.
During this PR, I ended up adding two other things which could arguably be two separate PRs
I think it would be good to extract them as separate PRs. Let's keep this PR only related to case-insensitive import suggestions.
And, please squash the commits to three commits, which would be helpful to review:
- Adding tests and make a snapshot of current compiler behavior
- The new implementation
- Bless tests
@rustbot author
| | | ||
| help: consider importing one of these similarly named items | ||
| | | ||
| LL + use std::fmt::Error; | ||
| | | ||
| LL + use std::fs::TryLockError::Error; | ||
| | |
There was a problem hiding this comment.
I think such suggestions may not be what we expect.
Considering let x = HashMap;, we won't suggest importing HashMap because it is in the type namespace but we expect value namespace.
There was a problem hiding this comment.
Basically we want the suggested imports to be in the same namespace.
There was a problem hiding this comment.
Ok, so I had to dive deep; there are two similar but distinct cases here.
I am writing this down as much for myself as for anyone else.
std::fmt::Error
Error here is a struct. It gets to live in two namespaces: TypeNS and ValueNS.
In this case, Error is a unit struct, it gets both a type and a const constructor with a DefKind of Ctor( Struct, Const,) that gets matched to ValueNS
DefKind::Fn | DefKind::Const { .. } | DefKind::ConstParam | DefKind::Static { .. } | DefKind::Ctor(..) | DefKind::AssocFn | DefKind::AssocConst { .. } => Some(Namespace::ValueNS),
std::fs::TryLock::Error
Error is an enum variant. It also get to be in the same two namespaces because of two distinct DefKinds:
a Variant DefKind gets mapped to the TypeNS namespace and the variant constructor gets a Ctor( Variant, Fn, ) DefKind (it is not a unit variant).
The same mapping as above places the constructor in the ValueNS namespace.
Therefore, fmt::Error is a valid suggestion.
For fs::TryLock::Error, I am looking into filtering the suggestion if it requires more parameters than provided.
There was a problem hiding this comment.
I test this on nightly, i.e, let x = Error;. it will emit the same suggestion.
So I think it is good enough to keep the behavior have implemented here.
And for the filter, I think don't need to implement it. IMO, we could assume user even don't know it requires parameters or not, so we could still emit them.
But we could sort them (I'm not sure we have done it or not) based on the these conditions. And also this could be a separate PR.
Sorry for the confusing, I should test the same case instead of different ones firstly. And thanks for your investigation.
| | | ||
| LL + use std::range::Range; | ||
| | | ||
| LL + use std::range::legacy::Range; |
There was a problem hiding this comment.
I think it would be good if this could be consistent with what we suggest for Range, currently we will get:
error[E0425]: cannot find type `Range` in this scope
--> src/lib.rs:1:11
|
1 | fn foo(x: Range) {}
| ^^^^^ not found in this scope
|
help: consider importing one of these items
|
1 + use std::collections::btree_map::Range;
|
1 + use std::collections::btree_set::Range;
|
1 + use std::range::Range;
|
1 + use std::range::legacy::Range;
|
= and 10 other candidates
There was a problem hiding this comment.
I am not seeing these 10 other candidates suggestions when running the same test on the current nightly or sable releases:
error[E0425]: cannot find type `Range` in this scope
--> src/main.rs:8:16
|
8 | fn range(r:Range){}
| ^^^^^ not found in this scope
|
help: consider importing one of these structs
|
8 + use std::collections::btree_map::Range;
|
8 + use std::collections::btree_set::Range;
|
8 + use std::range::Range;
|
8 + use std::range::legacy::Range;
|
= and 2 other candidates
on latest main (no other candidates):
error[E0425]: cannot find type `Range` in this scope
--> $DIR/libstd.rs:272:19
|
LL | fn test_Range(_x: Range){}
| ^^^^^ not found in this scope
|
help: consider importing one of these structs
|
LL + use std::collections::btree_map::Range;
|
LL + use std::collections::btree_set::Range;
|
LL + use std::range::Range;
|
LL + use std::range::legacy::Range;
|
I reporting the same things for range (lowercase) as the main branch reports for Range (uppercase).
Unless I am missing something?
There was a problem hiding this comment.
Oh, sorry for this, I found it on stable (play), it would emit:
Compiling playground v0.0.1 (/playground)
error[E0425]: cannot find type `Range` in this scope
--> src/lib.rs:1:11
|
1 | fn foo(x: Range) {}
| ^^^^^ not found in this scope
|
help: consider importing one of these structs
|
1 + use std::collections::btree_map::Range;
|
1 + use std::collections::btree_set::Range;
|
1 + use std::ops::Range;
|
1 + use std::range::Range;
|
= and 2 other candidates
But on nightly, it suggests the same to this PR. So just ignore this :)
There was a problem hiding this comment.
Seems #125687 has stabilized recently, so this change in the last commit is because rebasing, I guess, right?
Just want to make sure I don't miss something.
| if let Some(errcode) = err.code | ||
| && errcode.index() == 425 |
| } | ||
| /// Based on a subset of try_lookup_relaxed, this looks for import candidates in a case insensitive manner. | ||
| /// We do not suggest alternative capitalizations if only one letter long, too many constants can match and it becomes noisy. | ||
| fn try_lookup_import_case_insensitive( |
There was a problem hiding this comment.
Could we re-use try_lookup_name_relaxed? E.g., adding a mode param for that function and re-use most logic in it, instead of adding a new function here.
|
Reminder, once the PR becomes ready for a review, use |
This PR proposes case insensitive import suggestions.
Previous discussion of this topic here: #72641 and in this PR: #72988
If that is still of interest, a discussion may be needed to limit or expand the included list.
I initially followed the suggestions in #72988.
The tests are based on the tests by @chrissimpkins in #72988.
I added a
is_exact_matchfield toImportSuggestionto modify the suggestion text accordingly.Only when no other suggestion is made, do I check for case insensitive import suggestion.
for a more complex case:
SystemTimeexists in the stdlib, but I only suggest case insensitive import when nothing else is suggestedDuring this PR, I ended up adding two other things which could arguably be two separate PRs:
filtering out typos suggestions that do not have parameters when the typo has some
motivation: It suggested Clone (no parameter) for the std
cloned<(),()>test when I expectedCloned<(),()>to be suggested.when suggesting that a missing binding is available in a pattern but not used because behind a
.., suggest a MaybeIncorrect fix.motivation: this way, I can avoid looking for imports if there is a suggestion.
custom import message for case insensitive suggestion.
only suggest case insensitive when no other suggestion is made
check for enum variant match before suggesting an enum
check for enum variant parameter requirement before suggesting an enum
check with reviewers where to place the test, and whether to rename them
squash and split commits for a clean PR