-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Don't print name resolution errors if a crate fails to load #96799
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
I tried this diff: diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 62485beac47..f1900700946 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1537,19 +1537,26 @@ fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
}
/// Entry point to crate resolution.
- pub fn resolve_crate(&mut self, krate: &Crate) {
+ pub fn resolve_crate(&mut self, krate: &Crate) -> Result<(), ErrorGuaranteed> {
self.session.time("resolve_crate", || {
self.session.time("finalize_imports", || ImportResolver { r: self }.finalize_imports());
self.session.time("resolve_access_levels", || {
AccessLevelsVisitor::compute_access_levels(self, krate)
});
self.session.time("finalize_macro_resolutions", || self.finalize_macro_resolutions());
+ // If we can't find all imports, we run into cascading errors where all imported items are marked as unresolved.
+ // Avoid that by aborting early if we can't resolve all imports.
+ if let Some(reported) = self.session.has_errors() {
+ return Err(reported);
+ }
self.session.time("late_resolve_crate", || self.late_resolve_crate(krate));
self.session.time("resolve_main", || self.resolve_main());
self.session.time("resolve_check_unused", || self.check_unused(krate));
self.session.time("resolve_report_errors", || self.report_errors(krate));
self.session.time("resolve_postprocess", || self.crate_loader.postprocess(krate));
- });
+
+ Ok(())
+ })
}
pub fn traits_in_scope( which I think would work, and additionally have the benefit of aborting early soon after cc @petrochenkov - before I spend more time on this, do you think it's a good idea? |
I don't think that's a good idea. In cases like use my::import; // unresolved import
let x = import::y; we should already skip the error on Unresolved names in https://github.com/rust-lang/rust/runs/6331341497?check_suite_focus=true#step:26:783 mostly come from the standard library prelude. |
@petrochenkov here is a more realistic case: use regx::*;
fn main() {
Regex::new("[0-9]+").unwrap();
} That gives an error about code that would be correct if the import were resolved:
I've seen this happen for things besides glob imports in the past but I don't remember them off the top of my head; I'll post here if I come across one. |
Oh, here's another good one: when macros fail to expand, you get cascading errors about the items that they fail to define. https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b1a05f74b54686ec591b0782ce07a4ac macro_rules! m {
() => {
cost X: &str = "hi";
const Y: &str = "hello";
}
}
m!();
fn main() {
println!("{} {}", X, Y);
} |
Another cascading error from type check: the
|
This is a common situation if you don't have a target installed #0 14.21 error[E0463]: can't find crate for `core`
#0 14.21 --> /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/memchr-2.5.0/src/memchr/mod.rs:1:5
#0 14.21 |
#0 14.21 1 | use core::iter::Rev;
#0 14.21 | ^^^^ can't find crate
#0 14.21 |
#0 14.21 = note: the `wasm32-unknown-unknown` target may not be installed
#0 14.21 = help: consider downloading the target with `rustup target add wasm32-unknown-unknown`
#0 14.21 = help: consider building the standard library from source with `cargo build -Zbuild-std`
... 214 multiline name resolution errors referring to things like `Some` ... |
When encountering `use foo::*;` where `foo` fails to be found, and we later encounter resolution errors, we silence those later errors. A single case of the above, for an *existing* import on a big codebase would otherwise have a huge number of knock-down spurious errors. Ideally, instead of a global flag to silence all subsequent resolve errors, we'd want to introduce an unameable binding in the appropriate rib as a sentinel when there's a failed glob import, so when we encounter a resolve error we can search for that sentinel and if found, and only then, silence that error. The current approach is just a quick proof of concept to iterate over. Partially address rust-lang#96799.
When encountering `use foo::*;` where `foo` fails to be found, and we later encounter resolution errors, we silence those later errors. A single case of the above, for an *existing* import on a big codebase would otherwise have a huge number of knock-down spurious errors. Ideally, instead of a global flag to silence all subsequent resolve errors, we'd want to introduce an unameable binding in the appropriate rib as a sentinel when there's a failed glob import, so when we encounter a resolve error we can search for that sentinel and if found, and only then, silence that error. The current approach is just a quick proof of concept to iterate over. Partially address rust-lang#96799.
When encountering `use foo::*;` where `foo` fails to be found, and we later encounter resolution errors, we silence those later errors. A single case of the above, for an *existing* import on a big codebase would otherwise have a huge number of knock-down spurious errors. Ideally, instead of a global flag to silence all subsequent resolve errors, we'd want to introduce an unameable binding in the appropriate rib as a sentinel when there's a failed glob import, so when we encounter a resolve error we can search for that sentinel and if found, and only then, silence that error. The current approach is just a quick proof of concept to iterate over. Partially address rust-lang#96799.
Silence some resolve errors when there have been glob import errors When encountering `use foo::*;` where `foo` fails to be found, and we later encounter resolution errors, we silence those later errors. A single case of the above, for an *existing* import on a big codebase would otherwise have a huge number of knock-down spurious errors. Ideally, instead of a global flag to silence all subsequent resolve errors, we'd want to introduce an unnameable binding in the appropriate rib as a sentinel when there's a failed glob import, so when we encounter a resolve error we can search for that sentinel and if found, and only then, silence that error. The current approach is just a quick proof of concept to iterate over. Partially address rust-lang#96799.
Silence some resolve errors when there have been glob import errors When encountering `use foo::*;` where `foo` fails to be found, and we later encounter resolution errors, we silence those later errors. A single case of the above, for an *existing* import on a big codebase would otherwise have a huge number of knock-down spurious errors. Ideally, instead of a global flag to silence all subsequent resolve errors, we'd want to introduce an unnameable binding in the appropriate rib as a sentinel when there's a failed glob import, so when we encounter a resolve error we can search for that sentinel and if found, and only then, silence that error. The current approach is just a quick proof of concept to iterate over. Partially address rust-lang#96799.
Rollup merge of rust-lang#125381 - estebank:issue-96799, r=petrochenkov Silence some resolve errors when there have been glob import errors When encountering `use foo::*;` where `foo` fails to be found, and we later encounter resolution errors, we silence those later errors. A single case of the above, for an *existing* import on a big codebase would otherwise have a huge number of knock-down spurious errors. Ideally, instead of a global flag to silence all subsequent resolve errors, we'd want to introduce an unnameable binding in the appropriate rib as a sentinel when there's a failed glob import, so when we encounter a resolve error we can search for that sentinel and if found, and only then, silence that error. The current approach is just a quick proof of concept to iterate over. Partially address rust-lang#96799.
When encountering `use foo::*;` where `foo` fails to be found, and we later encounter resolution errors, we silence those later errors. A single case of the above, for an *existing* import on a big codebase would otherwise have a huge number of knock-down spurious errors. Ideally, instead of a global flag to silence all subsequent resolve errors, we'd want to introduce an unameable binding in the appropriate rib as a sentinel when there's a failed glob import, so when we encounter a resolve error we can search for that sentinel and if found, and only then, silence that error. The current approach is just a quick proof of concept to iterate over. Partially address rust-lang#96799.
This is still a problem: #118129 shows >1800 errors, and the last ~1700 are all irrelevant name resolution failures. One has to scroll up through many screens of output to see the actually relevant crate loading errors at the top. |
@petrochenkov as @Nemo157 wrote above, even "standard library not found" errors can easily occur on stable. And explicit Is there some strategy for avoiding thousands of pointless follow-up errors after a failed crate load that you would be okay with? |
Given the following code: 7342286
The current output is: several hundred thousand lines long. https://github.com/rust-lang/rust/runs/6331341497?check_suite_focus=true#step:26:783
Ideally the output should look like: not that. Just the errors about crate loading:
The failures from name resolution are almost always because of unresolved imports from the missing crate, and showing them hurts more than it helps.
@rustbot label +A-resolve
The text was updated successfully, but these errors were encountered: