about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-10-23 02:44:36 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-10-25 20:26:00 +0000
commit04ca378b897012026fb5a4ebe8e04263e32c236b (patch)
tree5ccf59588f95b9ea96fde1039c20fca137e15bed
parent199ed20aa6aa64ca58b4a924395bf9e1e71cf8a8 (diff)
downloadrust-04ca378b897012026fb5a4ebe8e04263e32c236b.tar.gz
rust-04ca378b897012026fb5a4ebe8e04263e32c236b.zip
Support `use $crate;` with a future compatibility warning.
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs19
-rw-r--r--src/librustc_resolve/lib.rs16
-rw-r--r--src/test/compile-fail/auxiliary/import_crate_var.rs12
-rw-r--r--src/test/compile-fail/import-crate-var.rs21
4 files changed, 58 insertions, 10 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index db86840fd38..1c9d1fb061f 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -130,14 +130,27 @@ impl<'b> Resolver<'b> {
 
                 match view_path.node {
                     ViewPathSimple(binding, ref full_path) => {
-                        let source_name = full_path.segments.last().unwrap().identifier.name;
-                        if source_name.as_str() == "mod" || source_name.as_str() == "self" {
+                        let mut source = full_path.segments.last().unwrap().identifier;
+                        let source_name = source.name.as_str();
+                        if source_name == "mod" || source_name == "self" {
                             resolve_error(self,
                                           view_path.span,
                                           ResolutionError::SelfImportsOnlyAllowedWithin);
+                        } else if source_name == "$crate" && full_path.segments.len() == 1 {
+                            let crate_root = self.resolve_crate_var(source.ctxt);
+                            let crate_name = match crate_root.kind {
+                                ModuleKind::Def(_, name) => name,
+                                ModuleKind::Block(..) => unreachable!(),
+                            };
+                            source.name = crate_name;
+
+                            self.session.struct_span_warn(item.span, "`$crate` may not be imported")
+                                .note("`use $crate;` was erroneously allowed and \
+                                       will become a hard error in a future release")
+                                .emit();
                         }
 
-                        let subclass = ImportDirectiveSubclass::single(binding.name, source_name);
+                        let subclass = ImportDirectiveSubclass::single(binding.name, source.name);
                         let span = view_path.span;
                         self.add_import_directive(module_path, subclass, span, item.id, vis);
                     }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 210cabdd8ec..856eb348eae 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1584,13 +1584,7 @@ impl<'a> Resolver<'a> {
     fn resolve_module_prefix(&mut self, module_path: &[Ident], span: Option<Span>)
                              -> ResolveResult<ModulePrefixResult<'a>> {
         if &*module_path[0].name.as_str() == "$crate" {
-            let mut ctxt = module_path[0].ctxt;
-            while ctxt.source().0 != SyntaxContext::empty() {
-                ctxt = ctxt.source().0;
-            }
-            let module = self.invocations[&ctxt.source().1].module.get();
-            let crate_root = if module.is_local() { self.graph_root } else { module };
-            return Success(PrefixFound(crate_root, 1))
+            return Success(PrefixFound(self.resolve_crate_var(module_path[0].ctxt), 1));
         }
 
         // Start at the current module if we see `self` or `super`, or at the
@@ -1623,6 +1617,14 @@ impl<'a> Resolver<'a> {
         return Success(PrefixFound(containing_module, i));
     }
 
+    fn resolve_crate_var(&mut self, mut crate_var_ctxt: SyntaxContext) -> Module<'a> {
+        while crate_var_ctxt.source().0 != SyntaxContext::empty() {
+            crate_var_ctxt = crate_var_ctxt.source().0;
+        }
+        let module = self.invocations[&crate_var_ctxt.source().1].module.get();
+        if module.is_local() { self.graph_root } else { module }
+    }
+
     // AST resolution
     //
     // We maintain a list of value ribs and type ribs.
diff --git a/src/test/compile-fail/auxiliary/import_crate_var.rs b/src/test/compile-fail/auxiliary/import_crate_var.rs
new file mode 100644
index 00000000000..1dfc7a128aa
--- /dev/null
+++ b/src/test/compile-fail/auxiliary/import_crate_var.rs
@@ -0,0 +1,12 @@
+// 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.
+
+#[macro_export]
+macro_rules! m { () => { use $crate; } }
diff --git a/src/test/compile-fail/import-crate-var.rs b/src/test/compile-fail/import-crate-var.rs
new file mode 100644
index 00000000000..9f573945483
--- /dev/null
+++ b/src/test/compile-fail/import-crate-var.rs
@@ -0,0 +1,21 @@
+// 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.
+
+// aux-build:import_crate_var.rs
+// error-pattern: `$crate` may not be imported
+// error-pattern: `use $crate;` was erroneously allowed and will become a hard error
+
+#![feature(rustc_attrs)]
+
+#[macro_use] extern crate import_crate_var;
+m!();
+
+#[rustc_error]
+fn main() {}