about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2017-11-07 18:01:35 -0800
committerEsteban Küber <esteban@kuber.com.ar>2017-11-08 10:36:14 -0800
commitd0339c7e44ea145acdc779f0ecd078b11d212dc2 (patch)
tree6cca05f64a9705a4c17035eabd580b7d365ac0e4 /src
parent7f6417e9b72de63666fd92caf1a6b96a778b60ed (diff)
downloadrust-d0339c7e44ea145acdc779f0ecd078b11d212dc2.tar.gz
rust-d0339c7e44ea145acdc779f0ecd078b11d212dc2.zip
Fix help for duplicated names: `extern crate (...) as (...)`
On the case of duplicated names caused by an `extern crate` statement
with a rename, don't include the inline suggestion, instead using a span
label with only the text to avoid incorrect rust code output.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs4
-rw-r--r--src/librustc_resolve/check_unused.rs2
-rw-r--r--src/librustc_resolve/lib.rs14
-rw-r--r--src/librustc_resolve/resolve_imports.rs6
-rw-r--r--src/test/compile-fail/E0259.rs1
-rw-r--r--src/test/ui/suggestions/auxiliary/m1.rs11
-rw-r--r--src/test/ui/suggestions/auxiliary/m2.rs11
-rw-r--r--src/test/ui/suggestions/extern-crate-rename.rs18
-rw-r--r--src/test/ui/suggestions/extern-crate-rename.stderr15
9 files changed, 74 insertions, 8 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index a10bce29342..b30fc38fcbc 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -250,7 +250,7 @@ impl<'a> Resolver<'a> {
                 }
             }
 
-            ItemKind::ExternCrate(_) => {
+            ItemKind::ExternCrate(as_name) => {
                 self.crate_loader.process_item(item, &self.definitions);
 
                 // n.b. we don't need to look at the path option here, because cstore already did
@@ -265,7 +265,7 @@ impl<'a> Resolver<'a> {
                     id: item.id,
                     parent,
                     imported_module: Cell::new(Some(module)),
-                    subclass: ImportDirectiveSubclass::ExternCrate,
+                    subclass: ImportDirectiveSubclass::ExternCrate(as_name),
                     span: item.span,
                     module_path: Vec::new(),
                     vis: Cell::new(vis),
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index a66d1ce0859..5820acf1b90 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -120,7 +120,7 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
             _ if directive.used.get() ||
                  directive.vis.get() == ty::Visibility::Public ||
                  directive.span.source_equal(&DUMMY_SP) => {}
-            ImportDirectiveSubclass::ExternCrate => {
+            ImportDirectiveSubclass::ExternCrate(_) => {
                 resolver.maybe_unused_extern_crates.push((directive.id, directive.span));
             }
             ImportDirectiveSubclass::MacroUse => {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index bed9f37c515..c4185e90801 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1118,7 +1118,7 @@ impl<'a> NameBinding<'a> {
         match self.kind {
             NameBindingKind::Import {
                 directive: &ImportDirective {
-                    subclass: ImportDirectiveSubclass::ExternCrate, ..
+                    subclass: ImportDirectiveSubclass::ExternCrate(_), ..
                 }, ..
             } => true,
             _ => false,
@@ -1132,6 +1132,15 @@ impl<'a> NameBinding<'a> {
         }
     }
 
+    fn is_renamed_extern_crate(&self) -> bool {
+        if let NameBindingKind::Import { directive, ..} = self.kind {
+            if let ImportDirectiveSubclass::ExternCrate(Some(_)) = directive.subclass {
+                return true;
+            }
+        }
+        false
+    }
+
     fn is_glob_import(&self) -> bool {
         match self.kind {
             NameBindingKind::Import { directive, .. } => directive.is_glob(),
@@ -3700,7 +3709,8 @@ impl<'a> Resolver<'a> {
             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) {
+            if let (Ok(snippet), false) = (cm.span_to_snippet(binding.span),
+                                           binding.is_renamed_extern_crate()) {
                 err.span_suggestion(binding.span,
                                     rename_msg,
                                     format!("{} as Other{}", snippet, name));
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index b85bf18ea80..bcbabd70094 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -23,7 +23,7 @@ use rustc::hir::def_id::DefId;
 use rustc::hir::def::*;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
 
-use syntax::ast::{Ident, SpannedIdent, NodeId};
+use syntax::ast::{Ident, Name, SpannedIdent, NodeId};
 use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
 use syntax::ext::hygiene::Mark;
 use syntax::parse::token;
@@ -48,7 +48,7 @@ pub enum ImportDirectiveSubclass<'a> {
         max_vis: Cell<ty::Visibility>, // The visibility of the greatest reexport.
         // n.b. `max_vis` is only used in `finalize_import` to check for reexport errors.
     },
-    ExternCrate,
+    ExternCrate(Option<Name>),
     MacroUse,
 }
 
@@ -923,7 +923,7 @@ fn import_directive_subclass_to_string(subclass: &ImportDirectiveSubclass) -> St
     match *subclass {
         SingleImport { source, .. } => source.to_string(),
         GlobImport { .. } => "*".to_string(),
-        ExternCrate => "<extern crate>".to_string(),
+        ExternCrate(_) => "<extern crate>".to_string(),
         MacroUse => "#[macro_use]".to_string(),
     }
 }
diff --git a/src/test/compile-fail/E0259.rs b/src/test/compile-fail/E0259.rs
index c285c4d9e00..e125cc0c19c 100644
--- a/src/test/compile-fail/E0259.rs
+++ b/src/test/compile-fail/E0259.rs
@@ -18,5 +18,6 @@ extern crate libc as alloc;
 //~^ ERROR E0259
 //~| NOTE `alloc` reimported here
 //~| NOTE `alloc` must be defined only once in the type namespace of this module
+//~| NOTE You can use `as` to change the binding name of the import
 
 fn main() {}
diff --git a/src/test/ui/suggestions/auxiliary/m1.rs b/src/test/ui/suggestions/auxiliary/m1.rs
new file mode 100644
index 00000000000..b61667cfd88
--- /dev/null
+++ b/src/test/ui/suggestions/auxiliary/m1.rs
@@ -0,0 +1,11 @@
+// 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 fn foo() {}
diff --git a/src/test/ui/suggestions/auxiliary/m2.rs b/src/test/ui/suggestions/auxiliary/m2.rs
new file mode 100644
index 00000000000..94ff5e4497f
--- /dev/null
+++ b/src/test/ui/suggestions/auxiliary/m2.rs
@@ -0,0 +1,11 @@
+// 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 fn bar() {}
diff --git a/src/test/ui/suggestions/extern-crate-rename.rs b/src/test/ui/suggestions/extern-crate-rename.rs
new file mode 100644
index 00000000000..b3fa5871a82
--- /dev/null
+++ b/src/test/ui/suggestions/extern-crate-rename.rs
@@ -0,0 +1,18 @@
+// 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.
+
+// aux-build:m1.rs
+// aux-build:m2.rs
+
+
+extern crate m1;
+extern crate m2 as m1;
+
+fn main() {}
diff --git a/src/test/ui/suggestions/extern-crate-rename.stderr b/src/test/ui/suggestions/extern-crate-rename.stderr
new file mode 100644
index 00000000000..c15e238e8b0
--- /dev/null
+++ b/src/test/ui/suggestions/extern-crate-rename.stderr
@@ -0,0 +1,15 @@
+error[E0259]: the name `m1` is defined multiple times
+  --> $DIR/extern-crate-rename.rs:16:1
+   |
+15 | extern crate m1;
+   | ---------------- previous import of the extern crate `m1` here
+16 | extern crate m2 as m1;
+   | ^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | `m1` reimported here
+   | You can use `as` to change the binding name of the import
+   |
+   = note: `m1` must be defined only once in the type namespace of this module
+
+error: aborting due to previous error
+