about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-05-12 08:54:40 +0000
committerbors <bors@rust-lang.org>2015-05-12 08:54:40 +0000
commitfeac9f1c7b17903ef14ff46bc24c2baa45f3b15f (patch)
tree62cb271674ec185c4811344f8446fff893c6279e
parentf2e1a1b50eee3dd98bbd760d71ae7b5fce360165 (diff)
parentdb9d01842450fe07f77ca97d9a68d105366f407e (diff)
downloadrust-feac9f1c7b17903ef14ff46bc24c2baa45f3b15f.tar.gz
rust-feac9f1c7b17903ef14ff46bc24c2baa45f3b15f.zip
Auto merge of #24818 - tbelaire:double-import, r=nrc
This isn't quite right, but it's interesting.
-rw-r--r--src/librustc_resolve/resolve_imports.rs31
-rw-r--r--src/test/compile-fail/double-import.rs27
2 files changed, 46 insertions, 12 deletions
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 350f69d30c4..9870b41e7fa 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -618,7 +618,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                                namespace_name,
                                name_bindings.def_for_namespace(namespace));
                         self.check_for_conflicting_import(
-                            &import_resolution.target_for_namespace(namespace),
+                            &import_resolution,
                             directive.span,
                             target,
                             namespace);
@@ -755,7 +755,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                             // Continue.
                         }
                         Some(ref value_target) => {
-                            self.check_for_conflicting_import(&dest_import_resolution.value_target,
+                            self.check_for_conflicting_import(&dest_import_resolution,
                                                               import_directive.span,
                                                               *ident,
                                                               ValueNS);
@@ -767,7 +767,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                             // Continue.
                         }
                         Some(ref type_target) => {
-                            self.check_for_conflicting_import(&dest_import_resolution.type_target,
+                            self.check_for_conflicting_import(&dest_import_resolution,
                                                               import_directive.span,
                                                               *ident,
                                                               TypeNS);
@@ -887,24 +887,31 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
 
     /// Checks that imported names and items don't have the same name.
     fn check_for_conflicting_import(&mut self,
-                                    target: &Option<Target>,
+                                    import_resolution: &ImportResolution,
                                     import_span: Span,
                                     name: Name,
                                     namespace: Namespace) {
+        let target = import_resolution.target_for_namespace(namespace);
         debug!("check_for_conflicting_import: {}; target exists: {}",
                &token::get_name(name),
                target.is_some());
 
-        match *target {
+        match target {
             Some(ref target) if target.shadowable != Shadowable::Always => {
-                let msg = format!("a {} named `{}` has already been imported \
-                                   in this module",
-                                  match namespace {
-                                    TypeNS => "type",
-                                    ValueNS => "value",
-                                  },
+                let ns_word = match namespace {
+                    TypeNS => "type",
+                    ValueNS => "value",
+                };
+                span_err!(self.resolver.session, import_span, E0252,
+                          "a {} named `{}` has already been imported \
+                           in this module", ns_word,
                                   &token::get_name(name));
-                span_err!(self.resolver.session, import_span, E0252, "{}", &msg[..]);
+                let use_id = import_resolution.id(namespace);
+                let item = self.resolver.ast_map.expect_item(use_id);
+                // item is syntax::ast::Item;
+                span_note!(self.resolver.session, item.span,
+                            "previous import of `{}` here",
+                            token::get_name(name));
             }
             Some(_) | None => {}
         }
diff --git a/src/test/compile-fail/double-import.rs b/src/test/compile-fail/double-import.rs
new file mode 100644
index 00000000000..cbf13c0a559
--- /dev/null
+++ b/src/test/compile-fail/double-import.rs
@@ -0,0 +1,27 @@
+// Copyright 2015 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.
+#![feature(no_std)]
+#![no_std]
+
+// This tests that conflicting imports shows both `use` lines
+// when reporting the error.
+
+mod sub1 {
+    fn foo() {} // implementation 1
+}
+
+mod sub2 {
+    fn foo() {} // implementation 2
+}
+
+use sub1::foo; //~ NOTE previous import of `foo` here
+use sub2::foo; //~ ERROR a value named `foo` has already been imported in this module [E0252]
+
+fn main() {}