about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-03-23 04:26:10 +0100
committerGitHub <noreply@github.com>2020-03-23 04:26:10 +0100
commit08dfd1344c47c5a7e3abbee10db6d0bcfde6d107 (patch)
treeec6e5dcc55e49994a51a7701edc0f2cfc004620f /src
parent11f5309858db86d0419e53fbb5eb622c87664e3b (diff)
parente543e3187c7d82149819c0044515336524086078 (diff)
downloadrust-08dfd1344c47c5a7e3abbee10db6d0bcfde6d107.tar.gz
rust-08dfd1344c47c5a7e3abbee10db6d0bcfde6d107.zip
Rollup merge of #70236 - petrochenkov:globimpice, r=ecstatic-morse
resolve: Avoid "self-confirming" import resolutions in one more case

So the idea behind "blacklisted bindings" is that we must ignore some name definitions during resolution because otherwise they cause infinite cycles.
E.g. import
```rust
use my_crate;
```
would refer to itself (on 2018 edition) without this blacklisting, because `use my_crate;` is the first name in scope when we are resolving `my_crate` here.

In this PR we are doing this blacklisting for the case
```rust
use same::same;
```
, namely blacklisting the second `same` when resolving the first `same`.
This was previously forgotten.

Fixes https://github.com/rust-lang/rust/issues/62767
Diffstat (limited to 'src')
-rw-r--r--src/librustc_resolve/imports.rs9
-rw-r--r--src/test/ui/imports/issue-62767.rs15
2 files changed, 24 insertions, 0 deletions
diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs
index 95597e8ebf1..d375ae4a447 100644
--- a/src/librustc_resolve/imports.rs
+++ b/src/librustc_resolve/imports.rs
@@ -874,6 +874,12 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
     /// consolidate multiple unresolved import errors into a single diagnostic.
     fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImportError> {
         let orig_vis = import.vis.replace(ty::Visibility::Invisible);
+        let orig_blacklisted_binding = match &import.kind {
+            ImportKind::Single { target_bindings, .. } => {
+                Some(mem::replace(&mut self.r.blacklisted_binding, target_bindings[TypeNS].get()))
+            }
+            _ => None,
+        };
         let prev_ambiguity_errors_len = self.r.ambiguity_errors.len();
         let path_res = self.r.resolve_path(
             &import.module_path,
@@ -884,6 +890,9 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             import.crate_lint(),
         );
         let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
+        if let Some(orig_blacklisted_binding) = orig_blacklisted_binding {
+            self.r.blacklisted_binding = orig_blacklisted_binding;
+        }
         import.vis.set(orig_vis);
         if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res {
             // Consider erroneous imports used to avoid duplicate diagnostics.
diff --git a/src/test/ui/imports/issue-62767.rs b/src/test/ui/imports/issue-62767.rs
new file mode 100644
index 00000000000..984d3f0ca92
--- /dev/null
+++ b/src/test/ui/imports/issue-62767.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+mod m {
+    pub enum Same {
+        Same,
+    }
+}
+
+use m::*;
+
+// The variant `Same` introduced by this import is not considered when resolving the prefix
+// `Same::` during import validation (issue #62767).
+use Same::Same;
+
+fn main() {}