Skip to content
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

Fix ICE with use clippy::a::b; #83336

Merged
merged 1 commit into from
Mar 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -955,14 +955,14 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
}
return None;
}
PathResult::NonModule(path_res) if path_res.base_res() == Res::Err => {
PathResult::NonModule(_) => {
if no_ambiguity {
assert!(import.imported_module.get().is_none());
}
// The error was already reported earlier.
return None;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be

            PathResult::NonModule(path_res) => {
                if no_ambiguity {
                    assert!(import.imported_module.get().is_none());
                }
                // The error was already reported earlier.
                return None;
            }

Res::Err was used to discern between reachable cases and (seemingly) unreachable cases.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, why do clippy::a and clippy::a::b seem to go through very different code paths? clippy::a didn't trigger the ICE, only clippy::a::b.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what exactly happens there, but both imports and tool attributes are "special" in some regards.

  • Import paths are split into two parts - module (everything except for the last segment, type namespace) and the final segment resolved multiple times in all namespaces.
  • Tool attributes are also split into two parts but in a different way - the first segment resolved as a tool module, and all other segments that are not even resolved (because no definitions for them exist in source code), just automatically assumed to be a tool attribute. (Perhaps the implementation is taking a shortcut here and it could be done better, at least for diagnostics.)

When you combine these two special cases together you get some unique code paths.

PathResult::Indeterminate | PathResult::NonModule(..) => unreachable!(),
PathResult::Indeterminate => unreachable!(),
};

let (ident, target, source_bindings, target_bindings, type_ns_only) = match import.kind {
Expand Down
7 changes: 7 additions & 0 deletions src/test/ui/imports/tool-mod-child.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use clippy::a; //~ ERROR unresolved import `clippy`
use clippy::a::b; //~ ERROR failed to resolve: maybe a missing crate `clippy`?

use rustdoc::a; //~ ERROR unresolved import `rustdoc`
use rustdoc::a::b; //~ ERROR failed to resolve: maybe a missing crate `rustdoc`?

fn main() {}
28 changes: 28 additions & 0 deletions src/test/ui/imports/tool-mod-child.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
error[E0433]: failed to resolve: maybe a missing crate `clippy`?
--> $DIR/tool-mod-child.rs:2:5
|
LL | use clippy::a::b;
| ^^^^^^ maybe a missing crate `clippy`?

error[E0432]: unresolved import `clippy`
--> $DIR/tool-mod-child.rs:1:5
|
LL | use clippy::a;
| ^^^^^^ maybe a missing crate `clippy`?

error[E0433]: failed to resolve: maybe a missing crate `rustdoc`?
--> $DIR/tool-mod-child.rs:5:5
|
LL | use rustdoc::a::b;
| ^^^^^^^ maybe a missing crate `rustdoc`?

error[E0432]: unresolved import `rustdoc`
--> $DIR/tool-mod-child.rs:4:5
|
LL | use rustdoc::a;
| ^^^^^^^ maybe a missing crate `rustdoc`?

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0432, E0433.
For more information about an error, try `rustc --explain E0432`.