about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2016-05-02 11:26:34 +0200
committerGeorg Brandl <georg@python.org>2016-05-02 22:02:07 +0200
commit4ba6bf44bd010c1837fdcb87bbebf67e8abd67d4 (patch)
treedb57f386954f21fcc5ee442346cfb807779a7856 /src
parent855fb6192263a5c059325bb4b4e10b55e4e8ddbb (diff)
downloadrust-4ba6bf44bd010c1837fdcb87bbebf67e8abd67d4.tar.gz
rust-4ba6bf44bd010c1837fdcb87bbebf67e8abd67d4.zip
resolve: print location of static for "static in pattern" error
The implementation mirrors the one for "constant defined here" annotation
used for constant patterns in the irrefutable-pattern case.

Fixes: #23716
Diffstat (limited to 'src')
-rw-r--r--src/librustc_resolve/lib.rs36
-rw-r--r--src/test/compile-fail/issue-23716.rs29
2 files changed, 54 insertions, 11 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 1674a96c8ba..c36fc771b5e 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -158,7 +158,7 @@ enum ResolutionError<'a> {
     /// error E0416: identifier is bound more than once in the same pattern
     IdentifierBoundMoreThanOnceInSamePattern(&'a str),
     /// error E0417: static variables cannot be referenced in a pattern
-    StaticVariableReference,
+    StaticVariableReference(DefId, Option<Name>),
     /// error E0418: is not an enum variant, struct or const
     NotAnEnumVariantStructOrConst(&'a str),
     /// error E0419: unresolved enum variant, struct or const
@@ -367,12 +367,24 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
                              "identifier `{}` is bound more than once in the same pattern",
                              identifier)
         }
-        ResolutionError::StaticVariableReference => {
-            struct_span_err!(resolver.session,
-                             span,
-                             E0417,
-                             "static variables cannot be referenced in a pattern, use a \
-                              `const` instead")
+        ResolutionError::StaticVariableReference(did, name) => {
+            let mut err = struct_span_err!(resolver.session,
+                                           span,
+                                           E0417,
+                                           "static variables cannot be referenced in a \
+                                            pattern, use a `const` instead");
+            if let Some(sp) = resolver.ast_map.span_if_local(did) {
+                err.span_note(sp, "static variable defined here");
+            }
+            if let Some(name) = name {
+                if let Some(binding) = resolver.current_module
+                                               .resolve_name_in_lexical_scope(name, ValueNS) {
+                    if binding.is_import() {
+                        err.span_note(binding.span, "static variable imported here");
+                    }
+                }
+            }
+            err
         }
         ResolutionError::NotAnEnumVariantStructOrConst(name) => {
             struct_span_err!(resolver.session,
@@ -2374,10 +2386,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             Def::Variant(..) | Def::Const(..) => {
                                 self.record_def(pattern.id, path_res);
                             }
-                            Def::Static(..) => {
+                            Def::Static(did, _) => {
                                 resolve_error(&self,
                                               path.span,
-                                              ResolutionError::StaticVariableReference);
+                                              ResolutionError::StaticVariableReference(
+                                                  did, None));
                                 self.record_def(pattern.id, err_path_resolution());
                             }
                             _ => {
@@ -2517,8 +2530,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             Some(def @ Def::Const(..)) | Some(def @ Def::AssociatedConst(..)) => {
                 FoundConst(def, ident.unhygienic_name)
             }
-            Some(Def::Static(..)) => {
-                resolve_error(self, span, ResolutionError::StaticVariableReference);
+            Some(Def::Static(did, _)) => {
+                resolve_error(self, span, ResolutionError::StaticVariableReference(
+                    did, Some(ident.unhygienic_name)));
                 BareIdentifierPatternUnresolved
             }
             _ => BareIdentifierPatternUnresolved,
diff --git a/src/test/compile-fail/issue-23716.rs b/src/test/compile-fail/issue-23716.rs
new file mode 100644
index 00000000000..c54f901199b
--- /dev/null
+++ b/src/test/compile-fail/issue-23716.rs
@@ -0,0 +1,29 @@
+// Copyright 2016 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.
+
+static foo: i32 = 0;
+//~^ NOTE static variable defined here
+
+fn bar(foo: i32) {}
+//~^ ERROR static variables cannot be referenced in a pattern, use a `const` instead
+
+mod submod {
+    pub static answer: i32 = 42;
+    //~^ NOTE static variable defined here
+}
+
+use self::submod::answer;
+//~^ NOTE static variable imported here
+
+fn question(answer: i32) {}
+//~^ ERROR static variables cannot be referenced in a pattern, use a `const` instead
+
+fn main() {
+}