From 9f5e08e0a167d6ce406445a619a8bf358deeade4 Mon Sep 17 00:00:00 2001
From: Manish Goregaokar <manishsmail@gmail.com>
Date: Fri, 20 Apr 2018 17:04:29 -0700
Subject: [PATCH] Fix crate:: in local paths

---
 src/librustc_resolve/lib.rs                              | 9 +++++----
 .../rfc-2126-crate-paths/crate-path-non-absolute.rs      | 5 +++--
 .../rfc-2126-crate-paths/keyword-crate-as-identifier.rs  | 2 +-
 .../crate-path-visibility-ambiguity.rs}                  | 2 +-
 4 files changed, 10 insertions(+), 8 deletions(-)
 rename src/test/{compile-fail/rfc-2126-crate-paths/crate-visibility-ambiguity.rs => run-pass/rfc-2126-crate-paths/crate-path-visibility-ambiguity.rs} (89%)

diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 7a87a72afc294..127331152c155 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -3245,6 +3245,7 @@ impl<'a> Resolver<'a> {
 
             if ns == TypeNS {
                 if (i == 0 && name == keywords::CrateRoot.name()) ||
+                   (i == 0 && name == keywords::Crate.name()) ||
                    (i == 1 && name == keywords::Crate.name() &&
                               path[0].name == keywords::CrateRoot.name()) {
                     // `::a::b` or `::crate::a::b`
@@ -3279,8 +3280,10 @@ impl<'a> Resolver<'a> {
                name == keywords::SelfType.name() && i != 0 ||
                name == keywords::Super.name() && i != 0 ||
                name == keywords::Extern.name() && i != 0 ||
-               name == keywords::Crate.name() && i != 1 &&
-                    path[0].name != keywords::CrateRoot.name() {
+               // we allow crate::foo and ::crate::foo but nothing else
+               name == keywords::Crate.name() && i > 1 &&
+                    path[0].name != keywords::CrateRoot.name() ||
+               name == keywords::Crate.name() && path.len() == 1 {
                 let name_str = if name == keywords::CrateRoot.name() {
                     format!("crate root")
                 } else {
@@ -3288,8 +3291,6 @@ impl<'a> Resolver<'a> {
                 };
                 let msg = if i == 1 && path[0].name == keywords::CrateRoot.name() {
                     format!("global paths cannot start with {}", name_str)
-                } else if i == 0 && name == keywords::Crate.name() {
-                    format!("{} can only be used in absolute paths", name_str)
                 } else {
                     format!("{} in paths can only be used in start position", name_str)
                 };
diff --git a/src/test/compile-fail/rfc-2126-crate-paths/crate-path-non-absolute.rs b/src/test/compile-fail/rfc-2126-crate-paths/crate-path-non-absolute.rs
index 75c2a5f5bc477..65f11c063ed2e 100644
--- a/src/test/compile-fail/rfc-2126-crate-paths/crate-path-non-absolute.rs
+++ b/src/test/compile-fail/rfc-2126-crate-paths/crate-path-non-absolute.rs
@@ -12,9 +12,10 @@
 
 struct S;
 
-mod m {
+pub mod m {
     fn f() {
-        let s = crate::S; //~ ERROR `crate` can only be used in absolute paths
+        let s = ::m::crate::S; //~ ERROR failed to resolve
+        let s2 = crate::S; // no error
     }
 }
 
diff --git a/src/test/compile-fail/rfc-2126-crate-paths/keyword-crate-as-identifier.rs b/src/test/compile-fail/rfc-2126-crate-paths/keyword-crate-as-identifier.rs
index 2c94f7b0f59df..bdd03be4356c9 100644
--- a/src/test/compile-fail/rfc-2126-crate-paths/keyword-crate-as-identifier.rs
+++ b/src/test/compile-fail/rfc-2126-crate-paths/keyword-crate-as-identifier.rs
@@ -11,5 +11,5 @@
 #![feature(crate_in_paths)]
 
 fn main() {
-    let crate = 0; //~ ERROR `crate` can only be used in absolute paths
+    let crate = 0; //~ ERROR failed to resolve. `crate` in paths can only be used in start position
 }
diff --git a/src/test/compile-fail/rfc-2126-crate-paths/crate-visibility-ambiguity.rs b/src/test/run-pass/rfc-2126-crate-paths/crate-path-visibility-ambiguity.rs
similarity index 89%
rename from src/test/compile-fail/rfc-2126-crate-paths/crate-visibility-ambiguity.rs
rename to src/test/run-pass/rfc-2126-crate-paths/crate-path-visibility-ambiguity.rs
index 8c5a971c2f756..1a8d2d80ef4d9 100644
--- a/src/test/compile-fail/rfc-2126-crate-paths/crate-visibility-ambiguity.rs
+++ b/src/test/run-pass/rfc-2126-crate-paths/crate-path-visibility-ambiguity.rs
@@ -15,7 +15,7 @@ mod m {
     pub struct Z;
     pub struct S1(crate (::m::Z)); // OK
     pub struct S2(::crate ::m::Z); // OK
-    pub struct S3(crate ::m::Z); //~ ERROR `crate` can only be used in absolute paths
+    pub struct S3(crate ::m::Z); // OK
 }
 
 fn main() {