-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Don't print name resolution errors if a crate fails to load #96799
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.
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: