From ce73bc7d47fc58d5e1436df10b2a2ceaddf511bd Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 28 Dec 2018 05:20:11 +0300 Subject: [PATCH] resolve: Fix an ICE in import validation --- src/librustc_resolve/resolve_imports.rs | 18 ++++++++++++------ .../uniform-paths/auxiliary/issue-56596.rs | 1 + .../ui/rust-2018/uniform-paths/issue-56596.rs | 14 ++++++++++++++ .../rust-2018/uniform-paths/issue-56596.stderr | 18 ++++++++++++++++++ 4 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/rust-2018/uniform-paths/auxiliary/issue-56596.rs create mode 100644 src/test/ui/rust-2018/uniform-paths/issue-56596.rs create mode 100644 src/test/ui/rust-2018/uniform-paths/issue-56596.stderr diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 9a7b8c24993..5830aa3713d 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -223,11 +223,6 @@ impl<'a> Resolver<'a> { } let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| { - if let Some(blacklisted_binding) = this.blacklisted_binding { - if ptr::eq(binding, blacklisted_binding) { - return Err((Determined, Weak::No)); - } - } // `extern crate` are always usable for backwards compatibility, see issue #37020, // remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`. let usable = this.is_accessible(binding.vis) || binding.is_extern_crate(); @@ -235,7 +230,18 @@ impl<'a> Resolver<'a> { }; if record_used { - return resolution.binding.ok_or((Determined, Weak::No)).and_then(|binding| { + return resolution.binding.and_then(|binding| { + // If the primary binding is blacklisted, search further and return the shadowed + // glob binding if it exists. What we really want here is having two separate + // scopes in a module - one for non-globs and one for globs, but until that's done + // use this hack to avoid inconsistent resolution ICEs during import validation. + if let Some(blacklisted_binding) = self.blacklisted_binding { + if ptr::eq(binding, blacklisted_binding) { + return resolution.shadowed_glob; + } + } + Some(binding) + }).ok_or((Determined, Weak::No)).and_then(|binding| { if self.last_import_segment && check_usable(self, binding).is_err() { Err((Determined, Weak::No)) } else { diff --git a/src/test/ui/rust-2018/uniform-paths/auxiliary/issue-56596.rs b/src/test/ui/rust-2018/uniform-paths/auxiliary/issue-56596.rs new file mode 100644 index 00000000000..bc010a3dd2b --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/auxiliary/issue-56596.rs @@ -0,0 +1 @@ +// Nothing here diff --git a/src/test/ui/rust-2018/uniform-paths/issue-56596.rs b/src/test/ui/rust-2018/uniform-paths/issue-56596.rs new file mode 100644 index 00000000000..5c40d78d81c --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/issue-56596.rs @@ -0,0 +1,14 @@ +// edition:2018 +// compile-flags: --extern issue_56596 +// aux-build:issue-56596.rs + +#![feature(uniform_paths)] + +mod m { + pub mod issue_56596 {} +} + +use m::*; +use issue_56596; //~ ERROR `issue_56596` is ambiguous + +fn main() {} diff --git a/src/test/ui/rust-2018/uniform-paths/issue-56596.stderr b/src/test/ui/rust-2018/uniform-paths/issue-56596.stderr new file mode 100644 index 00000000000..293d0ec6a72 --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/issue-56596.stderr @@ -0,0 +1,18 @@ +error[E0659]: `issue_56596` is ambiguous (name vs any other name during import resolution) + --> $DIR/issue-56596.rs:12:5 + | +LL | use issue_56596; //~ ERROR `issue_56596` is ambiguous + | ^^^^^^^^^^^ ambiguous name + | + = note: `issue_56596` could refer to an extern crate passed with `--extern` + = help: use `::issue_56596` to refer to this extern crate unambiguously +note: `issue_56596` could also refer to the module imported here + --> $DIR/issue-56596.rs:11:5 + | +LL | use m::*; + | ^^^^ + = help: use `crate::issue_56596` to refer to this module unambiguously + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0659`.