about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2017-11-01 13:32:19 +0800
committerGitHub <noreply@github.com>2017-11-01 13:32:19 +0800
commit0ec40c1704a16c6d491dc747573f71fabbe79ed2 (patch)
tree4a43313d0683a31739bfb5eae32337e4870ee4c4
parent63ad1293cc806e941d00fc356200a6bb43621312 (diff)
parent61396a8286cde05bea720f5738eb939cc32b8d34 (diff)
Rollup merge of #45660 - Cldfire:suggest-rename-import, r=estebank
Suggest renaming import if names clash

Closes https://github.com/rust-lang/rust/issues/32354.

The output for the example in the issue looks like this:

```
~/p/local-rust-dev-testing ❯❯❯ cargo +local-s1 build
   Compiling local-rust-dev-testing v0.1.0 (file:///home/cldfire/programming_projects/local-rust-dev-testing)
error[E0252]: the name `ConstructorExtension` is defined multiple times
  --> src/main.rs:49:5
   |
48 | use extension1::ConstructorExtension;
   |     -------------------------------- previous import of the trait `ConstructorExtension` here
49 | use extension2::ConstructorExtension;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ConstructorExtension` reimported here
   |
   = note: `ConstructorExtension` must be defined only once in the type namespace of this module
help: You can use `as` to change the binding name of the import
   |
49 | use extension2::ConstructorExtension as OtherConstructorExtension;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

...
```

This is my first PR that touches the compiler in any way, so if there's something else I need to do here (e.g. add a test), please let me know :).
-rw-r--r--src/librustc_resolve/lib.rs26
-rw-r--r--src/test/ui/suggestions/issue-32354-suggest-import-rename.rs22
-rw-r--r--src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr16
3 files changed, 61 insertions, 3 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 83eeaf551c5..3b27890013a 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -3606,12 +3606,12 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    fn report_conflict(&mut self,
+    fn report_conflict<'b>(&mut self,
                        parent: Module,
                        ident: Ident,
                        ns: Namespace,
-                       new_binding: &NameBinding,
-                       old_binding: &NameBinding) {
+                       new_binding: &NameBinding<'b>,
+                       old_binding: &NameBinding<'b>) {
         // Error on the second of two conflicting names
         if old_binding.span.lo() > new_binding.span.lo() {
             return self.report_conflict(parent, ident, ns, old_binding, new_binding);
@@ -3683,6 +3683,26 @@ impl<'a> Resolver<'a> {
                                                       old_noun, old_kind, name));
         }
 
+        // See https://github.com/rust-lang/rust/issues/32354
+        if old_binding.is_import() || new_binding.is_import() {
+            let binding = if new_binding.is_import() {
+                new_binding
+            } else {
+                old_binding
+            };
+
+            let cm = self.session.codemap();
+            let rename_msg = "You can use `as` to change the binding name of the import";
+
+            if let Ok(snippet) = cm.span_to_snippet(binding.span) {
+                err.span_suggestion(binding.span,
+                                    rename_msg,
+                                    format!("{} as Other{}", snippet, name));
+            } else {
+                err.span_label(binding.span, rename_msg);
+            }
+        }
+
         err.emit();
         self.name_already_seen.insert(name, span);
     }
diff --git a/src/test/ui/suggestions/issue-32354-suggest-import-rename.rs b/src/test/ui/suggestions/issue-32354-suggest-import-rename.rs
new file mode 100644
index 00000000000..51aba27498f
--- /dev/null
+++ b/src/test/ui/suggestions/issue-32354-suggest-import-rename.rs
@@ -0,0 +1,22 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub mod extension1 {
+    pub trait ConstructorExtension {}
+}
+
+pub mod extension2 {
+    pub trait ConstructorExtension {}
+}
+
+use extension1::ConstructorExtension;
+use extension2::ConstructorExtension;
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr b/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr
new file mode 100644
index 00000000000..07985191284
--- /dev/null
+++ b/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr
@@ -0,0 +1,16 @@
+error[E0252]: the name `ConstructorExtension` is defined multiple times
+  --> $DIR/issue-32354-suggest-import-rename.rs:20:5
+   |
+19 | use extension1::ConstructorExtension;
+   |     -------------------------------- previous import of the trait `ConstructorExtension` here
+20 | use extension2::ConstructorExtension;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ConstructorExtension` reimported here
+   |
+   = note: `ConstructorExtension` must be defined only once in the type namespace of this module
+help: You can use `as` to change the binding name of the import
+   |
+20 | use extension2::ConstructorExtension as OtherConstructorExtension;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+