about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-07-29 15:19:29 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-08-01 19:09:58 +0000
commit6372a6d7c271c58bc56dd35a2f58599d5429b39a (patch)
tree51444b9d7fc6639f540f26da192d4b87362566fc
parent07c706b57c863506e9ecee8e9006dbde84f9155c (diff)
downloadrust-6372a6d7c271c58bc56dd35a2f58599d5429b39a.tar.gz
rust-6372a6d7c271c58bc56dd35a2f58599d5429b39a.zip
Improve diagnostics for pattern bindings that illegally shadow items.
Improve unused import detection.
-rw-r--r--src/librustc/traits/object_safety.rs1
-rw-r--r--src/librustc_resolve/lib.rs34
-rw-r--r--src/librustc_trans/debuginfo/mod.rs2
-rw-r--r--src/test/compile-fail/const-pattern-irrefutable.rs1
-rw-r--r--src/test/compile-fail/lint-unused-imports.rs7
5 files changed, 28 insertions, 17 deletions
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index ffa1530a14e..93c6dd09e07 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -17,7 +17,6 @@
 //!   - not reference the erased type `Self` except for in this receiver;
 //!   - not have generic type parameters
 
-use super::supertraits;
 use super::elaborate_predicates;
 
 use hir::def_id::DefId;
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 48be5ad812a..84ebfad9ff2 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -158,7 +158,7 @@ enum ResolutionError<'a> {
     /// error E0435: attempt to use a non-constant value in a constant
     AttemptToUseNonConstantValueInConstant,
     /// error E0530: X bindings cannot shadow Ys
-    BindingShadowsSomethingUnacceptable(&'a str, &'a str, Name),
+    BindingShadowsSomethingUnacceptable(&'a str, Name, &'a NameBinding<'a>),
     /// error E0531: unresolved pattern path kind `name`
     PatPathUnresolved(&'a str, &'a Path),
     /// error E0532: expected pattern path kind, found another pattern path kind
@@ -422,17 +422,16 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
                              E0435,
                              "attempt to use a non-constant value in a constant")
         }
-        ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, shadows_what, name) => {
+        ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {
+            let shadows_what = PathResolution::new(binding.def().unwrap()).kind_name();
             let mut err = struct_span_err!(resolver.session,
                                            span,
                                            E0530,
                                            "{}s cannot shadow {}s", what_binding, shadows_what);
             err.span_label(span, &format!("cannot be named the same as a {}", shadows_what));
-            if let Success(binding) = resolver.current_module.resolve_name(name, ValueNS, true) {
-                let participle = if binding.is_import() { "imported" } else { "defined" };
-                err.span_label(binding.span, &format!("a {} `{}` is {} here",
-                                                      shadows_what, name, participle));
-            }
+            let participle = if binding.is_import() { "imported" } else { "defined" };
+            let msg = &format!("a {} `{}` is {} here", shadows_what, name, participle);
+            err.span_label(binding.span, msg);
             err
         }
         ResolutionError::PatPathUnresolved(expected_what, path) => {
@@ -712,12 +711,16 @@ impl<'a> LexicalScopeBinding<'a> {
         }
     }
 
-    fn module(self) -> Option<Module<'a>> {
+    fn item(self) -> Option<&'a NameBinding<'a>> {
         match self {
-            LexicalScopeBinding::Item(binding) => binding.module(),
+            LexicalScopeBinding::Item(binding) => Some(binding),
             _ => None,
         }
     }
+
+    fn module(self) -> Option<Module<'a>> {
+        self.item().and_then(NameBinding::module)
+    }
 }
 
 /// The link from a module up to its nearest parent node.
@@ -2316,16 +2319,17 @@ impl<'a> Resolver<'a> {
                 PatKind::Ident(bmode, ref ident, ref opt_pat) => {
                     // First try to resolve the identifier as some existing
                     // entity, then fall back to a fresh binding.
-                    let resolution = self.resolve_identifier(ident.node, ValueNS, true)
-                                         .map(|local_def| PathResolution::new(local_def.def))
-                                         .and_then(|resolution| {
+                    let binding = self.resolve_ident_in_lexical_scope(ident.node, ValueNS, false)
+                                      .and_then(LexicalScopeBinding::item);
+                    let resolution = binding.and_then(NameBinding::def).and_then(|def| {
                         let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
                                              bmode != BindingMode::ByValue(Mutability::Immutable);
-                        match resolution.base_def {
+                        match def {
                             Def::Struct(..) | Def::Variant(..) |
                             Def::Const(..) | Def::AssociatedConst(..) if !always_binding => {
                                 // A constant, unit variant, etc pattern.
-                                Some(resolution)
+                                self.record_use(ident.node.name, ValueNS, binding.unwrap());
+                                Some(PathResolution::new(def))
                             }
                             Def::Struct(..) | Def::Variant(..) |
                             Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => {
@@ -2334,7 +2338,7 @@ impl<'a> Resolver<'a> {
                                     self,
                                     ident.span,
                                     ResolutionError::BindingShadowsSomethingUnacceptable(
-                                        pat_src.descr(), resolution.kind_name(), ident.node.name)
+                                        pat_src.descr(), ident.node.name, binding.unwrap())
                                 );
                                 None
                             }
diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs
index ed20d949d55..639cdb135bd 100644
--- a/src/librustc_trans/debuginfo/mod.rs
+++ b/src/librustc_trans/debuginfo/mod.rs
@@ -18,7 +18,7 @@ use self::utils::{DIB, span_start, create_DIArray, is_node_local_to_unit};
 use self::namespace::mangled_name_of_item;
 use self::type_names::compute_debuginfo_type_name;
 use self::metadata::{type_metadata, diverging_type_metadata};
-use self::metadata::{file_metadata, scope_metadata, TypeMap};
+use self::metadata::{file_metadata, TypeMap};
 use self::source_loc::InternalDebugLocation::{self, UnknownLocation};
 
 use llvm;
diff --git a/src/test/compile-fail/const-pattern-irrefutable.rs b/src/test/compile-fail/const-pattern-irrefutable.rs
index 75b6397f4eb..11003067070 100644
--- a/src/test/compile-fail/const-pattern-irrefutable.rs
+++ b/src/test/compile-fail/const-pattern-irrefutable.rs
@@ -25,4 +25,5 @@ fn main() {
                //~^ NOTE cannot be named the same as a constant
     let d = 4; //~ ERROR let bindings cannot shadow constants
                //~^ NOTE cannot be named the same as a constant
+    fn f() {} // Check that the `NOTE`s still work with an item here (c.f. issue #35115).
 }
diff --git a/src/test/compile-fail/lint-unused-imports.rs b/src/test/compile-fail/lint-unused-imports.rs
index 40322f5a5b5..239f380e6c4 100644
--- a/src/test/compile-fail/lint-unused-imports.rs
+++ b/src/test/compile-fail/lint-unused-imports.rs
@@ -79,6 +79,13 @@ fn g() {
     }
 }
 
+// c.f. issue #35135
+#[allow(unused_variables)]
+fn h() {
+    use test2::foo; //~ ERROR unused import
+    let foo = 0;
+}
+
 fn main() {
     cal(foo::Point{x:3, y:9});
     let mut a = 3;