-
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
Surface multiple "can't find crate" errors at a time #90702
Comments
I think this should be as simple as removing the rust/compiler/rustc_metadata/src/locator.rs Line 1214 in 495322d
|
You'll also have to find some reasonable behavior to do for the places currently calling
@petrochenkov may have suggestions. |
Not so sure, most such calls are introduced because it's tricky to have the compiler keep marching on after it already knows it's operating on bad code. For example, the error for an It might be worth getting the resolver to continue looking for crates but nothing else (or something similar? idk). cc @estebank who probably has thoughts on how to correctly get the compiler to keep marching on after seeing errors that are the upstream cause of a lot of other errors that would be emitted if it kept naïvely marching on. I know we do this well in a bunch of places. |
At a minimum it would be ok to:
Our only hope here is probably to search for further extern crates, and extern crate serdy;
mod ohno {
extern crate hypur;
}
const _: () = { extern crate aho_korasic; } would be nice... (I say this having ~little knowledge of the HIR.) |
@jyn514 I'm looking for a beginner friendly mentored issue to start. Is it okay to claim this one? |
@mjptree feel free to claim this :) but I'm not sure how easy it will be. |
@rustbot claim |
In general, when we encounter an error in a type or during parsing we try and introduce a "poison pill" for its corresponding id (DefId, generally) or to the node being computed. This way we can check for these cases and silence errors. Otherwise So the file that you likely want to start looking at is https://github.com/rust-lang/rust/blob/9f6ca7482ca885bca14ba6870ed39a783ab939b5/compiler/rustc_resolve/src/lib.rs On a quick glance, Then I would look at
particularly rust/compiler/rustc_resolve/src/build_reduced_graph.rs Lines 701 to 707 in 9f6ca74
digging into it brought me to rust/compiler/rustc_metadata/src/creader.rs Line 1014 in 2834f57
which led me to rust/compiler/rustc_metadata/src/creader.rs Lines 510 to 522 in 2834f57
which is where we are causing the error to be emitted today. We must instead report and continue. To do so, I would try and change the call to Ping me if you need more context! |
@estebank Thank you so much for the information! This is really helpful. I ran into some rather unexpected problems yesterday trying to set up my working environment and spent my evening puzzling over some spurious build errors on a freshly cloned repo. I blame it on me having already updated to Windows 11 for now and tackle it one issue at a time, beginning with this one that I committed to :). I tried to start at rust/compiler/rustc_metadata/src/locator.rs Line 934 in d212d90
like jyn514 already mentioned, and walk backwards from there to all invocations, that could cause a CrateError::report and a subsequent abort.
Like you, I arrived also in
and also interestingly (or less so - can't judge at this point) rust/compiler/rustc_metadata/src/locator.rs Lines 811 to 822 in d212d90
which is probably less relevant, because as far as I can tell rust/compiler/rustc_plugin_impl/src/load.rs Lines 27 to 61 in d212d90
these functions are not called anywhere at the moment. Does "plugins" in this context refer to proc-macros? I'll have a closer look at rust/compiler/rustc_metadata/src/creader.rs Line 1014 in 2834f57
as you mentioned, as it looks the most promising. It would be good to see an applied example of the "poison pill" mechanism that you mentioned, in a similar context. Also, I'm not familiar with this |
Plugins were the way you could modify how the compiler behaved before proc-macros were designed. They are still in the codebase, but they were never in a path to stabilization. They worked similarly in By "poison pill" I mean something like enum TyKind {
Adt(Def, Substs),
Str,
Infer(InferTy),
/// Placeholder used to silence errors
Err,
}
|
I think I'm coming closer to a solution: I was using these two examples as a starting point
Because you already mentioned that in the case of failed rust/compiler/rustc_interface/src/passes.rs Lines 260 to 266 in 9dbbbb1
where rust/compiler/rustc_interface/src/passes.rs Lines 332 to 333 in 9dbbbb1
whereas rust/compiler/rustc_interface/src/passes.rs Line 432 in 9dbbbb1
In the latter case, the rust/compiler/rustc_resolve/src/imports.rs Line 661 in 82af160
where unresolved imports are imported as dummy bindings rust/compiler/rustc_resolve/src/imports.rs Lines 687 to 689 in 82af160
and only collectively thrown, when all imports have been attempted to be resolved. Maybe, if early rust/compiler/rustc_resolve/src/late.rs Line 2513 in 68568dc
but it doesn't really seem to do anything rust/compiler/rustc_resolve/src/late.rs Lines 1077 to 1079 in c8e9497
|
If you make a PR addressing this please assign it to me. |
A first tentative solution on my fork. It achieves the desired behaviour, but I'm still a bit reluctant to open a PR just yet:
Maybe, if @estebank or @petrochenkov could judge? |
I didn't read the thread in detail, but the right strategy is most likely to produce a binding with Then errors for all |
@mjptree if you'd like someone to review the code, please open a PR. You can always make further changes after review :) |
There are still some interplays between types, that I'm not sure I properly understand. My current approach to handling match self.r.crate_loader.process_extern_crate(
item,
&self.r.definitions,
local_def_id,
) {
Ok(crate_id) => {
self.r.extern_crate_map.insert(local_def_id, crate_id);
self.r.expect_module(crate_id.as_def_id())
}
Err(err) => {
err.report(&self.r.session);
let fake = self.r.arenas.alloc_import(Import {
kind: ImportKind::ExternCrate { source: orig_name, target: ident },
root_id: item.id,
id: item.id,
parent_scope: self.parent_scope,
imported_module: Cell::new(None),
has_attributes: !item.attrs.is_empty(),
use_span_with_attributes: item.span_with_attributes(),
use_span: item.span,
root_span: item.span,
span: item.span,
module_path: Vec::new(),
vis: Cell::new(vis),
used: Cell::new(true),
});
self.r.import_dummy_binding(fake);
return;
}
} If I try to extern crate foo;
extern crate bar;
use bar::baz;
use boo::buzz;
fn main() {
foo::fuzz();
boo::buzz();
bar::buzz();
baz::buzz();
} I receive errors for both failed resolutions of
I think although the The takeaway for me is: It is not sufficient to define a dummy import for the crate names imported via I'm not sure which components are responsible for that. So far, my understanding is:
Tl;dr: I am still not 100% what the characteristics of the |
The output in #90702 (comment) is exactly what I'd expect from using Doing something to "deduplicate" the |
This looks correct.
Creating a dummy |
Here we go. My very first pull request to the Rust compiler... |
…nkov Issue 90702 fix: Stop treating some crate loading failures as fatal errors Surface mulitple `extern crate` resolution errors at a time. This is achieved by creating a dummy crate, instead of aborting directly after the resolution error. The `ExternCrateError` has been added to allow propagating the resolution error from `rustc_metadata` crate to the `rustc_resolve` with a minimal public surface. The `import_extern_crate` function is a block that was factored out from `build_reduced_graph_for_item` for better organization. The only added functionality made to it where the added error handling in the `process_extern_crate` call. The remaining bits in this function are the same as before. Resolves rust-lang#90702 r? `@petrochenkov`
…nkov Issue 90702 fix: Stop treating some crate loading failures as fatal errors Surface mulitple `extern crate` resolution errors at a time. This is achieved by creating a dummy crate, instead of aborting directly after the resolution error. The `ExternCrateError` has been added to allow propagating the resolution error from `rustc_metadata` crate to the `rustc_resolve` with a minimal public surface. The `import_extern_crate` function is a block that was factored out from `build_reduced_graph_for_item` for better organization. The only added functionality made to it where the added error handling in the `process_extern_crate` call. The remaining bits in this function are the same as before. Resolves rust-lang#90702 r? ``@petrochenkov``
It would be nice if rustc could surface multiple "can't find crate xxxx" errors at once, instead of one at a time.
Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6a10dfbf5f9cc7dc6488fc9c3efaec70
The current output is:
Ideally the output should look like:
The text was updated successfully, but these errors were encountered: