-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
resolve suggestions should use crate::
when enabled
#51456
Conversation
r? @estebank (rust_highfive has picked a reviewer for you, use r? to override) |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
src/librustc_resolve/lib.rs
Outdated
@@ -4449,7 +4451,12 @@ fn show_candidates(err: &mut DiagnosticBuilder, | |||
} else { | |||
"\n" | |||
}; | |||
*candidate = format!("use {};\n{}", candidate, additional_newline); | |||
let crate_prefix = if crate_in_paths { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, now i'm worried that this will apply even when it shouldn't. Consider this testcase:
fn main() {
let x: &Debug = &22;
}
This currently prints:
error[E0412]: cannot find type `Debug` in this scope
--> src/main.rs:2:13
|
2 | let x: &Debug = &22;
| ^^^^^ not found in this scope
help: possible candidate is found in another module, you can import it into scope
|
1 | use std::fmt::Debug;
|
and I think we do not want it to print use crate::std::fmt::Debug
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like these are produced by this function:
rust/src/librustc_resolve/lib.rs
Lines 4003 to 4015 in a32e979
/// When name resolution fails, this method can be used to look up candidate | |
/// entities with the expected name. It allows filtering them using the | |
/// supplied predicate (which should be used to only accept the types of | |
/// definitions expected e.g. traits). The lookup spans across all crates. | |
/// | |
/// NOTE: The method does not look into imports, but this is not a problem, | |
/// since we report the definitions (thus, the de-aliased imports). | |
fn lookup_import_candidates<FilterFn>(&mut self, | |
lookup_name: Name, | |
namespace: Namespace, | |
filter_fn: FilterFn) | |
-> Vec<ImportSuggestion> | |
where FilterFn: Fn(Def) -> bool |
I suspect we want to extend this struct
rust/src/librustc_resolve/lib.rs
Lines 87 to 90 in a32e979
/// A free importable items suggested in case of resolution failure. | |
struct ImportSuggestion { | |
path: Path, | |
} |
with an additional field, indicating whether the first link in the path is an extern crate
or not. Notice that the function has the ability to check whether it is an extern crate
:
rust/src/librustc_resolve/lib.rs
Lines 4030 to 4031 in a32e979
// avoid imports entirely | |
if name_binding.is_import() && !name_binding.is_extern_crate() { return; } |
In fact, we are already threading this in_module_is_extern
state around -- that is almost what we want -- it tells us if the path contains an extern crate
anywhere. But we just want to know if the path contains an extern crate
in the first link.
Actually, reading this code, I think that likely these suggestions will break once we start removing extern crate
entries. It may be that the better approach is to fix that problem, basically by iterating over the extern crates that were given on the command line first. The advantage of that is that we would not need any special logic for extern crate
. So yeah scratch what I wrote above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some notes in the issue laying out a possible alternative plan.
create::
when enabledcrate::
when enabled
Ping from triage @qmx! It's been a while since we heard from you, will you have time to work on this again? |
I think @qmx is still on this, just waiting for a bit of free time =) |
yep, I'm on it, just got overwhelmed with work :) |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
Ping from triage! @qmx we haven't heard from you for a while, will you have time to work on this PR? |
hey @stokhos - @nikomatsakis asked for more tests to be added before landing this change, and that's where I'm investing time for now |
Ping from triage @qmx! It's been a while since we heard from you, will you have time to work on this again? |
Here's the catch, it's been worked but there's no actionable "output" yet - I'm trying to figure out how to include suggestions from the prelude also (described with greater detail on the parent issue). Any suggestions on how to surface the work in progress that not necessarily materializes in commits? |
Well, don't worry about that! We ping to make sure a PR is not forgotten (and close it if it's inactive), but if the author replies we do nothing. [note for triage: maybe revisit this in two weeks instead of one?] |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
src/librustc_resolve/lib.rs
Outdated
path_segments.clone() | ||
}; | ||
let first_segment_ident = segms[0].ident; | ||
if first_segment_ident.name != "std" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I was looking into this special-casing. I think the reason that I was confused is that I thought that if you had a path like use foo::bar
, then we would only look for the crate foo
amongst the extern-prelude crates. But from skimming the code I no longer quite think that is the case. I think we'll also search the -L
directories for that crate -- and this (I believe) is exactly how use std::foo
works at all. In that case, we can remove the special case here and make instead the change below.
Still, I somehow that wasn't the desired design... so cc @eddyb and @petrochenkov -- how do we get the full list of crates that can be used with an explicit extern crate
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eddyb, @petrochenkov -- for context, what we are trying to do is to search the "available" crates for completion, but avoid duplicates from where there is an extern crate
...
src/librustc_resolve/lib.rs
Outdated
let is_extern_crate_that_also_appears_in_prelude = | ||
name_binding.is_extern_crate() && | ||
self.session.rust_2018() && | ||
self.extern_prelude.contains(&ident.name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if my new understanding is correct, I think we can just remove this self.extern_prelude.contains(&ident.name)
line and we don't need to special case std at all.
I missed this comment earlier. I'm a bit confused though -- in Rust 2018, at least, won't |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one nit but looks good!
|
||
all: | ||
$(RUSTC) ep-nested-lib.rs | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dumb question but I forget -- in Makefiles -- what happens with a blank line like this? I think we should remove it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
afaik, nothing, and the other run-make tests do the same for separating the libs from the executables
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok fine fine
all: | ||
$(RUSTC) ep-nested-lib.rs | ||
|
||
$(RUSTC) use-suggestions.rs --edition=2018 --extern ep_nested_lib=$(TMPDIR)/libep_nested_lib.rlib 2>&1 | $(CGREP) "use ep_nested_lib::foo::bar::Baz" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@bors r+ |
📌 Commit d9791d6 has been approved by |
resolve suggestions should use `crate::` when enabled I couldn't find a way to add a specific assertion for the ui test, so the expected output is living under the `crates-in-path.stderr` ui test. - is this the right place for the test? fixes #51212
☀️ Test successful - status-appveyor, status-travis |
I couldn't find a way to add a specific assertion for the ui test, so the expected output is living under the
crates-in-path.stderr
ui test.fixes #51212