about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFrançois Mockers <mockersf@gmail.com>2018-10-21 00:23:29 +0200
committerFrançois Mockers <mockersf@gmail.com>2018-10-21 00:23:29 +0200
commit9eacd68a4945aaba244885c330f64004da58a408 (patch)
tree8edcfdc561f321108a3369c827cf6dc2a353b917
parent4520b305ec477b90629d078b20acffe6b32da58c (diff)
downloadrust-9eacd68a4945aaba244885c330f64004da58a408.tar.gz
rust-9eacd68a4945aaba244885c330f64004da58a408.zip
manage cases with tabs or other whitespaces
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs5
-rw-r--r--src/librustc_resolve/check_unused.rs2
-rw-r--r--src/librustc_resolve/lib.rs55
-rw-r--r--src/librustc_resolve/resolve_imports.rs7
-rw-r--r--src/test/ui/issues/issue-45829/import-self.rs22
-rw-r--r--src/test/ui/issues/issue-45829/import-self.stderr31
-rw-r--r--src/test/ui/issues/issue-45829/import-twice.rs18
-rw-r--r--src/test/ui/issues/issue-45829/import-twice.stderr17
-rw-r--r--src/test/ui/issues/issue-45829/rename-extern-with-tab.rs17
-rw-r--r--src/test/ui/issues/issue-45829/rename-extern-with-tab.stderr17
-rw-r--r--src/test/ui/issues/issue-45829/rename-use-with-tabs.rs21
-rw-r--r--src/test/ui/issues/issue-45829/rename-use-with-tabs.stderr17
-rw-r--r--src/test/ui/resolve/resolve-conflict-item-vs-extern-crate.stderr4
13 files changed, 204 insertions, 29 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 25a7ff9cd3f..4158d20a5f8 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -449,7 +449,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                     id: item.id,
                     parent,
                     imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
-                    subclass: ImportDirectiveSubclass::ExternCrate(orig_name),
+                    subclass: ImportDirectiveSubclass::ExternCrate {
+                        source: orig_name,
+                        target: ident,
+                    },
                     root_span: item.span,
                     span: item.span,
                     module_path: Vec::new(),
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index de9481579e2..5fa0460a28d 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -144,7 +144,7 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
                     }
                 }
             }
-            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 c1d1f3c5e0d..ba367cca245 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1234,7 +1234,7 @@ impl<'a> NameBinding<'a> {
         match self.kind {
             NameBindingKind::Import {
                 directive: &ImportDirective {
-                    subclass: ImportDirectiveSubclass::ExternCrate(_), ..
+                    subclass: ImportDirectiveSubclass::ExternCrate { .. }, ..
                 }, ..
             } => true,
             _ => false,
@@ -3794,7 +3794,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
             if let NameBindingKind::Import { directive: d, .. } = binding.kind {
                 // Careful: we still want to rewrite paths from
                 // renamed extern crates.
-                if let ImportDirectiveSubclass::ExternCrate(None) = d.subclass {
+                if let ImportDirectiveSubclass::ExternCrate { source: None, .. } = d.subclass {
                     return
                 }
             }
@@ -4776,7 +4776,15 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
             let cm = self.session.source_map();
             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),
+                NameBindingKind::Import { directive, ..},
+                _x @ 1 ... std::u32::MAX,
+            ) = (
+                cm.span_to_snippet(binding.span),
+                binding.kind.clone(),
+                binding.span.hi().0,
+            ) {
                 let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() {
                     format!("Other{}", name)
                 } else {
@@ -4785,24 +4793,29 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
 
                 err.span_suggestion_with_applicability(
                     binding.span,
-                    rename_msg,
-                    match (
-                        snippet.split_whitespace().find(|w| *w == "as"),
-                        snippet.ends_with(";")
-                    ) {
-                        (Some(_), false) => format!("{} as {}",
-                            &snippet[..snippet.find(" as ").unwrap()],
-                            suggested_name,
-                        ),
-                        (Some(_), true) => format!("{} as {};",
-                            &snippet[..snippet.find(" as ").unwrap()],
-                            suggested_name,
-                        ),
-                        (None, false) => format!("{} as {}", snippet, suggested_name),
-                        (None, true) => format!("{} as {};",
-                            &snippet[..snippet.len() - 1],
-                            suggested_name
-                        ),
+                    &rename_msg,
+                    match (&directive.subclass, snippet.ends_with(";"), snippet.as_ref()) {
+                        (ImportDirectiveSubclass::SingleImport { .. }, false, "self") =>
+                            format!("self as {}", suggested_name),
+                        (ImportDirectiveSubclass::SingleImport { source, .. }, false, _) =>
+                            format!(
+                                "{} as {}",
+                                &snippet[..((source.span.hi().0 - binding.span.lo().0) as usize)],
+                                suggested_name,
+                            ),
+                        (ImportDirectiveSubclass::SingleImport { source, .. }, true, _) =>
+                            format!(
+                                "{} as {};",
+                                &snippet[..((source.span.hi().0 - binding.span.lo().0) as usize)],
+                                suggested_name,
+                            ),
+                        (ImportDirectiveSubclass::ExternCrate { source, target, .. }, _, _) =>
+                            format!(
+                                "extern crate {} as {};",
+                                source.unwrap_or(target.name),
+                                suggested_name,
+                            ),
+                        (_, _, _) => unreachable!(),
                     },
                     Applicability::MaybeIncorrect,
                 );
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 6e9877b1ab6..bb51bf95051 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -52,7 +52,10 @@ pub enum ImportDirectiveSubclass<'a> {
         max_vis: Cell<ty::Visibility>, // The visibility of the greatest re-export.
         // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors.
     },
-    ExternCrate(Option<Name>),
+    ExternCrate {
+        source: Option<Name>,
+        target: Ident,
+    },
     MacroUse,
 }
 
@@ -1342,7 +1345,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/ui/issues/issue-45829/import-self.rs b/src/test/ui/issues/issue-45829/import-self.rs
new file mode 100644
index 00000000000..8b13ffd0076
--- /dev/null
+++ b/src/test/ui/issues/issue-45829/import-self.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+mod foo {
+    pub struct A;
+    pub struct B;
+}
+
+use foo::{self};
+
+use foo as self;
+
+use foo::self;
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-45829/import-self.stderr b/src/test/ui/issues/issue-45829/import-self.stderr
new file mode 100644
index 00000000000..985dc4e7131
--- /dev/null
+++ b/src/test/ui/issues/issue-45829/import-self.stderr
@@ -0,0 +1,31 @@
+error: expected identifier, found keyword `self`
+  --> $DIR/import-self.rs:18:12
+   |
+LL | use foo as self;
+   |            ^^^^ expected identifier, found keyword
+
+error[E0429]: `self` imports are only allowed within a { } list
+  --> $DIR/import-self.rs:20:5
+   |
+LL | use foo::self;
+   |     ^^^^^^^^^
+
+error[E0255]: the name `foo` is defined multiple times
+  --> $DIR/import-self.rs:16:11
+   |
+LL | mod foo {
+   | ------- previous definition of the module `foo` here
+...
+LL | use foo::{self};
+   |           ^^^^ `foo` reimported here
+   |
+   = note: `foo` 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
+   |
+LL | use foo::{self as other_foo};
+   |           ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+Some errors occurred: E0255, E0429.
+For more information about an error, try `rustc --explain E0255`.
diff --git a/src/test/ui/issues/issue-45829/import-twice.rs b/src/test/ui/issues/issue-45829/import-twice.rs
new file mode 100644
index 00000000000..785932e5ef4
--- /dev/null
+++ b/src/test/ui/issues/issue-45829/import-twice.rs
@@ -0,0 +1,18 @@
+// Copyright 2018 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.
+
+mod foo {
+    pub struct A;
+    pub struct B;
+}
+
+use foo::{A, A};
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-45829/import-twice.stderr b/src/test/ui/issues/issue-45829/import-twice.stderr
new file mode 100644
index 00000000000..566d47965f8
--- /dev/null
+++ b/src/test/ui/issues/issue-45829/import-twice.stderr
@@ -0,0 +1,17 @@
+error[E0252]: the name `A` is defined multiple times
+  --> $DIR/import-twice.rs:16:14
+   |
+LL | use foo::{A, A};
+   |           -  ^ `A` reimported here
+   |           |
+   |           previous import of the type `A` here
+   |
+   = note: `A` 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
+   |
+LL | use foo::{A, A as OtherA};
+   |              ^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0252`.
diff --git a/src/test/ui/issues/issue-45829/rename-extern-with-tab.rs b/src/test/ui/issues/issue-45829/rename-extern-with-tab.rs
new file mode 100644
index 00000000000..7066ed65c78
--- /dev/null
+++ b/src/test/ui/issues/issue-45829/rename-extern-with-tab.rs
@@ -0,0 +1,17 @@
+// Copyright 2018 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:issue_45829_a.rs
+// aux-build:issue_45829_b.rs
+
+extern crate issue_45829_a;
+extern  crate    issue_45829_b  as  issue_45829_a;
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-45829/rename-extern-with-tab.stderr b/src/test/ui/issues/issue-45829/rename-extern-with-tab.stderr
new file mode 100644
index 00000000000..769be545706
--- /dev/null
+++ b/src/test/ui/issues/issue-45829/rename-extern-with-tab.stderr
@@ -0,0 +1,17 @@
+error[E0259]: the name `issue_45829_a` is defined multiple times
+  --> $DIR/rename-extern-with-tab.rs:15:1
+   |
+LL | extern crate issue_45829_a;
+   | --------------------------- previous import of the extern crate `issue_45829_a` here
+LL | extern  crate    issue_45829_b  as  issue_45829_a;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `issue_45829_a` reimported here
+   |
+   = note: `issue_45829_a` 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
+   |
+LL | extern crate issue_45829_b as other_issue_45829_a;
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0259`.
diff --git a/src/test/ui/issues/issue-45829/rename-use-with-tabs.rs b/src/test/ui/issues/issue-45829/rename-use-with-tabs.rs
new file mode 100644
index 00000000000..c1e4d908906
--- /dev/null
+++ b/src/test/ui/issues/issue-45829/rename-use-with-tabs.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 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.
+
+mod foo {
+    pub struct A;
+
+    pub mod bar {
+        pub struct B;
+    }
+}
+
+use foo::{A, bar::B    as    A};
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-45829/rename-use-with-tabs.stderr b/src/test/ui/issues/issue-45829/rename-use-with-tabs.stderr
new file mode 100644
index 00000000000..b80a692028a
--- /dev/null
+++ b/src/test/ui/issues/issue-45829/rename-use-with-tabs.stderr
@@ -0,0 +1,17 @@
+error[E0252]: the name `A` is defined multiple times
+  --> $DIR/rename-use-with-tabs.rs:19:14
+   |
+LL | use foo::{A, bar::B    as    A};
+   |           -  ^^^^^^^^^^^^^^^^^ `A` reimported here
+   |           |
+   |           previous import of the type `A` here
+   |
+   = note: `A` 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
+   |
+LL | use foo::{A, bar::B as OtherA};
+   |              ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0252`.
diff --git a/src/test/ui/resolve/resolve-conflict-item-vs-extern-crate.stderr b/src/test/ui/resolve/resolve-conflict-item-vs-extern-crate.stderr
index 8e0baf3be6f..0b082c1105f 100644
--- a/src/test/ui/resolve/resolve-conflict-item-vs-extern-crate.stderr
+++ b/src/test/ui/resolve/resolve-conflict-item-vs-extern-crate.stderr
@@ -5,10 +5,6 @@ LL | mod std {}    //~ ERROR the name `std` is defined multiple times
    | ^^^^^^^ `std` redefined here
    |
    = note: `std` 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
-   |
-LL |  as other_std// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-   |  ^^^^^^^^^^^^
 
 error: aborting due to previous error